关于javascript:在-Openlayer-中添加-mark并添加-hover-效果

52次阅读

共计 2592 个字符,预计需要花费 7 分钟才能阅读完成。

add mark

办法一

如果有多个点的话,能够生成多个 feature(循环调用 addFeature

const iconStyle = () =>
  new Style({image: new Icon({ scale: 0.2, src: image}) });

const addFeature = (point: Coordinate) =>
  new Feature({geometry: new Point(Proj.fromLonLat(point)),
    properties,
    name: "以后地位",
    population: 4000,
    rainfall: 500,
  });
const pointSource = new VectorSource({features: [addFeature(point)],
});
const clusterSourceForLayer = new Cluster({
  source: pointSource,
  distance: 50,
});
const pointLayer = new VectorLayer({
  source: clusterSourceForLayer,
  zIndex: 3,
  style: iconStyle,
});
map.addLayer(pointLayer);
pointLayer.set("baseMap", "iconLayer");

办法二

geojson 去渲染 mark

const iconStyle = () =>
  new Style({image: new Icon({ scale: 0.2, src: image}) });

const pointSource = new VectorSource({features: new GeoJSON().readFeatures(geojson, {
    dataProjection: "EPSG:4326",
    featureProjection: "EPSG:3857",
  }),
});

const clusterSourceForLayer = new Cluster({
  source: pointSource,
  distance: 50,
});

const pointLayer = new VectorLayer({
  source: clusterSourceForLayer,
  zIndex: 3,
  style: iconStyle,
});
map?.addLayer(pointLayer);
pointLayer.set("baseMap", "iconLayer");

geojson 格局

生成 geojson 的形式:

  1. 本人手动构建
  2. 应用 @turf/helpers,它提供了 pointfeatureCollection 等办法
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "id": "customer002",
        "name": "c2"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [119.777738303153, 32.91324329434815]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "id": "customerId007",
        "name": "张三"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [109.54393448864997, 35.7427088696462]
      }
    }
  ]
}

hover mark

popover

overlay 须要一个 dom 元素,这里是用过 ref 获取的

const o = new Overlay({element: ref.current});
map?.addOverlay(o);
setOverlay(o);

办法一

select 去做,它有个 select 事件

它事件参数中,有个 selected,如果不是空数组,阐明你鼠标正在 hover mark,就能够弹出 popover,显示你想要显示的内容

const select = new Select({
  condition: pointerMove,
  hitTolerance: 1,
  layers: [iconLayer],
  style: iconStyle,
});

select.on("select", (e) => {const { selected} = e;
  if (selected.length) {const [feature] = selected;
    const _feature = feature.get("features")[0];
    const id = _feature.get("id");
    const name = _feature.get("name");
    setContent({name, id});
    const coordinate = feature.get("geometry").flatCoordinates;
    overlay.setPosition(coordinate);
  } else {overlay.setPosition(undefined);
  }
});
map?.addInteraction(select);

办法二

select 去做,实质也是通过 pointerMove 事件,所以能够间接在 map 上监听 pointerMove 事件

具体的实现形式我没有去尝试,通过下面的推断,我感觉是可行的

map.on("pointerMove", (e) => {});

clear mark

通过 useEffect 返回的函数清理地图中的 mark

useEffect(() => {return () => {
    // 卸载页面中的 mark
    iconSource?.getFeatures().forEach((feature) => {iconSource?.removeFeature(feature);
    });
  };
}, [points, iconSource]);

办法 addInteraction、addOverlay、addLayer 区别

我没有搞清楚他们之间的区别,目前理解的是:

  • addLayer:是增加图层,图层分为:

    • 栅格:Tile(图片)
    • 矢量:Vectorgeojsonlerc
    • 矢量栅格:VectorTilepbf
  • addInteraction:增加 SelectModify
  • addOverlay:增加 OverlayControl

    • Popover 能够用 Overlay 去做

正文完
 0