問題描述
我有一張傳單地圖,顯示公共藝術作品的點,從 GeoJSON 渲染.在地圖旁邊,我從相同的 GeoJSON 數據創建了一個片段列表,并且希望能夠單擊地圖外列表中的項目,并在地圖上顯示相關標記的彈出窗口.
I have a leaflet map showing points for public art pieces, rendered from GeoJSON. Next to the map, I created a list of the pieces from the same GeoJSON data and want to be able to click on an item from the list outside of the map and have the related marker's popup come up on the map.
如何通過點擊事件將項目列表鏈接到它們各自的標記?
How can I link the list of items to their respective markers through a click event?
我的 map.js 文件如下所示:
My map.js file looks like this:
var map;
var pointsLayer;
$(document).ready(function () {
map = new L.Map('mapContainer');
var url = 'http://{s}.tiles.mapbox.com/v3/mapbox.mapbox-streets/{z}/{x}/{y}.png';
var copyright = 'Map data © 2011 OpenStreetMap contributors, Imagery © 2011 CloudMade';
var tileLayer = new L.TileLayer(url, {
attribution: copyright
});
var startPosition = new L.LatLng(41.883333, - 87.633333);
map.on('load', function (e) {
requestUpdatedPoints(e.target.getBounds())
});
map.setView(startPosition, 13).addLayer(tileLayer);
map.on('moveend', function (e) {
requestUpdatedPoints(e.target.getBounds())
})
});
function requestUpdatedPoints(bounds) {
$.ajax({
type: 'GET',
url: '/SeeAll',
dataType: 'json',
data: JSON.stringify(bounds),
contentType: 'application/json; charset=utf-8',
success: function (result) {
parseNewPoints(result);
addToList(result)
},
error: function (req, status, error) {
alert('what happen? did you lose conn. to server ?')
}
})
}
function addToList(data) {
for (var i = 0; i < data.features.length; i++) {
var art = data.features[i];
$('div#infoContainer').append('<a href="#" class="list-link" title="' + art.properties.descfin + '"><div class="info-list-item">' + '<div class="info-list-txt">' + '<div class="title">' + art.properties.wrknm + '</div>' + '<br />' + art.properties.location + '</div>' + '<div class="info-list-img">' + art.properties.img_src + '</div>' + '<br />' + '</div></a>')
}
$('a.list-link').click(function (e) {
alert('now you see what happens when you click a list item!');
e.preventDefault()
})
}
function parseNewPoints(data) {
if (pointsLayer != undefined) {
map.removeLayer(pointsLayer)
}
pointsLayer = new L.GeoJSON();
var geojsonMarkerOptions = {
radius: 8,
fillColor: "#FF6788",
color: "YELLOW",
weight: 1,
opacity: 1,
fillOpacity: 0.5
};
L.geoJson(data, {
pointToLayer: function (feature, latlng) {
return L.circleMarker(latlng, geojsonMarkerOptions)
},
onEachFeature: function (feature, pointsLayer) {
pointsLayer.bindPopup(feature.properties.img_src + "<br />" + feature.properties.wrknm + "<br />" + feature.properties.artist + "<br />" + feature.properties.location + '<div class="description">' + feature.properties.descfin + '</div>')
}
}).addTo(map)
}
推薦答案
Felix Kling 是對的,但我會稍微擴展他的評論......
Felix Kling is right but I'll expand on his comment a little bit...
由于 L.LayerGroup 和 L.FeatureGroup(從 L.GeoJSON 擴展而來)沒有檢索各個層的方法,您需要從 L.GeoJSON 擴展并添加這樣的方法,或者保留您自己的單獨映射從 GeoJSON 到 CircleMarker 的唯一 ID.
Since L.LayerGroup and L.FeatureGroup (which L.GeoJSON extends from) don't have methods to retrieve individual layers you will need to either extend from L.GeoJSON and add such a method or keep your own seperate mapping from unique ID to CircleMarker from GeoJSON.
GeoJSON 不需要唯一 ID,但我假設您的提要中的標記具有稱為id"的唯一 ID 屬性.您需要將此唯一 ID 添加到用戶可以單擊的鏈接中,以便鏈接可以選擇地圖上的正確標記.然后,您需要將 id 映射存儲到標記,以便檢索標記以在地圖上選擇它.
GeoJSON does not require a unique ID but I'll assume that markers in your feed have a unique ID attribute called "id". You will need to add this unique ID to the links that the user can click on so that the links can select the right marker on the map. Then you'll need to store a map of ids to markers in order to retrieve the marker to select it on the map.
markerMap = {}; // a global variable unless you extend L.GeoJSON
// Add the marker id as a data item (called "data-artId") to the "a" element
function addToList(data) {
for (var i = 0; i < data.features.length; i++) {
var art = data.features[i];
$('div#infoContainer').append('<a href="#" class="list-link" data-artId="'+art.id+'" title="' + art.properties.descfin + '"><div class="info-list-item">' + '<div class="info-list-txt">' + '<div class="title">' + art.properties.wrknm + '</div>' + '<br />' + art.properties.location + '</div>' + '<div class="info-list-img">' + art.properties.img_src + '</div>' + '<br />' + '</div></a>')
}
$('a.list-link').click(function (e) {
alert('now you see what happens when you click a list item!');
//Get the id of the element clicked
var artId = $(this).data( 'artId' );
var marker = markerMap[artId];
//since you're using CircleMarkers the OpenPopup method requires
//a latlng so I'll just use the center of the circle
marker.openPopup(marker.getLatLng());
e.preventDefault()
})
}
從服務器獲取數據時需要構建markerMap.您的 pointToLayer 方法可以修改為:
You need to build the markerMap when you get the data from the server. Your pointToLayer method could be modified to do that:
L.geoJson(data, {
pointToLayer: function (feature, latlng) {
var marker = new L.CircleMarker( latlng, geojsonMarkerOptions );
markerMap[feature.id] = marker;
return marker;
},...
這篇關于如何從地圖外部與傳單標記層進行交互?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!