Search code examples
javascriptleafletgeojson

GeoJSON data is not displayed in leaflet with layer management plugins


I use a leaflet and have some problems displaying data from GeoJSON files.

I have no programming experience, so I used the manuals from the leafletjs developer site, and I found the answer to many questions here on stackoverflow.com.

At the first attempts I used the leaflet and jquery libraries. Everything worked, the code looked like this:

<html>

<head>
    <meta charset="utf-8" />
    <title>A simple map</title>
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
    <link rel="stylesheet" href="http://127.0.0.1:9009/leaflet.css" />
    <style>
        body {
            margin: 0;
            padding: 0;
        }

        #map {
            position: absolute;
            top: 0;
            bottom: 0;
            width: 100%;
        }
    </style>
</head>

<body>
    <div id="map"></div>
    <script src="http://127.0.0.1:9009/jquery.min.js"></script>
    <script src="http://127.0.0.1:9009/leaflet.js"></script>
    <script>

        var buildings = $.ajax({
            url: "http://127.0.0.1:9009/json/build1.geojson",
            dataType: "json",
            success: console.log("JSON file build1.geojson successfully loaded."),
            error: function(xhr) {
                alert(xhr.statusText)
            }
        });

        var vesPs = $.ajax({
            url: "http://127.0.0.1:9009/json/substVes1.geojson",
            dataType: "json",
            success: console.log("JSON file substVes1.geojson successfully loaded."),
            error: function(xhr) {
                alert(xhr.statusText)
            }
        });

        $.when(buildings,vesPs).done(function() {

            var REM = L.icon({
                iconUrl: 'http://127.0.0.1:9009/icons/REM.svg',
                iconSize: [32, 32],
                iconAnchor: [16, 16],
                popupAnchor: [0, -12]
            });
            var VEM = L.icon({
                iconUrl: 'http://127.0.0.1:9009/icons/VEM.svg',
                iconSize: [32, 32],
                iconAnchor: [16, 16],
                popupAnchor: [0, -12]
            });
            var Other = L.icon({
                iconUrl: 'http://127.0.0.1:9009/icons/Other.svg',
                iconSize: [32, 32],
                iconAnchor: [16, 16],
                popupAnchor: [0, -12]
            });

            var PS150_35_10 = L.icon({
                iconUrl: 'http://127.0.0.1:9009/icons/PS/PS150_35_10.svg',
                iconSize: [32, 32],
                iconAnchor: [16, 16],
                popupAnchor: [0, -16]
            });

            var buildings1 = L.layerGroup();
            var vesPs1 = L.layerGroup();

            var basemap1 = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png', {
                attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> &copy; <a href="http://cartodb.com/attributions">CartoDB</a>',
                subdomains: 'abcd',
                maxZoom: 19
            });

            var contMap1 = L.tileLayer.wms('http://localhost:8080/geoserver/Test002/ows?', {
                layers: 'Test002:DP_all',
                format: 'image/png',
                transparent: true
            });

            var map = L.map('map', {
                center: [48.32, 35.02],
                zoomSnap: 0.1,
                zoom: 8.5,
                layers: [basemap1, vesPs1]
            });

            var buildingsStyle

            function buildStyle(feature, layer) {
                layer.bindPopup(feature.properties.Sh_Name);
            };
            function vesPsStyle(feature, layer) {
                layer.bindPopup(feature.properties.Name);
            };

            L.geoJson(buildings.responseJSON, {
                style: buildingsStyle,
                onEachFeature: buildStyle,
                pointToLayer: function(feature, latlng) {
                    switch (feature.properties.Build_type) {
                        case "REM":
                            return L.marker(latlng, {icon: REM});
                        case "VEM":
                            return L.marker(latlng, {icon: VEM});
                        case "Other":
                            return L.marker(latlng, {icon: Other});
                        default:
                            return L.circleMarker(latlng, {color: "#000"});
                    }
                }
            }).addTo(buildings1);

            L.geoJson(vesPs.responseJSON, {
                style: buildingsStyle,
                onEachFeature: buildStyle,
                pointToLayer: function(feature, latlng) {
                    switch (feature.properties.Voltage) {
                        case "150/35/10кВ":
                            return L.marker(latlng, {icon: PS150_35_10});
                        default:
                            return L.circleMarker(latlng, {color: "#000"});
                    }
                }
            }).addTo(vesPs1);

            var baseLayers = {
                "Базовая карта": basemap1,
                "Контурная карта": contMap1
            };

            var overlays = {
                "Здания и сооружения": buildings1,
                "Подстанции ВЭС": vesPs1
            };

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

        });
    </script>
</body>

</html>

But then I decided to use plugins for grouping layers. I tried to use this: https://github.com/ismyrnow/leaflet-groupedlayercontrol and https://github.com/stefanocudini/leaflet-panel-layers

When I made mistakes in the code and something did not work, the console in the browser helped me, which indicated errors.

Now there are no errors in the console, but the GeoJSON data is not visible on the map. Where did I go wrong?

Here is one example:

<html>
<head>
    <title>My test Map</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="http://127.0.0.1:9009/newtest11/leaflet.css" />
    <link rel="stylesheet" href="http://127.0.0.1:9009/newtest11/leaflet-panel-layers.css" />

    <style>
        body {
            margin: 0;
            padding: 0;
        }

        #map {
            position: absolute;
            top: 0;
            bottom: 0;
            width: 100%;
        }
    </style>

</head>

<body>
<div id="map"></div>
<script src="http://127.0.0.1:9009/newtest11/leaflet.js"></script>
<script src="http://127.0.0.1:9009/newtest11/leaflet-panel-layers.js"></script>
<script src="http://127.0.0.1:9009/newtest11/jquery.min.js"></script>
<script>
    var map = L.map('map', {
        zoom: 8.5,
        zoomsnap: 0.1,
        center: L.latLng([48.32, 35.02]),
        attributionControl: false,
        maxBounds: L.latLngBounds([[49.37,32.64],[47.47,37.16]]).pad(0.5)
    }),

    osmLayer = new L.TileLayer('http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png');

    map.addLayer(osmLayer);

    var baseLayers = [
        {
            name: "Open Street Map",
            layer: osmLayer
        },
        {
            name: "Контурная карта",
            layer: L.tileLayer.wms('http://localhost:8080/geoserver/Test002/ows?', {
                    layers: 'Test002:DP_all',
                    format: 'image/png',
                    transparent: true
            })
        }
    ];

    var buildings = $.ajax({
            url: "http://127.0.0.1:9009/json/build1.geojson",
            dataType: "json",
            success: console.log("JSON file build1.geojson successfully loaded."),
            error: function(xhr) {
                alert(xhr.statusText)
            }
    });

    var REM = L.icon({
        iconUrl: 'http://127.0.0.1:9009/icons/REM.svg',
        iconSize: [32, 32],
        iconAnchor: [16, 16],
        popupAnchor: [0, -12]
    });
    var VEM = L.icon({
        iconUrl: 'http://127.0.0.1:9009/icons/VEM.svg',
        iconSize: [32, 32],
        iconAnchor: [16, 16],
        popupAnchor: [0, -12]
    });
    var Other = L.icon({
        iconUrl: 'http://127.0.0.1:9009/icons/Other.svg',
        iconSize: [32, 32],
        iconAnchor: [16, 16],
        popupAnchor: [0, -12]
    });

    var buildings1 = new L.LayerGroup();
    var buildingsStyle;

    function buildStyle(feature, layer) {
        layer.bindPopup(feature.properties.Sh_Name);
    };

    var geojsonlayer = new L.geoJson(buildings.responseJSON, {
        style: buildingsStyle,
        onEachFeature: buildStyle,
        pointToLayer: function(feature, latlng) {
            switch (feature.properties.Build_type) {
                case "REM":
                    return L.marker(latlng, {icon: REM});
                case "VEM":
                    return L.marker(latlng, {icon: VEM});
                case "Other":
                    return L.marker(latlng, {icon: Other});
                default:
                    return L.circleMarker(latlng, {color: "#000"});
            }
        }
    });

    var overLayers = [
        {
            group: "GeoJSON Layers",
            layers: [
                {
                    active: true,
                    name: "Drinking Water",
                    layer: geojsonlayer
                },
            ]
        }
    ];

    var panelLayers = new L.Control.PanelLayers(baseLayers, overLayers, {
    //compact: true,
    //collapsed: true,
    collapsibleGroups: true
    });

    map.addControl(panelLayers);

</script>

</body>
</html>

When using another plug-in, the situation is the same - the checkbox is present, it works, there are no errors in the console, but the data is not visible.

In the examples, I saw that the GeoJSON data is displayed. Perhaps the problem is, how do I work with GeoJSON data? Maybe I need another way? I have not found a solution to just such a question. Maybe this will help someone else...


Solution

  • In your 1st working code sample, you correctly wait for your AJAX call to complete (with $.when(buildings,vesPs).done) before trying to use its data to build Leaflet layers.

    In your 2nd not working code sample, you lack this waiting wrapper.