From 5b03b18f31ab00a72798dbd1609d3dff78530947 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Fri, 21 Oct 2022 13:59:36 -0700 Subject: [PATCH] Generate label points after simplification, not before. (#27) * Generate labels points after simplification, not before. Previously there were some cases where dropping the smallest polygons would never reduce the number of labels. * Also wait until after polygon cleaning to make labels * Remove the extra newlines after the TILES ONLY COMPLETE message --- CHANGELOG.md | 4 ++++ geometry.cpp | 11 +++++++++++ geometry.hpp | 1 + main.cpp | 2 +- tile.cpp | 37 ++++++++++++++++++++++--------------- version.hpp | 2 +- 6 files changed, 40 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f215dee..fbc0cf8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.9.1 + +* Do label generation after simplification, not before. + ## 2.9.0 * Add an option to generate label points in place of polygons diff --git a/geometry.cpp b/geometry.cpp index db4431c..74319af 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -92,6 +92,17 @@ void to_tile_scale(drawvec &geom, int z, int detail) { } } +drawvec from_tile_scale(drawvec const &geom, int z, int detail) { + drawvec out; + for (size_t i = 0; i < geom.size(); i++) { + draw d = geom[i]; + d.x <<= (32 - detail - z); + d.y <<= (32 - detail - z); + out.push_back(d); + } + return out; +} + drawvec remove_noop(drawvec geom, int type, int shift) { // first pass: remove empty linetos diff --git a/geometry.hpp b/geometry.hpp index 7c5ad9a..a124887 100644 --- a/geometry.hpp +++ b/geometry.hpp @@ -60,6 +60,7 @@ struct serial_feature; drawvec decode_geometry(FILE *meta, std::atomic *geompos, int z, unsigned tx, unsigned ty, long long *bbox, unsigned initial_x, unsigned initial_y); void to_tile_scale(drawvec &geom, int z, int detail); +drawvec from_tile_scale(drawvec const &geom, int z, int detail); drawvec remove_noop(drawvec geom, int type, int shift); drawvec clip_point(drawvec &geom, int z, long long buffer); drawvec clean_or_clip_poly(drawvec &geom, int z, int buffer, bool clip); diff --git a/main.cpp b/main.cpp index dfc0b5f..7222e62 100644 --- a/main.cpp +++ b/main.cpp @@ -2427,7 +2427,7 @@ int read_input(std::vector &sources, char *fname, int maxzoom, int minzo if (maxzoom != written) { if (written > minzoom) { - fprintf(stderr, "\n\n\n*** NOTE TILES ONLY COMPLETE THROUGH ZOOM %d ***\n\n\n", written); + fprintf(stderr, "\n\n\n*** NOTE TILES ONLY COMPLETE THROUGH ZOOM %d ***\n", written); maxzoom = written; ret = EXIT_INCOMPLETE; } else { diff --git a/tile.cpp b/tile.cpp index dbdd144..e53c016 100644 --- a/tile.cpp +++ b/tile.cpp @@ -447,9 +447,12 @@ struct partial { long long layer = 0; long long original_seq = 0; unsigned long long index = 0; + unsigned long long label_point = 0; int segment = 0; bool reduced = 0; int z = 0; + int tx = 0; + int ty = 0; int line_detail = 0; int extra_detail = 0; int maxzoom = 0; @@ -575,31 +578,37 @@ void *partial_feature_worker(void *v) { to_tile_scale(geom, z, out_detail); - std::vector geoms; - geoms.push_back(geom); - if (t == VT_POLYGON) { // Scaling may have made the polygon degenerate. // Give Clipper a chance to try to fix it. - for (size_t g = 0; g < geoms.size(); g++) { - drawvec before = geoms[g]; - geoms[g] = clean_or_clip_poly(geoms[g], 0, 0, false); + { + drawvec before = geom; + geom = clean_or_clip_poly(geom, 0, 0, false); if (additional[A_DEBUG_POLYGON]) { - check_polygon(geoms[g]); + check_polygon(geom); } - if (geoms[g].size() < 3) { + if (geom.size() < 3) { if (area > 0) { // area is in world coordinates, calculated before scaling down - geoms[g] = revive_polygon(before, area / geoms.size(), z, out_detail); + geom = revive_polygon(before, area, z, out_detail); } else { - geoms[g].clear(); + geom.clear(); } } } } + if (t == VT_POLYGON && additional[A_GENERATE_POLYGON_LABEL_POINTS]) { + t = (*partials)[i].t = VT_POINT; + geom = spiral_anchors(from_tile_scale(geom, z, out_detail), (*partials)[i].tx, (*partials)[i].ty, z, (*partials)[i].label_point); + to_tile_scale(geom, z, out_detail); + } + (*partials)[i].index = i; + + std::vector geoms; // artifact of former polygon-splitting to reduce geometric complexity + geoms.push_back(geom); (*partials)[i].geoms = geoms; } @@ -2087,11 +2096,6 @@ long long write_tile(FILE *geoms, std::atomic *geompos_in, char *meta } } - if (sf.t == VT_POLYGON && additional[A_GENERATE_POLYGON_LABEL_POINTS]) { - sf.t = VT_POINT; - sf.geometry = spiral_anchors(sf.geometry, tx, ty, z, sf.label_point); - } - if (sf.geometry.size() > 0) { if (partials.size() > max_tile_size) { // Even being maximally conservative, each feature is still going to be @@ -2114,6 +2118,8 @@ long long write_tile(FILE *geoms, std::atomic *geompos_in, char *meta p.original_seq = sf.seq; p.reduced = reduced; p.z = z; + p.tx = tx; + p.ty = ty; p.line_detail = line_detail; p.extra_detail = line_detail; p.maxzoom = maxzoom; @@ -2126,6 +2132,7 @@ long long write_tile(FILE *geoms, std::atomic *geompos_in, char *meta p.id = sf.id; p.has_id = sf.has_id; p.index = sf.index; + p.label_point = sf.label_point; p.renamed = -1; p.extent = sf.extent; p.clustered = 0; diff --git a/version.hpp b/version.hpp index a5e4005..3ae80ed 100644 --- a/version.hpp +++ b/version.hpp @@ -1,6 +1,6 @@ #ifndef VERSION_HPP #define VERSION_HPP -#define VERSION "v2.9.0" +#define VERSION "v2.9.1" #endif