Función setStyle () para las características de GeoJSON - Folleto

23

Ok, como ya hice una pregunta muy larga sobre esto, pero como no recibió ninguna respuesta nueva por un tiempo, y para no confundirme en detalles, mantendré esta simple de la mejor manera que pueda.

Si no me equivoco, una setStylefunción para una característica particular con nombre sería la siguiente:

var bounds = [[54.559322, -5.767822], [56.1210604, -3.021240]];
var rect = L.rectangle(bounds, {color: "#ff7800", weight: 1}).addTo(map);

rect.setStyle({color: "#4B1BDE"});

... que cambiaría el color de naranja a azul. También conozco la resetStyle()función que revertirá el estilo al original.

Así es como estilizo mi GeoJSON:

var everything = L.geoJson(myfile, {
    onEachFeature: function(feature){
        array_of_layers.addLayer(feature);
    },
    style: function(feature){
            switch(feature.properties.name){
            case "belgium": return belgium_style; break;
            case "bosnia": return bosnia_style; break;
            case "denmark": return denmark_style; break;
            case "great_britain": return britain_style; break;
            case "greece": return greece_style; break;
            case "italy": return italy_style; break;
            case "serbia": return serbia_style; break;
            case "spain": return spain_style; break;
            }
    }

});

Lo que quiero hacer es hacer que solo un país sea azul y los otros grises, más adelante en el código. Es una cosa de dos pasos, pintar todos los países en gris y luego hacer uno azul.

Lo primero es que necesito un bucle que repita cada característica y setStyle()que todos los países se vuelvan grises. ¿Funciona si solo everything.setStyle({color: "#4B1BDE"})o algo así?

La segunda cosa es que (eso me da noches de insomnio), ¿cómo selecciono solo una función de un grupo de polígonos GeoJSON para trabajar? Solo el país que necesito pintar de azul.

Si se tratara de desplazar el mouse, podría ubicar un detector de eventos como se hace en los tutoriales de Leaflet. Pero independientemente de la interacción del usuario, quiero establecer y restablecer el estilo llamándolo con su nombre, como hice con el rectángulo anterior.

Doruk Karınca
fuente
1
Gracias por señalar la setStyle()función del folleto .
berto

Respuestas:

27

Esto funciona sin necesidad de eliminar la capa y volver a crear una nueva como se describe anteriormente:

geojson_layer.eachLayer(function (layer) {  
  if(layer.feature.properties.NAME == 'feature 1') {    
    layer.setStyle({fillColor :'blue'}) 
  }
});

Parece ser bastante más eficiente que eliminar y recrear la capa geoJson. Desde los documentos, GeoJSONse extiendeFeatureGroup una capa que a su vez se extiende LayerGroup.
Además, parece que cada característica geoJson tiene su propia capa en el FeatureGroup!

Davem M
fuente
¿Cómo activo este método cuando quiero cambiar el estilo dinámicamente?
Karussell
3
Creo que es equivalente a geojson_layer.setStyle (function ...)
PeterVermont
un problema aquí si cambia las capas, es decir, agrega capas secundarias, se crearán a partir del estilo original en las opciones, no según lo que configuró
MikeT
19

He escrito un pequeño código para diseñar una característica específica de geojson usando un folleto. puede probarlo en JSFiddle (Original, no funcional) , Funcional JSFiddle 2018-02-17 , o usar la siguiente prueba de código localmente.

Para este ejemplo, estoy usando archivos us-states.json pero se puede usar para cualquier archivo geojson.

Espero que sea de ayuda.

Aquí está el código:

<!DOCTYPE html>
<html>
<head>
<title>Leaflet Coloring Geojson Features</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="http://leafletjs.com/dist/leaflet.css" />
<!--[if lte IE 8]><link rel="stylesheet" href="../dist/leaflet.ie.css" /><![endif]-->
<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="http://code.jquery.com/jquery-1.9.1.min.js"></script> 
<script src="http://leafletjs.com/dist/leaflet.js"></script> 
<script type="text/javascript" src="http://leafletjs.com/examples/us-states.js"></script> 
<script type="text/javascript">
    $(document).ready(function () {
        init_map();
        init_geojson();
        $("#btn").on('click', function () {
            var stateName = $('#statename').val();
            console.log(stateName);
            init_geojson(stateName);
        });
    });
    var map, geojson, sn;

    function init_map() {
        map = L.map('map').setView([37.8, -96], 4);
        L.tileLayer('http://{s}.tile.cloudmade.com/{key}/22677/256/{z}/{x}/{y}.png', {
            attribution: 'Map data &copy; 2011 OpenStreetMap contributors, Imagery &copy; 2012 CloudMade',
            key: 'BC9A493B41014CAABB98F0471D759707'
        }).addTo(map);
        geojson = L.geoJson(statesData, {
            style: style
            //onEachFeature: onEachFeature,
        }).addTo(map);
    }

    function init_geojson(n) {
        console.log(geojson.options);
        map.removeLayer(geojson);
        if (n != "") {
            sn = n;
            console.log(sn);
            geojson = L.geoJson(statesData, {
                style: style
            }).addTo(map);
        }
    }

    function style(feature) {
        console.log(sn);
        if (sn == feature.properties.name) {
            return {
                weight: 2,
                opacity: 1,
                color: 'white',
                dashArray: '3',
                fillOpacity: 0.3,
                fillColor: '#ff0000'
            };
        } else {
            return {
                weight: 2,
                opacity: 1,
                color: 'white',
                dashArray: '3',
                fillOpacity: 0.3,
                fillColor: '#666666'
            };
        }
    }
</script>
<input type="text" id="statename" value="Alaska">
<input type="button" id="btn" value="Set Color"/>
</body>
</html>
Farhat Abbas
fuente
3
Entonces, se trataba de hacer que una style(feature)función verificara el feature.properties.namevalor. ¡Gracias!
Doruk Karınca
@ DorukKarınca Sí :)
Farhat Abbas
¡Increíble! ¡Esto es exactamente lo que estaba buscando!
joosthoek