전단지에서 레이어 켜기/끄기(더 복잡한 시나리오) (Toggle layers on and off in Leaflet (more complex scenario))


문제 설명

전단지에서 레이어 켜기/끄기(더 복잡한 시나리오) (Toggle layers on and off in Leaflet (more complex scenario))

QGIS에서 생성한 외부 라인 데이터를 로드하기 위해 jQuery의 getJSON 메소드를 사용하고 있습니다.

내가 하려고 하는 것은 내 레이어를 켜고 끄는 것입니다. 베이스맵에 대한 라디오 버튼이 없는 간단한 확인란입니다. 또한 지도가 처음 로드될 때 모든 레이어를 해제하고 싶습니다.

내 코드

var map=L.map('map').setView([41.9698, ‑87.6859], 12);

var basemap = L.tileLayer('http://a.tile.stamen.com/toner/{z}/{x}/{y}.png',
    {
      //attribution: would go here
      maxZoom: 17,
      minZoom: 9
    }).addTo(map);

//display geoJson to the map as a vector

var x = function(source, map)
{
var layers = L.geoJson(source,
    {

style: function(feature){
var fillColor, side=feature.properties.side;
    if (side==='Both') fillColor = '#309e2d';
    else if (side==='Neither') fillColor = '#d90f0f';
    else if (side==='West Only') fillColor = '#e27f14';
    else if (side==='East Only') fillColor = '#2b74eb';
    else if (side==='North Only') fillColor = '#eae42b';
    else if (side==='South Only') fillColor = '#552d04';
    else fillColor = '#f0f5f3';
    return { color: fillColor, weight: 3.5, opacity: null };
        },

onEachFeature: function(feature, geojson){
var popupText="<h1 class='makebold'>Border: </h1>"+feature.properties.name+"<br/>"+"<h1 class='makebold'>Which Side?: </h1>"+feature.properties.side;
geojson.bindPopup(popupText);
        }

    }).addTo(map);
};      

$.getJSON("data/Knox.geojson", function(source){ x(source, map); });
$.getJSON("data/abc.geojson", function(source){ x(source, map); });
$.getJSON("data/xyz.geojson", function(source){ x(source, map); });

L 앞에 변수를 할당하려고 했습니다. .geoJson 함수(var 레이어), 그리고 L.control.layers(null, layers).addTo(map); 작동하지 않는 것 같습니다.

몇 가지 콜백 함수(L.geoJson, style 및 oneEachFeature)와 이미 연결된 여러 외부 geojson에 대한 레이어 컨트롤을 어떻게 생성합니까? 미리 감사드립니다.


참조 솔루션

방법 1:

EDIT:

Since you clarified that you want just the entire collection to be switched on/off, it is even more simple (and almost like what you tried by assigning your L.geoJson to var layers), but you have to take care of asynchronous processes.

To avoid this issue, you could do something like:

var myLayerGroup = L.layerGroup(), // do not add to map initially.
    overlays = {
        "Merged GeoJSON collections": myLayerGroup
    };

L.control.layers(null, overlays).addTo(map);

function x(source, map) {
    // Merge the GeoJSON layer into the Layer Group.
    myLayerGroup.addLayer(L.geoJson({}, {
        style: function (feature) { /* … */ },
        onEachFeature: function (feature, layer) { /* … */ }
    }));
}

$.getJSON("data/Knox.geojson", function(source){
    x(source, map);
});

Then myLayerGroup will be gradually populated with your GeoJSON features, when they are received from the jQuery getJSON requests and they are converted by L.geoJson.


If my understanding is correct, you would like the ability to switch on/off independently each feature from your GeoJSON data?

In that case, you would simply populate your layers object while building the L.geoJson layer group, e.g. inside the onEachFeature function:

var layers = {};

L.geoJson(source, {

    style: function (feature) { /* … */ },

    onEachFeature: function(feature, layer){
        var popupText = "<h1 class='makebold'>Border: </h1>" +
                feature.properties.name + "<br/>" +
                "<h1 class='makebold'>Which Side?: </h1>" +
                feature.properties.side;

        layer.bindPopup(popupText);

        // Populate `layers` with each layer built from a GeoJSON feature.
        layers[feature.properties.name] = layer;
    }

});

var myLayersControl = L.control.layers(null, layers).addTo(map);

If you have more GeoJSON data to load and to convert into Leaflet layers, simply do exactly the same (adding built layer into layers in onEachFeature function) and build the Layers Control only once at the end, or use myLayersControl.addOverlay(layer).

Note: make sure to structure your code to take into account your several asynchronous processes, if you load each GeoJSON data in a separate request. Refer to jQuery Deferred object. Or simply create your Layers Control first and use the addOverlay method.

If you want them to be initially hidden from the map, simply do not add the geoJson layer to the map…

방법 2:

I learned a lot more about layer control in Leaflet than I expected, which is great. @ghybs offered really helpful suggestions.

My issue was about toggling external geoJson files on and off, particularly with the getJSON jQuery method. I was trying to assign a variable within my multiple callbacks, like:

var layers=L.geoJson(source,{ {style: /*....*/}, {onEachFeature: /*....*/}}

and then just going L.control.layers(null, layers).addTo(map);

That doesn't work (why? I still can't explain‑I'm quite the beginner‑programmer). The way I did get this to work was by creating my style and onEachFeature functions separately, like this:

function borders (feature){
var fillColor, side=feature.properties.side;
if (side==='Both') fillColor = '#309e2d';
else if (side==='Neither') fillColor = '#d90f0f';
else if (side==='West Only') fillColor = '#e27f14';
else if (side==='East Only') fillColor = '#2b74eb';
else if (side==='North Only') fillColor = '#eae42b';
else if (side==='South Only') fillColor = '#552d04';
else fillColor = '#f0f5f3';
return { color: fillColor, weight: 3.5, opacity: null };
    };

and

function popUp (feature, geojson){
var popupText="<h1 class='makebold'>
Border: </h1>"+feature.properties.name+"<br/>"+"<h1 class='makebold'>
Which Side</h1>"+feature.properties.side;geojson.bindPopup(popupText);
 };

and then assigning these directly as callbacks into the getJSON method. By doing it this way, I could create a variable before "drawing" my geoJson to the map with L.geoJson(). Then I could assign the variable dynamically(?) to the layer control:

$.getJSON("data/xyz.geojson", function(source){
var xyz = L.geoJson(source, {
    style: borders,
    onEachFeature: popUp});
togglelayer.addOverlay(xyz, 'This name shows up on the control')});
});

I stored the variable togglelayer like this:

var togglelayer = L.control.layers(null, null,{collapsed: false}).addTo(map);

This post was also helpful: How to add two geoJSON feature collections in to two layer groups


(by kadenzghybskadenz)

참조 문서

  1. Toggle layers on and off in Leaflet (more complex scenario) (CC BY‑SA 2.5/3.0/4.0)

#geojson #jquery #leaflet #toggle #javascript






관련 질문

Geodjango GeoJSON 직렬 변환기 기하학은 항상 'null'입니다. (Geodjango GeoJSON Serializer geometry always 'null')

전단지에서 레이어 켜기/끄기(더 복잡한 시나리오) (Toggle layers on and off in Leaflet (more complex scenario))

RethinkDB r.polygon() - GeoJSON LinearRing에는 최소 4개의 위치가 있어야 합니까? (RethinkDB r.polygon() - GeoJSON LinearRing must have at least four positions?)

Leaflet : GeoJSON 속성에서 GeoJSON 레이어 설정 아이콘 (Leaflet : setting icon for GeoJSON layer from GeoJSON property)

'GeoJsonLayer' 기호를 확인할 수 없습니다. (Cannot resolve symbol 'GeoJsonLayer ')

스키마의 mongoose geojson, "지역 키를 추출할 수 없습니다" 오류 (mongoose geojson in schema, "Can't extract geo keys" error)

Android Google 지도는 GeoJSON을 사용하여 마커를 설정합니다. (Android Google Maps set marker using GeoJSON)

GraphQl로 geojson 포인트를 쿼리하는 방법은 무엇입니까? (How to query a geojson point with GraphQl?)

geojson 포인트 데이터 마커가 전단지 맵에서 클러스터링되지 않습니다. (The geojson point data markers are not clustering in leaflet map)

전단지 geoJSON.onEachFeature는 함수가 아닌가요? (leaflet geoJSON.onEachFeature is not a function?)

Folium에서 특정 국가 강조 표시 (Highlight one specific country in Folium)

RGeo 및 Geojson으로 면적 계산 (Calculating area with RGeo and Geojson)







코멘트