mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-02 16:35:40 +02:00
Fix placement of label anchors in the tile buffer
The anchor point that `--convert-polygons-to-label-points` computes was stored in `serial_feature` as a single `unsigned long long`, the Morton index of two *unsigned 32-bit* coordinates. That representation cost two things: * `SHIFT_LEFT` can legitimately put an anchor outside the [0, 2^32) plane -- that is exactly what happens for a feature reaching into a tile's buffer -- but `encode_index` only takes 32-bit unsigned values, so the anchor was masked with `& ((1LL << 32) - 1)` on the way in. An anchor just west or north of the plane wrapped around to the far edge of the world rather than staying where it was. This is most visible in the buffer of the z0 tile, whose own bounds are the whole plane, so every buffer anchor is out of range. * Zero was overloaded as "no anchor," but zero is also the index of the legitimate world coordinate (0, 0). Store the anchor as a pair of signed `long long` coordinates with an explicit `has_label_point` flag instead. The serialized form grows from one varint to two, both zigzag-encoded so negative coordinates round-trip; this is the internal geometry temp file, not tile output, so nothing external depends on the layout. `write_tile` now checks the flag rather than relying on the sentinel, and drops the feature when there is no anchor instead of quietly tiling one at (0, 0). `checkerboard_anchors` gains the tile buffer as a parameter and short-circuits: if the real anchor lies within the tile plus its buffer, emit it directly rather than searching the repeating checkerboard for a substitute. Computing `ty2` is what makes that test possible -- it had been commented out because only `tx2` was needed for the label spacing. The one place this changes test output is tests/ne_110m_admin_0_countries/out/-z2_--convert-polygons-to-label-points.json, where Antarctica's anchors move. That fixture is regenerated here. CHANGELOG and version follow this repo's conventions: an entry under a new 2.81.1 heading, patch rather than minor since this only fixes behavior. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NcSXLjtokxioaBCCwGTEv1
This commit is contained in:
+17
-7
@@ -944,23 +944,33 @@ drawvec polygon_to_anchor(const drawvec &geom) {
|
||||
return drawvec();
|
||||
}
|
||||
|
||||
drawvec checkerboard_anchors(drawvec const &geom, int tx, int ty, int z, unsigned long long label_point) {
|
||||
drawvec checkerboard_anchors(drawvec const &geom, int tx, int ty, int z, long long wx, long long wy, int buffer) {
|
||||
drawvec out;
|
||||
|
||||
// anchor point in world coordinates
|
||||
unsigned wx, wy;
|
||||
decode_index(label_point, &wx, &wy);
|
||||
|
||||
// upper left of tile in world coordinates
|
||||
long long tx1 = 0, ty1 = 0;
|
||||
// lower right of tile in world coordinates;
|
||||
long long tx2 = 1LL << 32; // , ty2 = 1LL << 32;
|
||||
long long tx2 = 1LL << 32, ty2 = 1LL << 32;
|
||||
if (z != 0) {
|
||||
tx1 = (long long) tx << (32 - z);
|
||||
ty1 = (long long) ty << (32 - z);
|
||||
|
||||
tx2 = (long long) (tx + 1) << (32 - z);
|
||||
// ty2 = (long long) (ty + 1) << (32 - z);
|
||||
ty2 = (long long) (ty + 1) << (32 - z);
|
||||
}
|
||||
|
||||
long long tx1_buffer = tx1 - (1LL << (32 - z)) * buffer / 256;
|
||||
long long ty1_buffer = ty1 - (1LL << (32 - z)) * buffer / 256;
|
||||
long long tx2_buffer = tx2 + (1LL << (32 - z)) * buffer / 256;
|
||||
long long ty2_buffer = ty2 + (1LL << (32 - z)) * buffer / 256;
|
||||
|
||||
// if the central label point is within this tile, always prefer that.
|
||||
// none of the label repetition code below matters much any more,
|
||||
// now that we truncate the tile pyramid once we have all the features
|
||||
if (wx >= tx1_buffer && wx <= tx2_buffer && wy >= ty1_buffer && wy <= ty2_buffer) {
|
||||
// offset to tile origin
|
||||
out.push_back(draw(VT_MOVETO, wx - tx1, wy - ty1));
|
||||
return out;
|
||||
}
|
||||
|
||||
// upper left of feature in world coordinates
|
||||
|
||||
Reference in New Issue
Block a user