如何与地图外部的传单标记图层进行交互?

我有一个传单地图,显示从GeoJSON渲染的公共艺术作品的点。 在地图旁边,我创建了一个来自相同GeoJSON数据的片段列表,并且希望能够从地图外部的列表中单击某个项目,并在地图上显示相关标记的弹出窗口。

如何通过点击事件将项目列表链接到各自的标记?

我的map.js文件如下所示:

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('
' + '
' + '
' + art.properties.wrknm + '
' + '
' + art.properties.location + '
' + '
' + art.properties.img_src + '
' + '
' + '
') } $('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 + "
" + feature.properties.wrknm + "
" + feature.properties.artist + "
" + feature.properties.location + '
' + feature.properties.descfin + '
') } }).addTo(map) }

Felix Kling是对的,但我会稍微扩展一下他的评论……

由于L.LayerGroup和L.FeatureGroup(其中L.GeoJSON扩展)没有方法来检索单个图层,您需要从L.GeoJSON扩展并添加这样的方法或保持您自己的独立映射从唯一ID到来自GeoJSON的CircleMarker。

GeoJSON不需要唯一的ID,但我会假设您的Feed中的标记具有名为“id”的唯一ID属性。 您需要将此唯一ID添加到用户可以单击的链接,以便链接可以在地图上选择正确的标记。 然后,您需要将标记的地图存储到标记中,以便检索标记以在地图上选择标记。

 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('
' + '
' + '
' + art.properties.wrknm + '
' + '
' + art.properties.location + '
' + '
' + art.properties.img_src + '
' + '
' + '
') } $('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方法可以修改为:

 L.geoJson(data, { pointToLayer: function (feature, latlng) { var marker = new L.CircleMarker( latlng, geojsonMarkerOptions ); markerMap[feature.id] = marker; return marker; },... 

我知道这是一个较老的问题,但Leaflet正在提供内置解决方案,现在有一种(有点)内置方式来实现它…

该方法将使用layerGroup接口。 它提供了一个方法getLayer ,听起来像是完美的使用ID获取我们的标记。 但是,目前,Leaflet 没有提供任何指定自定义ID或名称的方法

Github上的这个问题讨论了如何做到这一点。 话虽如此,您可以获取并保存任何标记(或iLayer )的自动生成ID,如下所示:

 let people = [...], group = L.layerGroup() people.forEach(person => { let marker = // ... create marker group.addLayer( marker ); person.marker_id = group.getLayerId(marker) }) 

现在我们已经在我们的数据数组中为每个支持对象保存了每个标记的ID,我们可以稍后轻松获取标记,如下所示:

 group.getLayer(person.marker_id) 

请参阅此笔以获取完整示例和此问题以获取更多选项…