Leaflet / Leaflet.VectorGrid

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

sliced mapicons #188

Closed tobwen closed 5 years ago

tobwen commented 5 years ago

I've got a lot of points in PBF format. Anyone with an idea, why Leaflet's default icons get sliced?

canvas Map: OpenStreetMap contributors

That's my code:

var buildingsURL = "http://localhost/buildings/{z}/{x}/{y}.pbf";
var buildingsOptions = {
    rendererFactory: L.canvas.tile,
    vectorTileLayerStyles: {
        'buildings': { icon: new L.Icon.Default() },
    },
    attribution: '',
    minZoom: 12,
    maxZoom: 22
};
var buildings = L.vectorGrid.protobuf(buildingsURL, buildingsOptions);

I'm on Leaflet 1.3.4 with latest Leaflet.VectorGrid release. The PBFs have been create by OGR with default settings for buffer and extent (but since this is point data, this might not even matter?).

tomchadwin commented 5 years ago

When you generate your tiles, I think you need to set your tile buffers to a value equal to or larger than the height of the marker icon. I'm not 100% sure, though.

tobwen commented 5 years ago

Okay, I'll give it a go and raise the values. But I thought, buffer only is needed if a geometry clips the border of a tile (which isn't the case when dealing with points).

These are OGR's default values:

EXTENT=positive_integer. Number of units in a tile. The greater, the more accurate geometry coordinates (at the expense of tile byte size). Defaults to 4096

BUFFER=positive_integer. Number of units for geometry buffering. This value corresponds to a buffer around each side of a tile into which geometries are fetched and clipped. This is used for proper rendering of geometries that spread over tile boundaries by some rendering clients. Defaults to 80 if EXTENT=4096.

perliedman commented 5 years ago

@tomchadwin is correct, this is because of buffering. The points themselves don't need buffers, but as soon as you use a marker larger than a pixel, that marker can be cut at the tile border, since each tile is rendered clipped to its extent. This means that icons that extend across a tile border need to be present in both tiles to avoid being cut like in your screenshot.

tomchadwin commented 5 years ago

Seems unlikely to exceed the quoted default 80px, though. Or perhaps the units are not pixels?

tobwen commented 5 years ago

Oh, so those tiles are rendered individually? I thought, vector tiles would work equal to WFS: give the coordinates and let the mapping library do the rendering on the geometry.

Since my dataset is in WGS84, "unit" is fun again... how big is a marker of 16 px on zoom X? Let's figure it out. You can close this one, I'll add results later for other users having the same problem.

tomchadwin commented 5 years ago

The mapping library does render the geometry, but it does it per-tile. Your issue arises because of the size of the marker. All your points are rendered - ie all the points themselves are present on their tiles - but the markers are being clipped because the marker extends onto a tile on which the point geometry is not present. On those occasions, you need the point to fall within the buffer of the other tile(s) to that, although the geometry does not lie on the tile(s) itself, the marker is rendered on it/them. When you set your buffers big enough, you get the full marker symbols, but in truth, the marker symbols themselves are divided along the tile boundaries. Half of the symbol comes from the feature rendered on its tile, and half from the feature rendered in the buffer of the neighbouring tile.

It's a bit laborious to explain verbally, but I can't be bothered to draw a representation of this. Perhaps one exists out there somewhere?

tobwen commented 5 years ago

Hey, really no need to - I've understood the concept. I'm around with rastertiles for 9 years now and buffers have always been fun for labels :-)

I just thought, it's different for points. Like: here's a coordinate, just render a marker in there :) Okay, I'll play around and report soon.

tomchadwin commented 5 years ago

In which case, apologies for unintentional condescension!

tobwen commented 5 years ago

In which case, apologies for unintentional condescension!

Naaaaaaaaaaaaaaaah :-)

mngyng commented 5 years ago

See #149. Sounds like the same issue. The buffer option didn't work for me, so I changed the query to add a buffer for points on the tile edge.