Select Leaflet 地图上多个重叠特征(此处为多边形)的一个特征
Select one feature of multiple overlapping features (here polygons) on a Leaflet map
我有一张地图,上面渲染了多个可以相互重叠的多边形。我使用 https://github.com/mapbox/leaflet-pip 中的 leafletPip.pointInLayer(point, layer) 来确定哪些多边形重叠。这发生在 processClick 函数中。在 Vue 对象中,我使用多边形创建了地图和 GeoJSON 层。我现在想要的是以下功能:如果您单击地图上的一个点并且该点包含在多个多边形中,则您有一个类似选择工具的东西,例如在弹出窗口中,单击这些多边形之一并仅为该特定多边形触发 .on('click') 函数。我搜索了 Leaflet 的所有功能,但找不到任何真正有用的东西。现在,如果您单击包含在多个多边形中的一个点,您只会触发在空间上包含其他多边形的多边形的 .on('click')。
var mapVue = new Vue({
parent: vue_broadcaster,
el: '#map',
data: {
map: null,
layer: null
},
created: function () {
// Adding Leaflet map here
var map = L.map('map').setView([51.959, 7.623], 14);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
this.$set('map', map);
this.get_zones();
},
methods: {
switch_zone: function (zoneid) {
this.$dispatch('zoneSelected', zoneid)
},
get_zones: function () {
this.$http.get('/api/zones/', function (data) {
// Creation of the GeoJSON layer
var geoZone = {
"type": "FeatureCollection",
"features": []
};
for (var i = 0; i < data['Zones'].length; i++) {
geoZone.features.push({
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [[]]
},
"properties": {
"name": ""
}
})
geoZone.features[i].properties.name = data['Zones'][i]['Name'];
for (var j = 0; j < data['Zones'][i]['Geometry']['Coordinates'].length; j++) {
geoZone.features[i].geometry.coordinates[0].push([data['Zones'][i]['Geometry']['Coordinates'][j][1], data['Zones'][i]['Geometry']['Coordinates'][j][0]])
}
this.layer = new L.geoJson(geoZone)
.bindPopup(data['Zones'][i]['Name'])
.on('click', dispatchZoneID(data['Zones'][i]['Zone-id'], this))
.on('click', function (e) {
processClick(e.latlng.lat, e.latlng.lng)
})
.addTo(this.map)
};
})
}
}
});
// function for processing the clicks on the map
function processClick(lat, lng) {
var info = '';
var point = [lng, lat];
var match = leafletPip.pointInLayer(point, mapVue.layer, false);
if (match.length) {
for (var i = 0; i < match.length; i++) {
info +=
"<b>" + match[i].feature.properties.name + "<br>"
}
}
if (info) {
mapVue.map.openPopup(info, [lat, lng]);
}
};
// not important for this one
function dispatchZoneID(id, vue) {
return function () {
vue.$dispatch('zoneSelected', id)
}
};
我找到了适合我的解决方案,但它可能不是最优雅的解决方案。如果单击的点包含在多个多边形 (match.length > 1) 中,我将生成此 info 字符串。在每次迭代中,for 循环都会创建一个可点击的 link,然后根据 id 在点击时调用一个函数。所以我基本上必须在一个字符串中生成很多 HTML 并使用文字和字符串连接。然后我用 info 作为我的 html 参数调用 openPopup 函数。
function processClick(lat, lng) {
var info = '';
var point = [lng, lat];
var match = leafletPip.pointInLayer(point, mapVue.layer, false);
if (match.length > 1) {
for (var i = 0; i < match.length; i++) {
id = match[i].feature.properties.zoneid;
name = match[i].feature.properties.name;
info +=
"<b><a onclick='dispatchZoneID(\"" + id + "\")();'>"+ name + "</a><br>"
}
}
else dispatchZoneID(mapVue.zoneid)();
if (info) {
mapVue.map.openPopup(info, [lat, lng]);
}
};
我有一张地图,上面渲染了多个可以相互重叠的多边形。我使用 https://github.com/mapbox/leaflet-pip 中的 leafletPip.pointInLayer(point, layer) 来确定哪些多边形重叠。这发生在 processClick 函数中。在 Vue 对象中,我使用多边形创建了地图和 GeoJSON 层。我现在想要的是以下功能:如果您单击地图上的一个点并且该点包含在多个多边形中,则您有一个类似选择工具的东西,例如在弹出窗口中,单击这些多边形之一并仅为该特定多边形触发 .on('click') 函数。我搜索了 Leaflet 的所有功能,但找不到任何真正有用的东西。现在,如果您单击包含在多个多边形中的一个点,您只会触发在空间上包含其他多边形的多边形的 .on('click')。
var mapVue = new Vue({
parent: vue_broadcaster,
el: '#map',
data: {
map: null,
layer: null
},
created: function () {
// Adding Leaflet map here
var map = L.map('map').setView([51.959, 7.623], 14);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
this.$set('map', map);
this.get_zones();
},
methods: {
switch_zone: function (zoneid) {
this.$dispatch('zoneSelected', zoneid)
},
get_zones: function () {
this.$http.get('/api/zones/', function (data) {
// Creation of the GeoJSON layer
var geoZone = {
"type": "FeatureCollection",
"features": []
};
for (var i = 0; i < data['Zones'].length; i++) {
geoZone.features.push({
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [[]]
},
"properties": {
"name": ""
}
})
geoZone.features[i].properties.name = data['Zones'][i]['Name'];
for (var j = 0; j < data['Zones'][i]['Geometry']['Coordinates'].length; j++) {
geoZone.features[i].geometry.coordinates[0].push([data['Zones'][i]['Geometry']['Coordinates'][j][1], data['Zones'][i]['Geometry']['Coordinates'][j][0]])
}
this.layer = new L.geoJson(geoZone)
.bindPopup(data['Zones'][i]['Name'])
.on('click', dispatchZoneID(data['Zones'][i]['Zone-id'], this))
.on('click', function (e) {
processClick(e.latlng.lat, e.latlng.lng)
})
.addTo(this.map)
};
})
}
}
});
// function for processing the clicks on the map
function processClick(lat, lng) {
var info = '';
var point = [lng, lat];
var match = leafletPip.pointInLayer(point, mapVue.layer, false);
if (match.length) {
for (var i = 0; i < match.length; i++) {
info +=
"<b>" + match[i].feature.properties.name + "<br>"
}
}
if (info) {
mapVue.map.openPopup(info, [lat, lng]);
}
};
// not important for this one
function dispatchZoneID(id, vue) {
return function () {
vue.$dispatch('zoneSelected', id)
}
};
我找到了适合我的解决方案,但它可能不是最优雅的解决方案。如果单击的点包含在多个多边形 (match.length > 1) 中,我将生成此 info 字符串。在每次迭代中,for 循环都会创建一个可点击的 link,然后根据 id 在点击时调用一个函数。所以我基本上必须在一个字符串中生成很多 HTML 并使用文字和字符串连接。然后我用 info 作为我的 html 参数调用 openPopup 函数。
function processClick(lat, lng) {
var info = '';
var point = [lng, lat];
var match = leafletPip.pointInLayer(point, mapVue.layer, false);
if (match.length > 1) {
for (var i = 0; i < match.length; i++) {
id = match[i].feature.properties.zoneid;
name = match[i].feature.properties.name;
info +=
"<b><a onclick='dispatchZoneID(\"" + id + "\")();'>"+ name + "</a><br>"
}
}
else dispatchZoneID(mapVue.zoneid)();
if (info) {
mapVue.map.openPopup(info, [lat, lng]);
}
};