2012-10-22 11 views
26

Mam ulotkę z mapą przedstawiającą punkty dla publicznych dzieł sztuki, wykonaną z GeoJSON. Obok mapy utworzyłem listę elementów z tych samych danych GeoJSON i chcę mieć możliwość kliknięcia elementu z listy poza mapą i pojawienia się odnośnego znacznika na mapie.Jak wchodzić w interakcje z warstwą znaczników ulotek spoza mapy?

Jak mogę połączyć listę pozycji z ich odpowiednimi znacznikami za pomocą zdarzenia kliknięcia?

Mój plik map.js wygląda następująco:

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

Chciałbym utworzyć hash mapa 'IDENTI fier -> marker', a następnie wyszukaj znacznik po ID, gdy klikniesz element. –

Odpowiedz

35

Felix Kling ma rację, ale ja rozszerzyć jego komentarzu trochę bitowego ...

Od L.LayerGroup i L.FeatureGroup (z którego rozciąga się L.GeoJSON) nie ma metod pobierania pojedynczych warstw, które trzeba rozszerzyć z L.GeoJSON i dodać taką metodę lub zachować własne oddzielne odwzorowanie z unikalnego identyfikatora do CircleMarker z GeoJSON.

GeoJSON nie wymaga unikalnego identyfikatora, ale zakładam, że znaczniki w pliku danych mają unikalny atrybut ID o nazwie "id". Będziesz musiał dodać ten unikalny identyfikator do linków, które użytkownik może kliknąć, aby linki mogły wybrać właściwy znacznik na mapie. Następnie musisz zapisać mapę identyfikatorów do znaczników, aby pobrać znacznik i wybrać go na mapie.

Musisz zbudować markerMap, gdy otrzymasz dane z serwera. Twoja metoda pointToLayer może zostać zmodyfikowany, aby to zrobić:

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

to jest bardzo pomocne wyjaśnienie. Dziękuję Ci za poświęcenie czasu. – roy

+3

Zastanawiam się, czy jest łatwiejszy sposób robienia tego z najnowszą wersją LeafletJS. – fuzz

+0

Wiem, że jest bardzo późno, ale dodałem poniżej odpowiedź, używając metod z najnowszej wersji Ulotki, aby osiągnąć to samo. –

4

wiem, że to starsza pytanie ale ulotka jest on it's way dostarczanie wbudowany rozwiązanie i jest (nieco) wbudowany w sposób do osiągnięcia go teraz ...

Podejście będzie korzystać z interfejsu layerGroup. Zapewnia ona metodę, getLayer, która brzmi, jakby to było idealne, aby nasze znaczniki używały identyfikatora. Jednak w tym momencie, Ulotka ma , a nie zapewnia dowolny sposób określenia niestandardowego identyfikatora lub nazwy.

Ten numer issue na Github omawia, w jaki sposób należy to zrobić. Z powiedział, że można dostać i zapisać automatycznie wygenerowany identyfikator każdej Marker (lub iLayer dla tej sprawy) tak:

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

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

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

Teraz, gdy mamy ID każdego znacznika zapisywane z każdym podporowego obiektu w naszej tablicy danych możemy łatwo dostać znacznik później tak:

group.getLayer(person.marker_id) 

Zobacz this pen dla pełnego przykład i this question więcej opcji ...

Powiązane problemy