Leaflet / Leaflet.VectorGrid

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

Low precision interation with L.vectorGrid.protobuf #211

Open antuanjoseff opened 5 years ago

antuanjoseff commented 5 years ago

I am using L.vectorGrid.protobuf with rendererFactory: L.canvas.tile to show some vectortiles generated with tippecanoe.

Everything looks nice and fast, but the interactive:true option lacks some precision for some polygons.

You can see this happening on this gif: http://sigserver3.udg.edu/map-vectortiles/low-precision-interaction.gif

all polygons are drawn (even small ones) but some of them are not detected when onclick event occurs, so and adjacent polygon is selected instead.

Also, you can try it by yourself here: http://sigserver3.udg.edu/map-vectortiles

Any idea why this is happening? And better yet, how to solve it?

I have also tryed the SVG renderer with no problems, but there are too many polygons and everything goes very slow. My only option is to use CANVAS rendererFactory.

Thanks.

IvanSanchez commented 5 years ago

That looks like the tolerance option of the renderer is a bit too greedy for this case. It defaults to 15 under certain circumstances IIRC, so try setting it to zero.

antuanjoseff commented 5 years ago

I set tolerance to zero to the map object with no luck.

myRenderer = L.canvas({'tolerance': 0}); mymap = L.map('mapid',{'renderer': myRenderer}).setView(...);

Any more ideas?

chriszrc commented 3 years ago

@antuanjoseff if that's the code your app is using, it won't make a different. As far as I could tell, the only way to ensure that the vectorgrid renderer uses an adjust tolerance is like this:

L.vectorGrid.protobuf("https://free-{s}.tilehosting.com/data/v3/{z}/{x}/{y}.pbf.pict?key={key}", {
    vectorTileLayerStyles: { ... },
    rendererFactory: function (tileCoord: any, tileSize: any, opts: any) {
         opts.tolerance = 5;
        return (<any>canvas).tile(tileCoord, tileSize, opts);
      },
      interactive: true,
}).addTo(map);

But maybe I missed some other better way to get it in there-