Mapbox实现拖拽标记点、高亮选中效果、拖拽实现点位置编辑

Mapbox实现点图层多点拖动、标记点标记效果

现通过监听地图的点击、鼠标移动和鼠标松开事件来实现拖拽操作,根据事件的发生情况更新标记点的位置,并提供了添加新点和取消编辑的功能。
效果视频链接:https://live.csdn.net/v/381248
在这里插入图片描述
在这里插入图片描述
实现思路:
构造函数:构造函数接受地图对象 map、图层ID layerID 和属性 xzData,并初始化类的属性。
edit 方法:该方法用于开始编辑标记点。在鼠标移动事件处理程序中,如果正在拖动且已选择特征,则更新选定特征的坐标。在鼠标松开事件处理程序中,如果正在拖动且已选择特征,则将 isDragging 设置为 false,表示拖动结束。
getSelectedFeatureIndex 方法:该方法接受一个选定的特征对象,并返回该特征在特征数组中的索引。
updateFeaturePosition 方法:该方法接受一个特征索引 index 和新的坐标 newCoordinates,并更新该索引对应特征的坐标为新坐标。
cancelEdit 方法:该方法用于取消编辑操作。它会将正在拖动标记点的状态重置为初始状态,恢复标记点的位置到初始状态,并移除事件监听器。
addNewPoint 方法:该方法接受新的经纬度坐标 lngLat,并在特征数组中添加一个新的点特征,然后更新地图上的数据源。

相关代码
调用封装的构造类

             // 图层合集
    addLayers() {
      this.layers = {
        Pit3DgcbwdData: new Pit3DgcbwdDataLayer(),
        heatMap: new HeatMapLayer(),
        dragMarker:new DragMarker(this.map, "pit3DgcbwdData", "xz")
      };
    },
        //开始编辑
        edit(data,type) {
          let dataJson=JSON.parse(JSON.stringify(this.json))
          let index=null
          for (let i = 0; i < dataJson.features.length; i++) {
            if (dataJson.features[i].properties.name == data.properties.name) {
              index = i;
            }
          }
          if(type==1){
            dataJson.features[index].properties["xz"] = 1;
            this.layers.dragMarker.edit(dataJson);
            // 在拖动操作完成后获取坐标值
            this.map.on("mouseup", () => {
              console.log("打印拖动后的坐标", this.layers.dragMarker.xy);
            });
          }else{
            dataJson.features[index].properties["editID"] = 0;
            this.layers.dragMarker.edit(dataJson);
          }
          },

构造类

class DragMarker {
  constructor(map, layerID,xzData) {
    this.map = map;
    this.layerID = layerID;
    this.featuresArray = null;
    this.xzData = xzData;
    this.xy = "";
    this.selectedFeatureIndex = null;
    this.initialCoordinates = null;
    this.isDragging = false;
  }
  edit(featuresA) {
    let that = this;
    let featuresArray=this.featuresArray
    if(featuresA){
      featuresArray=featuresA
      this.featuresArray=featuresA
    }
    this.map.getSource(this.layerID).setData(featuresArray);
    this.map.on("click", function (e) {
      var features = that.map.queryRenderedFeatures(e.point, {});
      if (features.length > 0 && features[0].properties[that.xzData] == 1) {
        var selectedFeature = features[0];
        that.selectedFeatureIndex = that.getSelectedFeatureIndex(selectedFeature);
        if (that.selectedFeatureIndex !== null) {
          that.initialCoordinates = selectedFeature.geometry.coordinates;
          that.isDragging = true;
        }
      } else {
        that.cancelEdit();
      }
    });
    this.map.on("mousemove", function (e) {
      if (that.isDragging && that.selectedFeatureIndex !== null) {
        var newCoordinates = that.map.unproject(e.point);
        that.updateFeaturePosition(that.selectedFeatureIndex, newCoordinates);
      }
    });

    this.map.on("mouseup", function (e) {
      if (that.isDragging && that.selectedFeatureIndex !== null) {
        that.isDragging = false;
        that.initialCoordinates = null;
      }
    });
  }
  getSelectedFeatureIndex(selectedFeature) {
    const selectedId = selectedFeature.properties.id;
    for (let i = 0; i < this.featuresArray.features.length; i++) {
      if (this.featuresArray.features[i].properties.id === selectedId) {
        return i;
      }
    }
    return null;
  }
  updateFeaturePosition(index, newCoordinates) {
    this.featuresArray.features[index].geometry.coordinates = [newCoordinates.lng, newCoordinates.lat];
    this.map.getSource(this.layerID).setData(this.featuresArray);
    this.xy = newCoordinates.lng + "," + newCoordinates.lat;
  }

  cancelEdit() {
    // 恢复标记点位置到初始状态
    if (this.selectedFeatureIndex !== null && this.initialCoordinates !== null) {
      this.featuresArray.features[this.selectedFeatureIndex].geometry.coordinates = this.initialCoordinates;
      this.map.getSource(this.layerID).setData(this.featuresArray);
    }

    this.isDragging = false;
    this.selectedFeatureIndex = null;
    this.initialCoordinates = null;

    // 移除事件监听器
    this.map.off("click");
    this.map.off("mousemove");
    this.map.off("mouseup");
  }
  addNewPoint(lngLat) {
    const newFeature = {
        type: 'Feature',
        properties: {

        },
        geometry: {
            type: 'Point',
            coordinates: [lngLat.lng, lngLat.lat]
        }
    };
    this.featuresArray.features.push(newFeature);
    this.map.getSource(this.layerID).setData(this.featuresArray);
}
}
export default DragMarker;
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个使用MapboxGL添加一个marker并实现高亮闪烁效果的完整代码示例: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>MapboxGL Marker Highlight Animation</title> <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /> <script src="https://api.mapbox.com/mapbox-gl-js/v2.5.1/mapbox-gl.js"></script> <link href="https://api.mapbox.com/mapbox-gl-js/v2.5.1/mapbox-gl.css" rel="stylesheet" /> <style> body { margin: 0; padding: 0; } #map { position: absolute; top: 0; bottom: 0; width: 100%; } .highlight-animation { animation: highlight 1s infinite; } @keyframes highlight { 0% { opacity: 1; transform: scale(1); } 50% { opacity: 0.5; transform: scale(1.5); } 100% { opacity: 1; transform: scale(1); } } </style> </head> <body> <div id="map"></div> <script> mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN'; var lng = -122.4194; // 经度 var lat = 37.7749; // 纬度 var zoomLevel = 12; // 缩放级别 // 创建地图实例 var map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/streets-v11', center: [lng, lat], zoom: zoomLevel }); // 创建一个图层,并向地图添加一个marker var marker = new mapboxgl.Marker({ element: createMarkerElement() }) .setLngLat([lng, lat]) .addTo(map); // 为标记元素添加动画类 marker.getElement().classList.add('highlight-animation'); // 创建标记元素及样式 function createMarkerElement() { var el = document.createElement('div'); el.className = 'marker'; el.style.backgroundImage = 'url(https://example.com/your-marker-icon.png)'; // 替换为您自己的标记图标URL el.style.width = '40px'; el.style.height = '40px'; el.style.backgroundRepeat = 'no-repeat'; el.style.backgroundSize = 'cover'; return el; } </script> </body> </html> ``` 请确保将YOUR_MAPBOX_ACCESS_TOKEN替换为您自己的Mapbox访问令牌,并将`https://example.com/your-marker-icon.png`替换为您自己的标记图标的URL。 通过上述代码,您将能够在MapboxGL地图上添加一个marker,并为其添加高亮闪烁的动画效果。根据您的需求,您可以调整地图的样式、标记位置和动画效果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

此人很懒€

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值