Skip to content

Commit 42ee195

Browse files
committed
Add an option to keep intersection nodes from being simplified away
1 parent 9dc92a4 commit 42ee195

File tree

8 files changed

+835
-5
lines changed

8 files changed

+835
-5
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@ the same layer, enclose them in an `all` expression so they will all be evaluate
470470
the line or polygon within one tile unit of its proper location. You can probably go up to about 10 without too much visible difference.
471471
* `-ps` or `--no-line-simplification`: Don't simplify lines and polygons
472472
* `-pS` or `--simplify-only-low-zooms`: Don't simplify lines and polygons at maxzoom (but do simplify at lower zooms)
473+
* `-pn` or `--no-simplification-of-shared-nodes`: Don't simplify away nodes that appear in more than one feature or are used multiple times within the same feature, so that the intersection node will not be lost from intersecting roads. (This will not be effective if you also use `--coalesce` or `--detect-shared-borders`.)
473474
* `-pt` or `--no-tiny-polygon-reduction`: Don't combine the area of very small polygons into small squares that represent their combined area.
474475

475476
### Attempts to improve shared polygon boundaries

geometry.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -802,7 +802,7 @@ drawvec impose_tile_boundaries(drawvec &geom, long long extent) {
802802
return out;
803803
}
804804

805-
drawvec simplify_lines(drawvec &geom, int z, int detail, bool mark_tile_bounds, double simplification, size_t retain) {
805+
drawvec simplify_lines(drawvec &geom, int z, int detail, bool mark_tile_bounds, double simplification, size_t retain, drawvec const &shared_nodes) {
806806
int res = 1 << (32 - detail - z);
807807
long long area = 1LL << (32 - z);
808808

@@ -814,6 +814,13 @@ drawvec simplify_lines(drawvec &geom, int z, int detail, bool mark_tile_bounds,
814814
} else {
815815
geom[i].necessary = 1;
816816
}
817+
818+
if (prevent[P_SIMPLIFY_SHARED_NODES]) {
819+
auto pt = std::lower_bound(shared_nodes.begin(), shared_nodes.end(), geom[i]);
820+
if (pt != shared_nodes.end() && *pt == geom[i]) {
821+
geom[i].necessary = true;
822+
}
823+
}
817824
}
818825

819826
if (mark_tile_bounds) {

geometry.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ drawvec clip_lines(drawvec &geom, int z, long long buffer);
6868
drawvec stairstep(drawvec &geom, int z, int detail);
6969
bool point_within_tile(long long x, long long y, int z);
7070
int quick_check(long long *bbox, int z, long long buffer);
71-
drawvec simplify_lines(drawvec &geom, int z, int detail, bool mark_tile_bounds, double simplification, size_t retain);
71+
drawvec simplify_lines(drawvec &geom, int z, int detail, bool mark_tile_bounds, double simplification, size_t retain, drawvec const &shared_nodes);
7272
drawvec reorder_lines(drawvec &geom);
7373
drawvec fix_polygon(drawvec &geom);
7474
std::vector<drawvec> chop_polygon(std::vector<drawvec> &geoms);

main.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -2569,6 +2569,7 @@ int main(int argc, char **argv) {
25692569
{"no-line-simplification", no_argument, &prevent[P_SIMPLIFY], 1},
25702570
{"simplify-only-low-zooms", no_argument, &prevent[P_SIMPLIFY_LOW], 1},
25712571
{"no-tiny-polygon-reduction", no_argument, &prevent[P_TINY_POLYGON_REDUCTION], 1},
2572+
{"no-simplification-of-shared-nodes", no_argument, &prevent[P_SIMPLIFY_SHARED_NODES], 1},
25722573

25732574
{"Attempts to improve shared polygon boundaries", 0, 0, 0},
25742575
{"detect-shared-borders", no_argument, &additional[A_DETECT_SHARED_BORDERS], 1},

options.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
#define P_SIMPLIFY ((int) 's')
3030
#define P_SIMPLIFY_LOW ((int) 'S')
31+
#define P_SIMPLIFY_SHARED_NODES ((int) 'n')
3132
#define P_FEATURE_LIMIT ((int) 'f')
3233
#define P_KILOBYTE_LIMIT ((int) 'k')
3334
#define P_DYNAMIC_DROP ((int) 'd')

tests/tl_2018_51685_roads/in.json

+263
Large diffs are not rendered by default.

tests/tl_2018_51685_roads/out/-Z11_-z11_--no-simplification-of-shared-nodes.json

+529
Large diffs are not rendered by default.

tile.cpp

+31-3
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,7 @@ struct partial_arg {
381381
std::vector<struct partial> *partials = NULL;
382382
int task = 0;
383383
int tasks = 0;
384+
drawvec *shared_nodes;
384385
};
385386

386387
drawvec revive_polygon(drawvec &geom, double area, int z, int detail) {
@@ -464,7 +465,7 @@ void *partial_feature_worker(void *v) {
464465
}
465466

466467
if (!already_marked) {
467-
drawvec ngeom = simplify_lines(geom, z, line_detail, !(prevent[P_CLIPPING] || prevent[P_DUPLICATION]), (*partials)[i].simplification, t == VT_POLYGON ? 4 : 0);
468+
drawvec ngeom = simplify_lines(geom, z, line_detail, !(prevent[P_CLIPPING] || prevent[P_DUPLICATION]), (*partials)[i].simplification, t == VT_POLYGON ? 4 : 0, *(a->shared_nodes));
468469

469470
if (t != VT_POLYGON || ngeom.size() >= 3) {
470471
geom = ngeom;
@@ -898,7 +899,7 @@ bool find_common_edges(std::vector<partial> &partials, int z, int line_detail, d
898899
}
899900
}
900901
if (!(prevent[P_SIMPLIFY] || (z == maxzoom && prevent[P_SIMPLIFY_LOW]) || (z < maxzoom && additional[A_GRID_LOW_ZOOMS]))) {
901-
simplified_arcs[ai->second] = simplify_lines(dv, z, line_detail, !(prevent[P_CLIPPING] || prevent[P_DUPLICATION]), simplification, 4);
902+
simplified_arcs[ai->second] = simplify_lines(dv, z, line_detail, !(prevent[P_CLIPPING] || prevent[P_DUPLICATION]), simplification, 4, drawvec());
902903
} else {
903904
simplified_arcs[ai->second] = dv;
904905
}
@@ -1763,6 +1764,7 @@ long long write_tile(FILE *geoms, std::atomic<long long> *geompos_in, char *meta
17631764
std::vector<long long> extents;
17641765
std::map<std::string, accum_state> attribute_accum_state;
17651766
double coalesced_area = 0;
1767+
drawvec shared_nodes;
17661768

17671769
int within[child_shards];
17681770
std::atomic<long long> geompos[child_shards];
@@ -1962,6 +1964,12 @@ long long write_tile(FILE *geoms, std::atomic<long long> *geompos_in, char *meta
19621964
}
19631965

19641966
if (sf.geometry.size() > 0) {
1967+
if (prevent[P_SIMPLIFY_SHARED_NODES]) {
1968+
for (auto &g : sf.geometry) {
1969+
shared_nodes.push_back(g);
1970+
}
1971+
}
1972+
19651973
partial p;
19661974
p.geoms.push_back(sf.geometry);
19671975
p.layer = sf.layer;
@@ -1991,6 +1999,25 @@ long long write_tile(FILE *geoms, std::atomic<long long> *geompos_in, char *meta
19911999
coalesced_area = 0;
19922000
}
19932001

2002+
{
2003+
drawvec just_shared_nodes;
2004+
std::sort(shared_nodes.begin(), shared_nodes.end());
2005+
2006+
for (size_t i = 0; i + 1 < shared_nodes.size(); i++) {
2007+
if (shared_nodes[i] == shared_nodes[i + 1]) {
2008+
just_shared_nodes.push_back(shared_nodes[i]);
2009+
2010+
draw d = shared_nodes[i];
2011+
i++;
2012+
while (i + 1 < shared_nodes.size() && shared_nodes[i + 1] == d) {
2013+
i++;
2014+
}
2015+
}
2016+
}
2017+
2018+
shared_nodes = just_shared_nodes;
2019+
}
2020+
19942021
for (size_t i = 0; i < partials.size(); i++) {
19952022
partial &p = partials[i];
19962023

@@ -2073,6 +2100,7 @@ long long write_tile(FILE *geoms, std::atomic<long long> *geompos_in, char *meta
20732100
args[i].task = i;
20742101
args[i].tasks = tasks;
20752102
args[i].partials = &partials;
2103+
args[i].shared_nodes = &shared_nodes;
20762104

20772105
if (tasks > 1) {
20782106
if (pthread_create(&pthreads[i], NULL, partial_feature_worker, &args[i]) != 0) {
@@ -2186,7 +2214,7 @@ long long write_tile(FILE *geoms, std::atomic<long long> *geompos_in, char *meta
21862214
if (layer_features[x].coalesced && layer_features[x].type == VT_LINE) {
21872215
layer_features[x].geom = remove_noop(layer_features[x].geom, layer_features[x].type, 0);
21882216
layer_features[x].geom = simplify_lines(layer_features[x].geom, 32, 0,
2189-
!(prevent[P_CLIPPING] || prevent[P_DUPLICATION]), simplification, layer_features[x].type == VT_POLYGON ? 4 : 0);
2217+
!(prevent[P_CLIPPING] || prevent[P_DUPLICATION]), simplification, layer_features[x].type == VT_POLYGON ? 4 : 0, shared_nodes);
21902218
}
21912219

21922220
if (layer_features[x].type == VT_POLYGON) {

0 commit comments

Comments
 (0)