Leaflet.VectorGrid icon indicating copy to clipboard operation
Leaflet.VectorGrid copied to clipboard

Soft redraw -- reapply styles without reloading tiles

Open gregallensworth opened this issue 6 years ago • 8 comments

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.

gregallensworth avatar Apr 11 '18 19:04 gregallensworth

Any update on this ?

Thanks

2803media avatar May 08 '19 15:05 2803media

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

gregallensworth avatar May 08 '19 16:05 gregallensworth

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!

2803media avatar May 08 '19 16:05 2803media

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

fofi avatar Apr 25 '23 16:04 fofi

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

mcleantom avatar Sep 07 '23 08:09 mcleantom

@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)

mcleantom avatar Sep 07 '23 08:09 mcleantom

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

2803media avatar Sep 07 '23 08:09 2803media

@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

fofi avatar Sep 07 '23 10:09 fofi