Copy antimeridian-crossing geometries to the other side too

This commit is contained in:
Erica Fischer
2024-09-09 21:49:07 -07:00
parent 8361df4ceb
commit cd466e63a4
2 changed files with 38 additions and 9 deletions
+37 -8
View File
@@ -290,17 +290,45 @@ std::vector<mvt_layer> parse_layers(FILE *fp, int z, unsigned x, unsigned y, int
// so move it to the other side.
if (fix_longitudes) {
const long long quarter_world = 1LL << 30;
const long long world = 1LL << 32;
bool copy_to_left = false;
bool copy_to_right = false;
for (size_t i = 0; i < dv.size(); i++) {
// is this vertex on a different side of the world
// than the first vertex? then shift this one to match
if (i > 0) {
if ((dv[0].x < (1LL << 30)) &&
(dv[i].x > 3 * (1LL << 30))) {
dv[i].x -= 1LL << 32;
if ((dv[0].x < quarter_world) && (dv[i].x > 3 * quarter_world)) {
dv[i].x -= world;
}
if ((dv[0].x > 3 * (1LL << 30)) &&
(dv[i].x < (1LL << 30))) {
dv[i].x += 1LL << 32;
if ((dv[0].x > 3 * quarter_world) && (dv[i].x < quarter_world)) {
dv[i].x += world;
}
}
// does it stick off the edge of the world?
// then we need another copy on the other side of the world
if (dv[i].x < 0) {
copy_to_right = true;
}
if (dv[i].x > world) {
copy_to_left = true;
}
}
if (copy_to_left) {
size_t n = dv.size();
for (size_t i = 0; i < n; i++) {
dv.emplace_back(dv[i].op, dv[i].x - world, (long long) dv[i].y);
}
}
if (copy_to_right) {
size_t n = dv.size();
for (size_t i = 0; i < n; i++) {
dv.emplace_back(dv[i].op, dv[i].x + world, (long long) dv[i].y);
}
}
}
@@ -319,8 +347,9 @@ std::vector<mvt_layer> parse_layers(FILE *fp, int z, unsigned x, unsigned y, int
}
if (mb_geometry[t] == VT_POLYGON) {
// we can try scaling up because these are tile coordinates
dv = clean_or_clip_poly(dv, 0, 0, false, true);
// don't try scaling up because we may have coordinates
// on the other side of the world
dv = clean_or_clip_poly(dv, z, 256, true, false);
if (dv.size() < 3) {
dv.clear();
}
File diff suppressed because one or more lines are too long