2012-10-22 24 views
26

मेरे पास एक पुस्तिका पुस्तिका है जो सार्वजनिक कला टुकड़ों के लिए अंक दिखाती है, जो 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) 
} 
+1

मैं एक हैश मानचित्र 'पहचान बन जाएगा फियर -> मार्कर' और फिर जब आप किसी आइटम पर क्लिक करते हैं तो आईडी द्वारा मार्कर को देखें। –

उत्तर

35

फेलिक्स Kling सही है, लेकिन मैं अपने टिप्पणी एक छोटा सा पर विस्तार करेंगे ...

L.LayerGroup और L.FeatureGroup के बाद से (जो एल। जीओजेसन से फैली हुई है) में अलग-अलग परतों को पुनर्प्राप्त करने के तरीके नहीं हैं जिन्हें आपको एलजीओएसओएसओएन से विस्तारित करने की आवश्यकता होगी और ऐसी विधि जोड़ें या अद्वितीय आईडी से अपनी खुद की अलग मैपिंग को GeoJSON से CircleMarker पर रखें।

जियोज़सन को एक अद्वितीय आईडी की आवश्यकता नहीं है, लेकिन मुझे लगता है कि आपकी फ़ीड में मार्करों में "आईडी" नामक एक अद्वितीय आईडी विशेषता है। आपको इस अद्वितीय आईडी को उन लिंक पर जोड़ना होगा जिन्हें उपयोगकर्ता क्लिक कर सकते हैं ताकि लिंक मानचित्र पर सही मार्कर का चयन कर सकें। फिर आपको मानचित्र पर इसे चुनने के लिए मार्कर को पुनर्प्राप्त करने के लिए मार्करों को आईडी के मानचित्र को स्टोर करने की आवश्यकता होगी।

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

जब आप सर्वर से डेटा प्राप्त करते हैं तो आपको मार्कर मैप बनाने की आवश्यकता होती है। आपका pointToLayer विधि है कि ऐसा करने के लिए संशोधित किया जा सकता है:

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

यह एक सुपर सहायक स्पष्टीकरण है। समय देने के लिए धन्यवाद। – roy

+3

मुझे आश्चर्य है कि क्या यह letterJS के वर्तमान नवीनतम संस्करण के साथ ऐसा करने का एक आसान तरीका है। – fuzz

+0

मुझे पता है कि यह बहुत देर हो चुकी है, लेकिन मैंने एक ही चीज़ प्राप्त करने के लिए, पत्रक के नवीनतम संस्करण से विधियों का उपयोग करके नीचे एक उत्तर जोड़ा। –

4

मैं जानता हूँ कि यह एक पुराने सवाल है, लेकिन पत्रक एक अंतर्निहित समाधान प्रदान करने के लिए on it's way है और वहाँ एक (कुछ) में निर्मित रास्ता अब इसे प्राप्त करने के लिए है ...

दृष्टिकोण layerGroup इंटरफ़ेस का उपयोग करेगा। यह एक विधि प्रदान करता है, getLayer, ऐसा लगता है कि यह एक आईडी का उपयोग कर हमारे मार्करों को सही होगा। हालांकि, इस समय, कस्टम आईडी या नाम देने का कोई तरीका प्रदान नहीं करता है।

यह issue गिथब पर चर्चा करता है कि यह कैसे किया जाना चाहिए। इसके साथ ही कहा, आप प्राप्त कर सकते हैं और किसी भी मार्कर (या iLayer उस बात के लिए) की स्वत: जनरेट आईडी बचाने इसलिए की तरह:

let people = [...], 
    group = L.layerGroup() 

people.forEach(person => { 
    let marker = // ... create marker 

    group.addLayer(marker); 
    person.marker_id = group.getLayerId(marker) 
}) 

अब हम हर मार्कर की आईडी हमारे सरणी में प्रत्येक समर्थन वस्तु के साथ सहेजा है डेटा की हम आसानी से इसलिए की तरह बाद में मार्कर प्राप्त कर सकते हैं:

group.getLayer(person.marker_id) 

एक पूर्ण उदाहरण और अधिक विकल्पों के लिए this question के लिए this pen देखें ...