30

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('<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)
}
4

2 に答える 2

36

Felix Kling は正しいですが、彼のコメントを少し拡張します...

L.LayerGroup と L.FeatureGroup (L.GeoJSON の拡張元) には個々のレイヤーを取得するメソッドがないため、L.GeoJSON から拡張してそのようなメソッドを追加するか、独自の個別のマッピングを一意の ID からGeoJSON の 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;
    },...
于 2012-10-22T13:42:12.357 に答える
5

これは古い質問であることは知っていますが、リーフレットは組み込みのソリューションを提供する途中であり、現在それを達成するための(ある程度)組み込みの方法があります...

アプローチは、layerGroupインターフェースを使用することです。getLayerこれは、ID を使用してマーカーを取得するのに最適なメソッドを提供します。ただし、現時点では、Leafletはカスタム ID または名前を指定する方法を提供していませ

Github のこの問題では、これを行う方法について説明しています。そうは言っても、次のように、任意のマーカーの自動生成された ID を取得して保存できます (さらに言えばiLayer)。

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)

完全な例についてはこのペンを、その他のオプションについてはこの質問を参照してください...

于 2016-06-07T13:55:27.127 に答える