Leaflet / Leaflet.VectorGrid

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

Soft redraw -- reapply styles without reloading tiles #159

Open gregallensworth opened 6 years ago

gregallensworth commented 6 years ago

See issue #43 and #50 for use cases, or replacing the options.vectorTileLayerStyles content in a VectorGrid layer, then calling redraw() to apply the styles. Ideally, there could be a "softer" redraw (a param to redraw() or a new refresh() function) which could reapply the styles, without re-downloading the tiles.

This would make for a significantly faster experience, as tile volume could be 1 MB or more, may be over a slow or metered network, and results in the layer becoming cleared and then reloaded one tile at a time.

2803media commented 5 years ago

Any update on this ?

Thanks

gregallensworth commented 5 years ago

No progress on my end, and there may not be for the foreseeable future.

As we dug into rendering vector tile data with Leaflet.VectorGrid, we found other issues in Leaflet's handling of vector tile data (rendering bugs, false edges at tile edges, polygons being duplicated into other places). As such, the project moved on to Mapbox GL JS API and https://github.com/mapbox/mapbox-gl-leaflet

2803media commented 5 years ago

Thanks for this update, I made a small trick to not use the redraw().

use 2 instances of vector grid and play with the layer control to enable or disable the wanted features

vectorGrid = L.vectorGrid.slicer( geojsonLayer, {
                rendererFactory: L.canvas.tile,
                vectorTileLayerStyles: {
                  sliced: {
                  fillOpacity: 0,
                  color: 'orange',
                  weight: 1,
                  stroke: true,
                  fill: false,
                  }
                },
                interactive: true,
                maxZoom: 29, // max zoom to preserve detail on
                tolerance: 20, // 5 simplification tolerance (higher means simpler)
                extent: 4096, //4096, // 4096 tile extent (both width and height)
                buffer: 64, // 64 default 64tile buffer on each side
                indexMaxZoom: 0, // 0 max zoom in the initial tile index
                indexMaxPoints: 100000, // 100000 max number of points per tile in the index
              }).addTo(map);

              vectorGrid2 = L.vectorGrid.slicer( geojsonLayer, {
                rendererFactory: L.canvas.tile,
                vectorTileLayerStyles: {
                  sliced: function(properties, zoom) {
                    if(typeof parcelles !== 'undefined'){
                      if(jQuery.inArray(properties.id,parcelles) !== -1){
                        return {
                          fillOpacity: 0.2,
                          color: 'red',
                          weight: 1,
                          stroke: true,
                          fill: true,
                        }
                      } else {
                        return {
                          fillOpacity: 0,
                          color: 'orange',
                          weight: 0,
                          stroke: true,
                          fill: false,
                        }
                      }
                    }
                  }
                },
                interactive: true,
                maxZoom: 29, // max zoom to preserve detail on
                tolerance: 20, // 5 simplification tolerance (higher means simpler)
                extent: 4096, //4096, // 4096 tile extent (both width and height)
                buffer: 64, // 64 default 64tile buffer on each side
                indexMaxZoom: 0, // 0 max zoom in the initial tile index
                indexMaxPoints: 100000, // 100000 max number of points per tile in the index
              }).addTo(map);
layerControl.addOverlay(vectorGrid, "Parcelles");
layerControl.addOverlay(vectorGrid2, "2018");

Not the best way but it's working for my use case!

fofi commented 1 year ago

Not very nice, but I am doing the following to avoid making new requests

_.forEach(layer._vectorTiles, function (tile) {
  _.forEach(tile._features, function (feature, id) {
    layer.setFeatureStyle(id, layerConf.vectorTileLayerStyles)
  })
})

I hope it helps

mcleantom commented 12 months ago

@fofi Do you have a more complete example of this? I am getting layer._vectorTiles is undefined

mcleantom commented 12 months ago

@gregallensworth @2803media If you guys have any new ideas on how to implement this, I would be happy to try do something new :) (Although this package hasnt been updated for a long time)

2803media commented 12 months ago

Sorry since I switched to maplibre which is easier for vectortiles than leaflet

fofi commented 12 months ago

@fofi Do you have a more complete example of this? I am getting layer._vectorTiles is undefined

Are you using the latest version of the lib? I am using it with L.vectorGrid.protobuf and with L.vectorGrid.slicer without any problem

Cant provide an example right now, but that property is on the codebase Check this https://github.com/Leaflet/Leaflet.VectorGrid/blob/0079d72add0e1bd5dcd4fac3b85248cb854755da/src/Leaflet.VectorGrid.js#L48