diff --git a/tile.cc b/tile.cc index 7b1931b..5c5adf9 100644 --- a/tile.cc +++ b/tile.cc @@ -197,6 +197,39 @@ int remove_noop(struct draw *geom, int n) { return out; } +int shrink_lines(struct draw *geom, int len, int z, int basezoom) { + double scale = 1.0 / exp(log(sqrt(2.5)) * (basezoom - z)); + struct draw tmp[3 * len]; + int out = 0; + int i; + + for (i = 0; i < len; i++) { + if (i > 0 && (geom[i - 1].op == VT_MOVETO || geom[i - 1].op == VT_LINETO) && geom[i].op == VT_LINETO) { + long long cx = (geom[i].x + geom[i - 1].x) / 2; + long long cy = (geom[i].y + geom[i - 1].y) / 2; + + tmp[out + 0].op = VT_MOVETO; + tmp[out + 0].x = cx + (geom[i - 1].x - cx) * scale; + tmp[out + 0].y = cy + (geom[i - 1].y - cy) * scale; + + tmp[out + 1].op = VT_LINETO; + tmp[out + 1].x = cx + (geom[i].x - cx) * scale; + tmp[out + 1].y = cy + (geom[i].y - cy) * scale; + + tmp[out + 2].op = VT_MOVETO; + tmp[out + 2].x = geom[i].x; + tmp[out + 2].y = geom[i].y; + + out += 3; + } else { + tmp[out++] = geom[i]; + } + } + + memcpy(geom, tmp, out * sizeof(struct draw)); + return out; +} + void to_tile_scale(struct draw *geom, int n, int z, int detail) { int i; @@ -261,12 +294,16 @@ long long write_tile(struct index *start, struct index *end, char *metabase, uns } int len = decode_feature(&meta, NULL, z, tx, ty, detail); - struct draw geom[len]; + struct draw geom[3 * len]; meta = metabase + i->fpos; deserialize_int(&meta, &t); decode_feature(&meta, geom, z, tx, ty, detail); + if (t == VT_LINE && z != basezoom) { + len = shrink_lines(geom, len, z, basezoom); + } + to_tile_scale(geom, len, z, detail); if (t == VT_LINE || t == VT_POLYGON) {