2012-10-22 31 views
26

Tôi có một bản đồ tờ rơi hiển thị các điểm cho các tác phẩm nghệ thuật công cộng, được hiển thị từ GeoJSON. Bên cạnh bản đồ, tôi đã tạo một danh sách các phần từ cùng một dữ liệu GeoJSON và muốn có thể nhấp vào một mục từ danh sách bên ngoài bản đồ và có cửa sổ bật lên của người đánh dấu có liên quan xuất hiện trên bản đồ.Làm cách nào để tương tác với lớp đánh dấu tờ rơi từ bên ngoài bản đồ?

Làm cách nào để liên kết danh sách các mục với điểm đánh dấu tương ứng thông qua sự kiện nhấp chuột?

tập tin map.js của tôi trông như thế này:

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

tôi sẽ tạo ra một bản đồ băm 'identi khốc liệt -> điểm đánh dấu' và sau đó tra cứu điểm đánh dấu bằng ID khi bạn nhấp vào một mục. –

Trả lời

35

Felix Kling là đúng nhưng tôi sẽ mở rộng trên bình luận của mình một chút ...

Kể từ L.LayerGroup và L.FeatureGroup (mà L.GeoJSON mở rộng từ) không có các phương thức để truy xuất các lớp riêng lẻ, bạn sẽ cần phải mở rộng từ L.GeoJSON và thêm một phương thức như vậy hoặc giữ ánh xạ riêng của riêng bạn từ ID duy nhất đến CircleMarker từ GeoJSON.

GeoJSON không yêu cầu ID duy nhất nhưng tôi cho rằng các điểm đánh dấu trong nguồn cấp dữ liệu của bạn có thuộc tính ID duy nhất được gọi là "id". Bạn sẽ cần thêm ID duy nhất này vào các liên kết mà người dùng có thể nhấp vào để các liên kết có thể chọn điểm đánh dấu phù hợp trên bản đồ. Sau đó, bạn sẽ cần phải lưu trữ một bản đồ của id để đánh dấu để lấy điểm đánh dấu để chọn nó trên bản đồ.

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

Bạn cần tạo điểm đánh dấuMap khi bạn nhận dữ liệu từ máy chủ. phương pháp pointToLayer của bạn có thể được sửa đổi để làm điều đó:

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

đây là giải thích cực kỳ hữu ích. Cảm ơn bạn đã dành thời gian. – roy

+3

Tôi tự hỏi liệu có cách nào dễ dàng hơn để làm điều này với phiên bản mới nhất của LeafletJS không. – fuzz

+0

Tôi biết điều này là rất muộn nhưng tôi đã thêm một câu trả lời dưới đây, sử dụng các phương pháp từ phiên bản mới nhất của Leaflet, để đạt được điều tương tự. –

4

Tôi biết đây là một câu hỏi cũ nhưng Tờ rơi là on it's way để cung cấp một giải pháp tích hợp và có một (hơi) được xây dựng theo cách để đạt được nó bây giờ ...

Cách tiếp cận sẽ sử dụng giao diện layerGroup. Nó cung cấp một phương thức, getLayer, nghe có vẻ như nó sẽ hoàn hảo nhận được điểm đánh dấu của chúng tôi bằng cách sử dụng một ID. Tuy nhiên, tại thời điểm này, Tờ rơi không không cung cấp bất kỳ cách nào để chỉ định ID tùy chỉnh hoặc tên.

Điều này issue trên Github thảo luận về cách thực hiện việc này. Với những gì đã nói, bạn có thể nhận và lưu ID tự động tạo ra của bất kỳ Marker (hoặc iLayer cho rằng vấn đề) như sau:

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

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

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

Bây giờ chúng ta có ID của mỗi điểm đánh dấu lưu với từng đối tượng ủng hộ trong mảng của chúng tôi dữ liệu chúng ta có thể dễ dàng nhận được điểm đánh dấu sau này như sau:

group.getLayer(person.marker_id) 

Xem this pen cho một ví dụ đầy đủ và this question cho các tùy chọn thêm ...

Các vấn đề liên quan