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 去做