1

I am able to following the Choropleth example of leaflet:

https://leafletjs.com/examples/choropleth/

Now, I want to add another overlay for another data, and with that I am also successful. My problem is on displaying or retrieving the data of the current active overlay, no matter what I did it is still showing the data of the 1st overlay even if I am selecting the 2nd overlay.

The "e" in the following example still displays the data of the 1st overlay:

    function highlightFeature(e) {

Here is how I am adding the overlays:

var overlays = {
    "PUI": PUIs,
    "Confirmed": Confirmed
};

var options = {
      position: 'bottomleft'
};

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

And here is how I am adding the layers:

    geojson = L.geoJson(item, {
                style: style,
                onEachFeature: onEachFeature
            }).addTo(PUIs);

I am not sure what I am missing, I tried using different "onEachFeature" for each overlay, and different functions for the different events but still it made no difference. What am I missing?

EDIT: With 1st overlay I meant the "PUIs", even if I uncheck it and select "Confirmed", when highlighting the map it is displaying the data for "PUIs" instead of the "Confirmed".

EDIT2: Here's the modified Choropleth example which shows the behaviour:

<!DOCTYPE html>
<html>
<head>

    <title>Choropleth Tutorial - Leaflet</title>

    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />

    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin=""/>
    <script src="https://unpkg.com/[email protected]/dist/leaflet.js" integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew==" crossorigin=""></script>


    <style>
        html, body {
            height: 100%;
            margin: 0;
        }
        #map {
            width: 600px;
            height: 400px;
        }
    </style>

    <style>#map { width: 800px; height: 500px; }
.info { padding: 6px 8px; font: 14px/16px Arial, Helvetica, sans-serif; background: white; background: rgba(255,255,255,0.8); box-shadow: 0 0 15px rgba(0,0,0,0.2); border-radius: 5px; } .info h4 { margin: 0 0 5px; color: #777; }
.legend { text-align: left; line-height: 18px; color: #555; } .legend i { width: 18px; height: 18px; float: left; margin-right: 8px; opacity: 0.7; }</style>
</head>
<body>

<div id='map'></div>
<script src="https://code.jquery.com/jquery-3.4.1.js"  integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU="  crossorigin="anonymous"></script>
<script src="assets/js/script.js"></script>

<script type="text/javascript" src="us-states.js"></script>

<script type="text/javascript">

    var cities = L.layerGroup();
    var cities2 = L.layerGroup();

    var map = L.map('map').setView([37.8, -96], 4);

    var xx = L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
        maxZoom: 18,
        attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
            '<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
            'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
        id: 'mapbox/light-v9',
        tileSize: 512,
        zoomOffset: -1
    }).addTo(map);


    // control that shows state info on hover
    var info = L.control();

    info.onAdd = function (map) {
        this._div = L.DomUtil.create('div', 'info');
        this.update();
        return this._div;
    };

    info.update = function (props) {
        this._div.innerHTML = '<h4>US Population Density</h4>' +  (props ?
            '<b>' + props.name + '</b><br />' + props.density + ' people / mi<sup>2</sup>'
            : 'Hover over a state');
    };

    info.addTo(map);


    // get color depending on population density value
    function getColor(d) {
        return d > 1000 ? '#800026' :
                d > 500  ? '#BD0026' :
                d > 200  ? '#E31A1C' :
                d > 100  ? '#FC4E2A' :
                d > 50   ? '#FD8D3C' :
                d > 20   ? '#FEB24C' :
                d > 10   ? '#FED976' :
                            '#FFEDA0';
    }

    function style(feature) {
        return {
            weight: 2,
            opacity: 1,
            color: 'white',
            dashArray: '3',
            fillOpacity: 0.7,
            fillColor: getColor(feature.properties.density)
        };
    }

    function highlightFeature(e) {
        var layer = e.target;

        layer.setStyle({
            weight: 5,
            color: '#666',
            dashArray: '',
            fillOpacity: 0.7
        });

        if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
            layer.bringToFront();
        }

        info.update(layer.feature.properties);
    }

    var geojson;

    function resetHighlight(e) {
        geojson.resetStyle(e.target);
        info.update();
    }

    function zoomToFeature(e) {
        map.fitBounds(e.target.getBounds());
    }

    function onEachFeature(feature, layer) {
        layer.on({
            mouseover: highlightFeature,
            mouseout: resetHighlight,
            click: zoomToFeature
        });
    }

    geojson = L.geoJson(statesData, {
        style: style,
        onEachFeature: onEachFeature
    }).addTo(cities);

    cities.addTo(map);

    var states2 = statesData;
    $.each(states2.features, function (index, item) {
        item.properties.density = 11;       
        geojson = L.geoJson(item, {
            style: style,
            onEachFeature: onEachFeature
        }).addTo(cities2);
    }); 


    map.attributionControl.addAttribution('Population data &copy; <a href="http://census.gov/">US Census Bureau</a>');


    var legend = L.control({position: 'bottomright'});

    legend.onAdd = function (map) {

        var div = L.DomUtil.create('div', 'info legend'),
            grades = [0, 10, 20, 50, 100, 200, 500, 1000],
            labels = [],
            from, to;

        for (var i = 0; i < grades.length; i++) {
            from = grades[i];
            to = grades[i + 1];

            labels.push(
                '<i style="background:' + getColor(from + 1) + '"></i> ' +
                from + (to ? '&ndash;' + to : '+'));
        }

        div.innerHTML = labels.join('<br>');
        return div;
    };

    legend.addTo(map);


    var baseLayers = {
        "Grayscale": xx
    };

    var overlays = {
        "Cities": cities,
        "Cities2": cities2
    };

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

</script>

</body>
</html>

Hovering over the cities will just display "11" which is the density of the 2nd overlay, and will reset according to the style of the 2nd overlay.

1 Answer 1

1

This not really a GIS problem but JS object manipulation problem, but anyway …

Where you think you are creating new object by assignment var states2 = statesData;, you are in reality just passing pointer to original object. When you are later changing properties of object referred to by states2 with statement item.properties.density = 11;, you are in fact changing properties of original object.

There are a few methods how to create clone of a object, the simplest being in first converting object to JSON string and then back to object, thus creating new object:

function objectClone(obj) {
  return JSON.parse(JSON.stringify(obj));
}

Your states2 assignment statement then becomes:

var states2 = objectClone(statesData);
1
  • Thank you so much, that did it, I was not aware of that intricacy, I thought I was just missing some setting in the leaflet.
    – dee-u
    Apr 15, 2020 at 12:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.