Interject new points into LineStrings where they cross tile boundaries

This commit is contained in:
Eric Fischer 2018-03-12 16:36:40 -07:00
parent 086832d5e3
commit d8a75a496c
3 changed files with 72 additions and 4 deletions

@ -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

@ -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;