TransWikia.com

Regular-grid-cluster plugin for Leaflet

Geographic Information Systems Asked on November 19, 2021

I am starting with Leaflet and I am trying to use the Regular-grid-cluster plugin with no success. The following code works until the definition of the ‘const grid’ element. So, I can see the markers on the map but I can not implement the functionality of the plugin. Could you point me the errors in the code?

<!DOCTYPE html>
<html>

<head>
    <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" />
    <!-- Leaflet -->
    <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>
    <!-- Grid Cluster -->
    <link rel="stylesheet" href="https://adammertel.github.io/Leaflet.RegularGridCluster/demo/node_modules/leaflet/dist/leaflet.css" />
    <link rel="stylesheet" href="https://adammertel.github.io/Leaflet.RegularGridCluster/demo/zoomdisplay/zoomdisplay.css" />
    <link rel="stylesheet" href="https://adammertel.github.io/Leaflet.RegularGridCluster/demo/demo.css" />
    <script src="https://adammertel.github.io/Leaflet.RegularGridCluster/demo/node_modules/leaflet/dist/leaflet.js"></script>
    <script src="https://adammertel.github.io/Leaflet.RegularGridCluster/demo/zoomdisplay/zoomdisplay.js"></script>
    <script src="https://adammertel.github.io/Leaflet.RegularGridCluster/dist/leaflet-regulargridcluster.src.js"></script>
    <script src="https://adammertel.github.io/Leaflet.RegularGridCluster/demo/random_data/main.js"></script>
    <!-- GeoJSON file -->
    <script src="https://drive.google.com/uc?export=view&id=1Wiju0Kfbpj2YKTKog1u2ZceEXBdbb12r"></script>
</head>

<body>
    <div id="map" style="height: 98vh; width: 100hw"></div>
    <script>
    var map = L.map('map');
    var CartoDB_PositronNoLabels = L.tileLayer('https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}{r}.png', {
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>',
        subdomains: 'abcd',
        minZoom: 4,
        maxZoom: 18,
    }).addTo(map);
    var CartoDB_PositronOnlyLabels = L.tileLayer('https://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}{r}.png', {
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>',
        subdomains: 'abcd',
        minZoom: 4,
        maxZoom: 18,
    }).addTo(map);
    var southWest = L.latLng(-60, -80),
        northEast = L.latLng(-10, -60);
    var bounds = L.latLngBounds(southWest, northEast);
    map.setMaxBounds(bounds);
    map.on('drag', function() {
        map.panInsideBounds(bounds, {
            animate: false
        });
    });
    var layer = L.geoJSON(points, {
        onEachFeature: function(feature, layer) {
            var popupContent = "<p> <b>" + "FIC_ID: " + "</br>" + feature.properties.fic_id + "</b></br>" + "Región: " + "</br>" + feature.properties.reg_ejec + "</br>" + feature.properties.pro_ejec + ",</br> " + feature.properties.com_ejec + ",</br> " + feature.properties.num_informe + "</p>";
            layer.bindPopup(popupContent);
        }
    }).addTo(map);
    map.fitBounds(layer.getBounds());
    const rules = {
        cells: {
            "fillColor": {
                "method": "mean",
                "attribute": "fic_id",
                "scale": "size",
                "range": ["#d7191c", "#fdae61", "#ffffbf", "#a6d96a", "#1a9641"]
            },
            "color": "black",
            "fillOpacity": 0.2,
            "weight": 0
        },
        markers: {
            "color": "white",
            "weight": 2,
            "fillOpacity": 0.9,
            "fillColor": {
                "method": "mean",
                "attribute": "fic_id",
                "scale": "continuous",
                "range": ["#ffffb2", "#fecc5c", "#fd8d3c", "#e31a1c"]
            },
            "radius": {
                "method": "count",
                "attribute": "fic_id",
                "scale": "continuous",
                "range": [7, 17]
            }
        },
        texts: {}
    }
    const grid = L.regularGridCluster({
        rules: rules,
        gridMode: 'hexagon,
        showCells: true,
        showMarkers: true,
        showTexts: false
    });
    grid.addLayers(layer);
    grid.addTo(map);
    </script>
</body>

</html>

EDIT: I made some amendments to the code, now I can see the markers when testing but I still got an error, this time the console says:

leaflet-regulargridcluster.src.js:282 Uncaught TypeError:
layersArray.map is not a function
at i.addLayers (leaflet-regulargridcluster.src.js:282)
at test05.html:94

<!DOCTYPE html>
<html>

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

    <!-- Leaflet -->
    <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>
    
    <!-- Grid Cluster -->
    <link rel="stylesheet" href="https://adammertel.github.io/Leaflet.RegularGridCluster/demo/zoomdisplay/zoomdisplay.css" />
    <link rel="stylesheet" href="https://adammertel.github.io/Leaflet.RegularGridCluster/demo/demo.css" />

    <script src="https://adammertel.github.io/Leaflet.RegularGridCluster/demo/zoomdisplay/zoomdisplay.js"></script>
    <script src="https://adammertel.github.io/Leaflet.RegularGridCluster/dist/leaflet-regulargridcluster.src.js"></script>
    
    <!-- GeoJSON file -->
    <script src="https://drive.google.com/uc?export=view&id=1Wiju0Kfbpj2YKTKog1u2ZceEXBdbb12r"></script>
</head>

<body>
    <div id="map" style="height: 98vh; width: 100hw"></div>
    <script>
    var map = L.map('map');
    var CartoDB_PositronNoLabels = L.tileLayer('https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}{r}.png', {
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>',
        subdomains: 'abcd',
        minZoom: 4,
        maxZoom: 18,
    }).addTo(map);
    var CartoDB_PositronOnlyLabels = L.tileLayer('https://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}{r}.png', {
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>',
        subdomains: 'abcd',
        minZoom: 4,
        maxZoom: 18,
    }).addTo(map);
    var southWest = L.latLng(-60, -80),
        northEast = L.latLng(-10, -60);
    var bounds = L.latLngBounds(southWest, northEast);
    map.setMaxBounds(bounds);
    map.on('drag', function() {
        map.panInsideBounds(bounds, {
            animate: false
        });
    });
    var layer = L.geoJSON(points, {
        onEachFeature: function(feature, layer) {
            var popupContent = "<p> <b>" + "FIC_ID: " + "</br>" + feature.properties.fic_id + "</b></br>" + "Región: " + "</br>" + feature.properties.region_ejecucion + "</br>" + feature.properties.provincia_ejecucion + ",</br> " + feature.properties.comuna_ejecucion + ",</br> " + feature.properties.numero + "</p>";
            layer.bindPopup(popupContent);
        }
    }).addTo(map);
    map.fitBounds(layer.getBounds());
    const rules = {
        cells: {
            "fillColor": {
                "method": "mean",
                "attribute": "fic_id",
                "scale": "size",
                "range": ["#d7191c", "#fdae61", "#ffffbf", "#a6d96a", "#1a9641"]
            },
            "color": "black",
            "fillOpacity": 0.2,
            "weight": 0
        },
        markers: {
            "color": "white",
            "weight": 2,
            "fillOpacity": 0.9,
            "fillColor": {
                "method": "mean",
                "attribute": "fic_id",
                "scale": "continuous",
                "range": ["#ffffb2", "#fecc5c", "#fd8d3c", "#e31a1c"]
            },
            "radius": {
                "method": "count",
                "attribute": "fic_id",
                "scale": "continuous",
                "range": [7, 17]
            }
        },
        texts: {}
    }
    const grid = L.regularGridCluster({
        rules: rules,
        gridMode: 'square',
        showCells: true,
        showMarkers: true,
        showTexts: false
    });
    grid.addLayers(layer);
    grid.addTo(map);
    </script>
</body>

</html>

One Answer

Documentation on Regular-grid-cluster Leaflet plugin is not very extensive, but with the help of demo code at https://adammertel.github.io/Leaflet.RegularGridCluster/demo/random_data/ I was able to make your code work.

First thing you notice in demo code is that input to .addLayers of L.regularGridCluster is not Leaflet layer, but an array of objects. Description of structure of these objects in the docs is not very helping, but in the demo code such object has the following form:

{marker: markerLayer,
 properties: {
   a: maxValue,
   b: minValue
 }
}

Next thing is that markers to be used in L.regularGridCluster must support styling, like for example L.circleMarker.

And the last thing, when creating markers from GeoJSON, this layer should not be added to the map, since marker display is regulated by L.regularGridCluster.

Taken all this into account, your code could then look something like this (min and max properties are created random, as in demo code):

var data = [];

var layer = L.geoJSON(points, {
    pointToLayer: function (point, latLng) {
      var marker = L.circleMarker(latLng, {radius: 10});
      return(marker);
    },
    onEachFeature: function(feature, layer) {
      const properties = {
          a: 5 + Math.floor(Math.random() * 5),
          b: Math.floor(Math.random() * 5)
      };          
      data.push({marker: layer, properties: properties});
      var popupContent = "<p> <b>" + "FIC_ID: " + "</br>" + feature.properties.fic_id + "</b></br>" + "Región: " + "</br>" + feature.properties.reg_ejec + "</br>" + feature.properties.pro_ejec + ",</br> " + feature.properties.com_ejec + ",</br> " + feature.properties.num_informe + "</p>";
      layer.bindPopup(popupContent);
    }
});
map.fitBounds(layer.getBounds());

const grid = L.regularGridCluster({
    rules: rules,
    gridMode: 'hexagon',
    showCells: true,
    showMarkers: true,
    showTexts: false
});
grid.addLayers(data);
grid.addTo(map);

Answered by TomazicM on November 19, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP