mapbox添加自定义图片绑定点击事件,弹窗为自定义组件
一、首先构建根据后端返回的数据构建geojson格式的数据,点位的geojson数据格式:
{"type": "FeatureCollection","features": [{"type": "Feature","geometry": {"type": "Point","coordinates": [117.1625,36.7074]},"properties": {"proIndex": 0}},{"type": "Feature","geometry": {"type": "Point","coordinates": [117.1701,36.6923]},"properties": {"proIndex": 1}},{"type": "Feature","geometry": {"type": "Point","coordinates": [117.17,36.6927]},"properties": {"proIndex": 2}},{"type": "Feature","geometry": {"type": "Point","coordinates": [117.1701,36.6916]},"properties": {"proIndex": 3}},{"type": "Feature","geometry": {"type": "Point","coordinates": [117.1445,36.6852]},"properties": {"proIndex": 4}}]
}
二、如果需要设置自定义图片作为点位,则要调用loadImage方法加载图片。
map.loadImage(imageUrl, function (error, image) {if (error) throw error;if (!map.hasImage('custom-marker')) { map.addImage('custom-marker', image);}map.addSource('geojson-source', {type: 'geojson',data: pointGeojsonData});map.addLayer({id: 'custom-marker-layer',type: 'symbol',source: 'geojson-source',layout: {'icon-image': 'custom-marker','icon-size': 0.1}});map.on('click', 'custom-marker-layer', function (e) {// console.log(e.features,'eeeeeeeeeeeeeeeeeeeee')// var features = map.queryRenderedFeatures(e.lnglat, { layers: ['custom-marker-layer'] });// if (!features.length) return;var feature = e.features[0];console.log(feature, 'feature')// 创建一个新的弹窗let p = Vue.extend(TestPopup);let vm = new p({propsData: {obj:feature.properties}})vm.$mount();var popup = new mapboxgl.Popup({offset: [0, -15],// closeButton: false,// closeOnClick: false})popup.setLngLat(feature.geometry.coordinates)popup.setDOMContent(vm.$el).addTo(map)})});
map.loadImage(imageUrl, function (error, image) { ... });
- 这行代码使用
map.loadImage
方法异步加载一个图像。imageUrl
是图像的URL。加载完成后,回调函数会被调用,参数error
如果有值表示加载出错,image
是加载成功的图像对象。
- 这行代码使用
if (error) throw error;
- 如果加载图像时出错,抛出错误。
if (!map.hasImage('custom-marker')) { map.addImage('custom-marker', image); }
- 检查地图上是否已经存在一个名为
custom-marker
的图像。如果不存在,则使用map.addImage
方法添加这个图像。
- 检查地图上是否已经存在一个名为
map.addSource('geojson-source', { type: 'geojson', data: pointGeojsonData });
- 向地图添加一个GeoJSON数据源。
geojson-source
是数据源的ID,type: 'geojson'
指定了数据源的类型,data: pointGeojsonData
是包含GeoJSON数据的变量。
- 向地图添加一个GeoJSON数据源。
map.addLayer({ ... });
- 在地图上添加一个图层。这个图层使用之前添加的GeoJSON数据源,并将自定义图标
custom-marker
作为图层的图标。图层的ID是custom-marker-layer
,类型是symbol
,它指定了图标的尺寸等布局属性。
- 在地图上添加一个图层。这个图层使用之前添加的GeoJSON数据源,并将自定义图标
map.on('click', 'custom-marker-layer', function (e) { ... });
- 为
custom-marker-layer
图层添加一个点击事件监听器。当用户点击这个图层上的点时,会触发回调函数。
- 为
var feature = e.features[0];
- 从事件对象
e
中获取被点击的特征(feature)。e.features
是一个数组,包含所有在点击位置被渲染的特征。这里只取第一个特征。
- 从事件对象
console.log(feature, 'feature')
- 在控制台打印被点击的特征。
- 接下来的几行代码使用Vue.js创建一个新的组件实例,并将其内容设置为Mapbox弹窗的内容。
let p = Vue.extend(TestPopup);
使用Vue的extend
方法创建一个TestPopup
组件的构造器。let vm = new p({ propsData: { obj: feature.properties } });
创建一个新的Vue实例,将点击的特征的属性作为props传递给TestPopup
组件。vm.$mount();
手动挂载Vue实例。
var popup = new mapboxgl.Popup({ ... });
- 创建一个新的Mapbox弹窗实例,并设置一些选项,如偏移量和是否显示关闭按钮。
popup.setLngLat(feature.geometry.coordinates)
- 设置弹窗的位置为被点击特征的地理坐标。
popup.setDOMContent(vm.$el).addTo(map)
- 将Vue实例的DOM元素设置为弹窗的内容,并将弹窗添加到地图上
三、在App.vue中设置取消mapbox默认的弹窗样式
.mapboxgl-popup-tip {display: none;
}
.mapboxgl-popup-content {padding:0;
}
四、弹窗组件通过props接收传过来的属性的值。
组件成功弹窗!