Shift the coordinate system so the tile boundary marking works right.

(Was missing transitions before because division rounds toward zero)
This commit is contained in:
Eric Fischer 2018-04-25 16:36:23 +02:00
parent 6b70e2aebd
commit d45c960c1f
3 changed files with 29 additions and 9 deletions

View File

@ -790,14 +790,24 @@ bool point_within_tile(long long x, long long y, int z) {
return x >= 0 && y >= 0 && x < area && y < area;
}
drawvec mark_tile_edges(drawvec geom, long long width, long long *pointid) {
drawvec mark_tile_edges(drawvec geom, long long width, long long *pointid, int z, unsigned tx, unsigned ty) {
drawvec out;
// shift to word coordinates so tile edge division will work
// even though it rounds toward 0 instead of rounding down
unsigned sx = 0, sy = 0;
if (z != 0) {
sx = tx << (32 - z);
sy = ty << (32 - z);
}
for (size_t i = 0; i < geom.size(); i++) {
geom[i].x += sx;
geom[i].y += sy;
}
for (size_t i = 0; i < geom.size(); i++) {
if (geom[i].op == VT_LINETO) {
if (geom[i - 1].x / width != geom[i].x / width) {
long long min, max;
if (geom[i - 1].x < geom[i].x) {
for (long long xx = geom[i - 1].x / width * width + width; xx <= geom[i].x / width * width; xx += width) {
long long yy = (xx - geom[i - 1].x) * (geom[i].y - geom[i - 1].y) / (geom[i].x - geom[i - 1].x) + geom[i - 1].y;
@ -816,12 +826,11 @@ drawvec mark_tile_edges(drawvec geom, long long width, long long *pointid) {
}
geom = out;
out.clear();
for (size_t i = 0; i < geom.size(); i++) {
if (geom[i].op == VT_LINETO) {
if (geom[i - 1].y / width != geom[i].y / width) {
long long min, may;
if (geom[i - 1].y < geom[i].y) {
for (long long yy = geom[i - 1].y / width * width + width; yy <= geom[i].y / width * width; yy += width) {
long long xx = (yy - geom[i - 1].y) * (geom[i].x - geom[i - 1].x) / (geom[i].y - geom[i - 1].y) + geom[i - 1].x;
@ -839,16 +848,21 @@ drawvec mark_tile_edges(drawvec geom, long long width, long long *pointid) {
out.push_back(geom[i]);
}
for (size_t i = 0; i < out.size(); i++) {
out[i].x -= sx;
out[i].y -= sy;
}
return out;
}
drawvec clip_lines(drawvec geom, int z, long long buffer, long long *pointid) {
drawvec clip_lines(drawvec geom, int z, unsigned x, unsigned y, long long buffer, long long *pointid) {
drawvec out;
long long min = 0;
long long area = 1LL << (32 - z);
geom = mark_tile_edges(geom, area, pointid);
geom = mark_tile_edges(geom, area, pointid, z, x, y);
min -= buffer * area / 256;
area += buffer * area / 256;

View File

@ -74,7 +74,7 @@ drawvec clean_or_clip_poly(drawvec &geom, int z, int buffer, bool clip);
drawvec simple_clip_poly(drawvec &geom, int z, int buffer);
drawvec close_poly(drawvec &geom);
drawvec reduce_tiny_poly(drawvec &geom, int z, int detail, bool *reduced, double *accum_area);
drawvec clip_lines(drawvec geom, int z, long long buffer, long long *pointid);
drawvec clip_lines(drawvec geom, int z, unsigned x, unsigned y, long long buffer, long long *pointid);
drawvec stairstep(drawvec &geom, int z, int detail);
bool point_within_tile(long long x, long long y, int z);
int quick_check(long long *bbox, int z, long long buffer);

View File

@ -401,6 +401,8 @@ struct partial {
int segment = 0;
bool reduced = 0;
int z = 0;
unsigned x;
unsigned y;
int line_detail = 0;
int maxzoom = 0;
double spacing = 0;
@ -480,6 +482,8 @@ void *partial_feature_worker(void *v) {
(*partials)[i].geoms.clear(); // avoid keeping two copies in memory
signed char t = (*partials)[i].t;
int z = (*partials)[i].z;
unsigned x = (*partials)[i].x;
unsigned y = (*partials)[i].y;
int line_detail = (*partials)[i].line_detail;
int maxzoom = (*partials)[i].maxzoom;
@ -531,7 +535,7 @@ void *partial_feature_worker(void *v) {
if (t == VT_LINE) {
for (size_t g = 0; g < geoms.size(); g++) {
from_tile_scale(geoms[g], z, line_detail);
geoms[g] = clip_lines(geoms[g], z, (*partials)[i].buffer, (*partials)[i].pointid);
geoms[g] = clip_lines(geoms[g], z, x, y, (*partials)[i].buffer, (*partials)[i].pointid);
to_tile_scale(geoms[g], z, line_detail);
}
}
@ -1988,6 +1992,8 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
p.original_seq = sf.seq;
p.reduced = reduced;
p.z = z;
p.x = tx;
p.y = ty;
p.line_detail = line_detail;
p.maxzoom = maxzoom;
p.keys = sf.keys;