2012-10-22 11 views
26

公共の芸術作品のポイントを示すチラシマップがGeoJSONからレンダリングされています。マップの隣に同じGeoJSONデータのピースのリストを作成し、地図の外のリストからアイテムをクリックし、関連マーカーのポップアップをマップに表示させたいと考えています。地図の外側からリーフレットマーカーレイヤーとやりとりする方法は?

クリックイベントによって、アイテムのリストをそれぞれのマーカーにリンクするにはどうすればよいですか?

マイmap.jsファイルは次のようになります。L.LayerGroupとL.FeatureGroupので

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) 
} 
+1

を参照してください、私はハッシュマップ '同定を作成しますfier - > marker'をクリックし、項目をクリックするとIDでマーカーを参照します。 –

答えて

35

フェリックスクリングは正しいですが、私は彼のコメントに少し広げます...

(L.GeoJSONの拡張)には、L.GeoJSONから拡張してそのようなメソッドを追加するか、GeoJSONの独自のIDからCircleMarkerへの別個のマッピングを維持する必要がある個々のレイヤーを取得するメソッドがありません。

GeoJSONには一意のIDは必要ありませんが、フィードのマーカーには「id」という一意の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('<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方法は、それを行うように変更することができます

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

これは非常に参考になる説明です。時間を割いていただきありがとうございます。 – roy

+3

LeafletJSの最新バージョンでこれを行う簡単な方法があるのだろうかと思います。 – fuzz

+0

これは非常に遅いと知っていますが、同じことを達成するために、リーフレットの最新バージョンのメソッドを使用して、以下の回答を追加しました。 –

4

私はこれは古い質問です知っているが、リーフレットは、内蔵のソリューションを提供することにon it's wayで、今それを達成するための(やや)内蔵の方法があります...

このアプローチは、layerGroupインターフェイスを使用します。それは、IDを使って私たちのマーカーを得るのに完璧であるように聞こえる方法、getLayerを提供します。ただし、現時点ではリーフレットではありません。では、カスタムIDまたは名前を指定する方法はありません

Githubのissueでは、これを行う方法について説明しています。そうは言っても、あなたはとてもように(そのことについてまたは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) 

は完全な例とより多くのオプションのためのthis questionためthis pen ...

関連する問題