Leaflet / Leaflet.VectorGrid

Display gridded vector data (sliced GeoJSON or protobuf vector tiles) in Leaflet 1.0.0
598 stars 194 forks source link

Highlight features with VectorGrid #156

Closed soli004 closed 5 years ago

soli004 commented 6 years ago

I have no luck getting this to work. What I need is that the polygon layer will turn gray when clicked on and you need to click again or mouseout to "deactivate" the highlight... The idea is that the user should be able to highlight the layer and see the cover area of the polygon an be able to move the map without loosing the highlight....sample code below


var data = new L.layerGroup();

$.getJSON("../data/3_pop.geojson", function(json) {

    var vectorGrid =  L.vectorGrid.slicer(json, {
                      maxZoom: 20,
                      rendererFactory: L.svg.tile,
                      vectorTileLayerStyles: {
                          sliced: function(properties, zoom){
                          var pop = properties.pop
                          if (pop <= 20000 ){
                            return {
                          weight: 0.5,
                          color: 'white',
                          opacity: 0.8,
                          fill: true,
                          fillColor: '#238B45',
                          stroke: true,
                          fillOpacity: 0.4
                          }
                          } else if (pop > 20000 && pop <= 30000){
                            return {
                          weight: 1,
                          color: 'white',
                          opacity: 0.8,
                          fill: true,
                          fillColor: '#41AB5D',
                          stroke: true,
                          fillOpacity: 0.4
                          }
                          } else if (pop > 30000 && pop <= 40000){
                            return {
                          weight: 1,
                          color: 'white',
                          opacity: 0.8,
                          fill: true,
                          fillColor: '#74C476',
                          stroke: true,
                          fillOpacity: 0.4
                          }
                         } else {
                          return {
                          weight: 0,
                          color: 'white',
                          opacity: 0,
                          fill: true,
                          fillColor: 'white',
                          stroke: false,
                          fillOpacity: 0.4
                          }
                          }
                         }},
                         interactive: true,
                       })

     .on('click', function(e) {
      var properties = e.layer.properties;
      L.popup()
        .setContent(
          "<b>Population</b>: " + properties.pop +
          "<br><b>Place</b>: " + properties.place)
        .setLatLng(e.latlng)
        .openOn(map);
                        })

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

        layer.setStyle({
        weight: 2,
        color: 'white',
        opacity: 1,
        fillColor: '#969696',
        dashArray: '',
        fillOpacity: 0.6
    });

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

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

function onEachFeature(feature, layer) {
    layer.on({
        click: highlightFeature,
        mouseout: resetHighlight,
    });
}
    vectorGrid.addTo(data)

                }) 
JamesLMilner commented 6 years ago

There is an example of highlighting in the docs: https://github.com/Leaflet/Leaflet.VectorGrid/blob/master/docs/demo-points.html

soli004 commented 6 years ago

Thanks, I tried on this example and it does not work and I get no error. When I activate the layer it does not show any colored layer, its all white with low opacity. Then when clicked I get random highlights on several polygons and are not able to clear. Is there a limit to "if else"? I can't see where the fault is...


var pw_4 = new L.layerGroup();

  var highlight;
    var clearHighlight = function() {
      if (highlight) {
        vectorGrid.resetFeatureStyle(highlight);
      }
      highlight = null;
    };

var vectorTileOptions = {
      rendererFactory: L.canvas.tile,
      maxNativeZoom: 14,
      vectorTileLayerStyles: {
                  sliced: function(properties, zoom){
                          var avl = properties.used_available
                          if (avl <= 500 ){
                            return {
                          weight: 0.5,
                          color: 'white',
                          opacity: 0.8,
                          fill: true,
                          fillColor: '#67000D',
                          stroke: true,
                          fillOpacity: 0.4
                          }
                          } else if (avl > 500 && avl <= 1200){
                            return {
                          weight: 1,
                          color: 'white',
                          opacity: 0.8,
                          fill: true,
                          fillColor: '#A50F15',
                          stroke: true,
                          fillOpacity: 0.4
                          }
                          } else if (avl > 1200 && avl <= 1800){
                            return {
                          weight: 1,
                          color: 'white',
                          opacity: 0.8,
                          fill: true,
                          fillColor: '#CB181D',
                          stroke: true,
                          fillOpacity: 0.4
                          }
                          } else if (avl > 1800 && avl <= 2400){
                            return {
                          weight: 1,
                          color: 'white',
                          opacity: 0.8,
                          fill: true,
                          fillColor: '#EF3B2C',
                          stroke: true,
                          fillOpacity: 0.4
                          }
                          } else if (avl > 2400 && avl <= 3000){
                            return {
                          weight: 1,
                          color: 'white',
                          opacity: 0.8,
                          fill: true,
                          fillColor: '#FB6A4A',
                          stroke: true,
                          fillOpacity: 0.4
                          }
                          } else if (avl > 3000 && avl <= 6000){
                            return {
                          weight: 1,
                          color: 'white',
                          opacity: 0.8,
                          fill: true,
                          fillColor: '#FC9272',
                          stroke: true,
                          fillOpacity: 0.4
                          }
                          } else if (avl > 6000 && avl <= 7000){
                            return {
                          weight: 1,
                          color: 'white',
                          opacity: 0.8,
                          fill: true,
                          fillColor: '#FCBBA1',
                          stroke: true,
                          fillOpacity: 0.4
                          }
                          } else if (avl > 7000 && avl <= 8000){
                            return {
                          weight: 1,
                          color: 'white',
                          opacity: 0.8,
                          fill: true,
                          fillColor: '#FEE0D2',
                          stroke: true,
                          fillOpacity: 0.4
                          }
                          } else if (avl > 8000 && avl <= 11000){
                            return {
                          weight: 1,
                          color: 'white',
                          opacity: 0.8,
                          fill: true,
                          fillColor: '#FFF5F0',
                          stroke: true,
                          fillOpacity: 0.4
                          }
                          } else {
                          return {
                          weight: 0,
                          color: 'white',
                          opacity: 0,
                          fill: true,
                          fillColor: 'white',
                          stroke: false,
                          fillOpacity: 0.4
                          }
                          }},
                          interactive: true,
                          getFeatureId: function(f) {
                          return f.properties.pr_txt;
                          }
                       }};

    $.getJSON("../data/pw_4.geojson", function(json) {

    var vectorGrid =  L.vectorGrid.slicer(json, vectorTileOptions)

     .on('click', function(e) {
      var properties = e.layer.properties;
      L.popup()
        .setContent(
          "<b>Nummer serie</b>: " + properties.nr_txt +
          "<br><b>Places</b>: " + properties.pw4 + '.st' +
          "<br><b>Time</b>: " + properties.free + " <b> Distance</b>: " + properties.dist + '.km')

        .setLatLng(e.latlng)
        .openOn(map);
        //var highlight;
        clearHighlight();
        highlight = e.layer.properties.pr_txt;
        vectorGrid.setFeatureStyle(highlight, {
          weight: 2,
          color: 'white',
          opacity: 1,
          fillColor: 'gray',
          fill: true,
          //radius: 6,
          fillOpacity: 0.5
        })
        L.DomEvent.stop(e);
      })

      var clearHighlight = function() {
      if (highlight) {
      vectorGrid.resetFeatureStyle(highlight);
      }
      highlight = null;
    };    

    map.on('click', clearHighlight);

    vectorGrid.addTo(pw_4)

                });
chriszrc commented 6 years ago

If you're seeing highlights on random polygons, chances are you are not following the guidelines for vectorgrid that specifies that every feature needs to have a unique id:

http://leaflet.github.io/Leaflet.VectorGrid/vectorgrid-api-docs.html#vectorgrid

I see you're using the "getFeatureId" function, you need to ensure that whatever property you're returning there, that its a unique number to that feature alone across all layers.