mirror of
https://github.com/mapbox/tippecanoe.git
synced 2025-04-26 13:59:51 +00:00
Interject new points into LineStrings where they cross tile boundaries
This commit is contained in:
parent
086832d5e3
commit
d8a75a496c
52
geometry.cpp
52
geometry.cpp
@ -1289,3 +1289,55 @@ void checkgeom(drawvec const &dv, std::string s) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
drawvec tag_line_transitions(drawvec dv, int nextzoom, long long *pointid, long long tx1, long long ty1, long long tx2, long long ty2) {
|
||||
// Crossings of vertical lines
|
||||
for (long long tx = tx1; tx < tx2; tx++) {
|
||||
long long x = (1LL << (32 - nextzoom)) * (tx + 1);
|
||||
drawvec out;
|
||||
|
||||
for (size_t i = 0; i < dv.size(); i++) {
|
||||
if (i > 0 && dv[i].op == VT_LINETO) {
|
||||
if ((dv[i - 1].x < x && dv[i].x > x) ||
|
||||
(dv[i - 1].x > x && dv[i].x < x)) {
|
||||
long long ny = dv[i - 1].y + (dv[i].y - dv[i - 1].y) * (x - dv[i - 1].x) / (dv[i].x - dv[i - 1].x);
|
||||
long long nx = x;
|
||||
|
||||
draw d(VT_LINETO, nx, ny);
|
||||
d.id = ++*pointid;
|
||||
// out.push_back(d);
|
||||
}
|
||||
}
|
||||
|
||||
out.push_back(dv[i]);
|
||||
}
|
||||
|
||||
dv = out;
|
||||
}
|
||||
|
||||
// Crossings of horizontal lines
|
||||
for (long long ty = ty1; ty < ty2; ty++) {
|
||||
long long y = (1LL << (32 - nextzoom)) * (ty + 1);
|
||||
drawvec out;
|
||||
|
||||
for (size_t i = 0; i < dv.size(); i++) {
|
||||
if (i > 0 && dv[i].op == VT_LINETO) {
|
||||
if ((dv[i - 1].y < y && dv[i].y > y) ||
|
||||
(dv[i - 1].y > y && dv[i].y < y)) {
|
||||
long long nx = dv[i - 1].x + (dv[i].x - dv[i - 1].x) * (y - dv[i - 1].y) / (dv[i].y - dv[i - 1].y);
|
||||
long long ny = y;
|
||||
|
||||
draw d(VT_LINETO, nx, ny);
|
||||
d.id = ++*pointid;
|
||||
out.push_back(d);
|
||||
}
|
||||
}
|
||||
|
||||
out.push_back(dv[i]);
|
||||
}
|
||||
|
||||
dv = out;
|
||||
}
|
||||
|
||||
return dv;
|
||||
}
|
||||
|
@ -87,5 +87,7 @@ double get_mp_area(drawvec &geom);
|
||||
|
||||
void checkgeom(drawvec const &dv, std::string s);
|
||||
|
||||
drawvec tag_line_transitions(drawvec dv, int nextzoom, long long *pointid, long long tx1, long long ty1, long long tx2, long long ty2);
|
||||
|
||||
#endif
|
||||
|
||||
|
22
tile.cpp
22
tile.cpp
@ -252,7 +252,7 @@ static int metacmp(int m1, const std::vector<long long> &keys1, const std::vecto
|
||||
}
|
||||
}
|
||||
|
||||
void rewrite(drawvec &geom, int z, int nextzoom, int maxzoom, long long *bbox, unsigned tx, unsigned ty, int buffer, int *within, long long *geompos, FILE **geomfile, const char *fname, signed char t, int layer, long long metastart, signed char feature_minzoom, int child_shards, int max_zoom_increment, long long seq, int tippecanoe_minzoom, int tippecanoe_maxzoom, int segment, unsigned *initial_x, unsigned *initial_y, int m, std::vector<long long> &metakeys, std::vector<long long> &metavals, bool has_id, unsigned long long id, unsigned long long index, long long extent, long long clipid, long long pointid, size_t tiling_seg, std::vector<long long> *clipids) {
|
||||
void rewrite(drawvec geom, int z, int nextzoom, int maxzoom, long long *bbox, unsigned tx, unsigned ty, int buffer, int *within, long long *geompos, FILE **geomfile, const char *fname, signed char t, int layer, long long metastart, signed char feature_minzoom, int child_shards, int max_zoom_increment, long long seq, int tippecanoe_minzoom, int tippecanoe_maxzoom, int segment, unsigned *initial_x, unsigned *initial_y, int m, std::vector<long long> &metakeys, std::vector<long long> &metavals, bool has_id, unsigned long long id, unsigned long long index, long long extent, long long clipid, long long pointid, size_t tiling_seg, std::vector<long long> *clipids) {
|
||||
if (geom.size() > 0 && (nextzoom <= maxzoom || additional[A_EXTEND_ZOOMS])) {
|
||||
int xo, yo;
|
||||
int span = 1 << (nextzoom - z);
|
||||
@ -280,6 +280,7 @@ void rewrite(drawvec &geom, int z, int nextzoom, int maxzoom, long long *bbox, u
|
||||
bbox2[k] = 256 * (span - 1);
|
||||
}
|
||||
|
||||
// Shift bounding box from pixels to tiles
|
||||
bbox2[k] /= 256;
|
||||
}
|
||||
|
||||
@ -290,9 +291,9 @@ void rewrite(drawvec &geom, int z, int nextzoom, int maxzoom, long long *bbox, u
|
||||
sy = ty << (32 - z);
|
||||
}
|
||||
|
||||
drawvec geom2;
|
||||
for (size_t i = 0; i < geom.size(); i++) {
|
||||
geom2.push_back(draw(geom[i].op, (geom[i].x + sx) >> geometry_scale, (geom[i].y + sy) >> geometry_scale, geom[i].id));
|
||||
geom[i].x += sx;
|
||||
geom[i].y += sy;
|
||||
}
|
||||
|
||||
if (additional[A_JOIN_FEATURES_ACROSS_TILES]) {
|
||||
@ -305,9 +306,22 @@ void rewrite(drawvec &geom, int z, int nextzoom, int maxzoom, long long *bbox, u
|
||||
if (clipid == 0) {
|
||||
clipid = (*clipids)[tiling_seg]++ * CPUS + tiling_seg + 1;
|
||||
}
|
||||
|
||||
// If this is a LineString, tag the transition points
|
||||
// between tiles with IDs now.
|
||||
|
||||
if (t == VT_LINE) {
|
||||
geom = tag_line_transitions(geom, nextzoom, &pointid, tx * span + bbox2[0], ty * span + bbox2[1], tx * span + bbox2[2], ty * span + bbox2[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scale down to maxzoom resolution
|
||||
for (size_t i = 0; i < geom.size(); i++) {
|
||||
geom[i].x >>= geometry_scale;
|
||||
geom[i].y >>= geometry_scale;
|
||||
}
|
||||
|
||||
for (xo = bbox2[0]; xo <= bbox2[2]; xo++) {
|
||||
for (yo = bbox2[1]; yo <= bbox2[3]; yo++) {
|
||||
unsigned jx = tx * span + xo;
|
||||
@ -353,7 +367,7 @@ void rewrite(drawvec &geom, int z, int nextzoom, int maxzoom, long long *bbox, u
|
||||
sf.has_tippecanoe_maxzoom = tippecanoe_maxzoom != -1;
|
||||
sf.tippecanoe_maxzoom = tippecanoe_maxzoom;
|
||||
sf.metapos = metastart;
|
||||
sf.geometry = geom2;
|
||||
sf.geometry = geom;
|
||||
sf.index = index;
|
||||
sf.extent = extent;
|
||||
sf.m = m;
|
||||
|
Loading…
x
Reference in New Issue
Block a user