加载多个 GeoJSON,如何为每个使用不同的 markers/pop-ups

Loading multiple GeoJSONs, how to use different markers/pop-ups for each

我花了一整天的时间试图弄清楚如何加载多个 GeoJSON。由于早期的 SE 问题,终于弄明白了。现在我一直在尝试对每个 GeoJSON

进行符号化

当然,我想用不同的方式来表示每个 GeoJSON,但我真的不知道下一步该怎么做。旧代码(底部)在单层上运行良好,但我不知道如何针对各个 geojsons 修改它。

我希望我的代码不会太糟糕或难以阅读!

//blahblahblah, initial headers, etc

//load breweries GeoJSONs from external file
var breweries = new L.geoJson();
breweries.addTo(map);

$.ajax({
    dataType: "json",
    url: "breweries.geojson",
    success: function(data) {
        $(data.features).each(function(key, data) {
            breweries.addData(data);
        });
    }
}).error(function() {});

//load wineries GeoJSON from external file
var wineries = new L.geoJson();
wineries.addTo(map);

$.ajax({
    dataType: "json",
    url: "winetest.geojson",
    success: function(data) {
        $(data.features).each(function(key, data) {
            wineries.addData(data);
        });
    }
}).error(function() {});


//skip this intermediate stuff


//load Brewery GeoJSON from an external file
$.getJSON("breweries.geojson", function(data) {
    var pintGlass = L.icon({
        iconUrl: 'glass.png',
        iconSize: [24, 48]
    });

    var popupMarker = L.geoJson(data, {
        pointToLayer: function(feature, latlng) {
            var marker = L.marker(latlng, {
                icon: pintGlass
            });
            //popup shows NAME, ADDRESS, URL and opens the URL in a new window/tab
            marker.bindPopup("<strong>" + feature.properties.NAME + "</strong><br/>" + feature.properties.STREETNUM + " " + feature.properties.STREET + ", " + feature.properties.CITY + "<br/>" + "<a target = _blank href=" +
                feature.properties.URL + ">" + feature.properties.URLDISPLAY + "</a>");
            return marker;
        }
    });
});

首先,您可以将 pintGlass 图标定义移到 $.getJSON 回调函数之外,因为它不依赖于返回数据的值:

var pintGlass = L.icon({
  iconUrl: 'glass.png',
  iconSize: [24, 48]
});

然后,如果您想在 $.getJSON 回调函数之外访问您的 L.geoJson 层(例如,如果您稍后在构建层控件时要引用它),您将还需要先在 $.getJSON 之外定义那个。您实际上可以通过将 false 作为第一个参数传递给它来创建一个空的 L.geoJson 对象,同时仍然设置选项,这些选项将应用于您稍后添加的任何数据:

var popupMarker = L.geoJson(false, {
    pointToLayer: function(feature, latlng) {
        var marker = L.marker(latlng, {
            icon: pintGlass
        });
        //popup shows NAME, ADDRESS, URL and opens the URL in a new window/tab
        marker.bindPopup("<strong>" + feature.properties.NAME + "</strong><br/>" + feature.properties.STREETNUM + " " + feature.properties.STREET + ", " + feature.properties.CITY + "<br/>" + "<a target = _blank href=" +
            feature.properties.URL + ">" + feature.properties.URLDISPLAY + "</a>");
        return marker;
    }
}).addTo(map);

然后,您的 $.getJSON 函数无需执行任何操作,只需将数据添加到图层即可:

$.getJSON("breweries.geojson", function(data) {
    popupMarker.addData(data);
});

现在复制和修改这段代码来处理酒厂应该比较简单了。假设您有一个名为 grapes.png 的图标,它看起来像这样:

var wineIcon = L.icon({
  iconUrl: 'grapes.png',
  iconSize: [32, 32]
});

var wineMarker = L.geoJson(false, {
  pointToLayer: function(feature, latlng) {
    var marker = L.marker(latlng, {
      icon: wineIcon
    });
    //popup shows NAME, ADDRESS, URL and opens the URL in a new window/tab
    marker.bindPopup("<strong>" + feature.properties.NAME + "</strong><br/>" + feature.properties.STREETNUM + " " + feature.properties.STREET + ", " + feature.properties.CITY + "<br/>" + "<a target = _blank href=" +
      feature.properties.URL + ">" + feature.properties.URLDISPLAY + "</a>");
    return marker;
  }
}).addTo(map);

$.getJSON("winetest.geojson", function(data) {
  wineMarker.addData(data);
});

至于图层控件,这是一个单独的问题,但是通过查看 layer control tutorial 应该很容易回答这个问题。

下面是一个示例 fiddle,其中包含一些虚拟数据,显示了工作中的一切:

http://jsfiddle.net/nathansnider/tuppLt0b/

另一个例子,其中 L.geoJsonpointToLayeronEachFeature 分解成单独的函数:

http://jsfiddle.net/nathansnider/Lo8cmuvt/

(顺便说一下,代码开头的 $.ajax 例程是多余的,因为 $.getJSON 是一个 shorthand 方法,它做的事情完全相同。)