Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Even-odd wagyu after scaling to counterbalance ring reversals #178

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions clip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ static void decode_clipped(mapbox::geometry::multi_polygon<long long> &t, drawve
}
}

drawvec clean_or_clip_poly(drawvec &geom, int z, int buffer, bool clip, bool try_scaling) {
drawvec clean_or_clip_poly(drawvec &geom, int z, int buffer, bool clip, bool try_scaling, bool even_odd) {
geom = remove_noop(geom, VT_POLYGON, 0);
mapbox::geometry::multi_polygon<long long> result;

Expand Down Expand Up @@ -308,7 +308,11 @@ drawvec clean_or_clip_poly(drawvec &geom, int z, int buffer, bool clip, bool try

try {
result.clear();
wagyu.execute(mapbox::geometry::wagyu::clip_type_union, result, mapbox::geometry::wagyu::fill_type_positive, mapbox::geometry::wagyu::fill_type_positive);
if (even_odd) {
wagyu.execute(mapbox::geometry::wagyu::clip_type_union, result, mapbox::geometry::wagyu::fill_type_even_odd, mapbox::geometry::wagyu::fill_type_even_odd);
} else {
wagyu.execute(mapbox::geometry::wagyu::clip_type_union, result, mapbox::geometry::wagyu::fill_type_positive, mapbox::geometry::wagyu::fill_type_positive);
}
} catch (std::runtime_error &e) {
FILE *f = fopen("/tmp/wagyu.log", "w");
fprintf(f, "%s\n", e.what());
Expand Down Expand Up @@ -858,7 +862,8 @@ std::string overzoom(mvt_tile tile, int oz, int ox, int oy, int nz, int nx, int

geom = remove_noop(geom, t, 0);
if (t == VT_POLYGON) {
geom = clean_or_clip_poly(geom, 0, 0, false, false);
// this is after scaling, so even-odd to balance scaling errors between features
geom = clean_or_clip_poly(geom, 0, 0, false, false, true);
geom = close_poly(geom);
}

Expand Down
2 changes: 1 addition & 1 deletion geometry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ 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, bool try_scaling);
drawvec clean_or_clip_poly(drawvec &geom, int z, int buffer, bool clip, bool try_scaling, bool even_odd);
drawvec close_poly(drawvec &geom);
drawvec reduce_tiny_poly(drawvec &geom, int z, int detail, bool *still_needs_simplification, bool *reduced_away, double *accum_area, serial_feature *this_feature, serial_feature *tiny_feature);
int clip(long long *x0, long long *y0, long long *x1, long long *y1, long long xmin, long long ymin, long long xmax, long long ymax);
Expand Down
3 changes: 2 additions & 1 deletion plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,8 @@ std::vector<mvt_layer> parse_layers(int fd, int z, unsigned x, unsigned y, std::

if (mb_geometry[t] == VT_POLYGON) {
// we can try scaling up because these are tile coordinates
dv = clean_or_clip_poly(dv, 0, 0, false, true);
// these are already scaled, so even-odd winding
dv = clean_or_clip_poly(dv, 0, 0, false, true, true);
if (dv.size() < 3) {
dv.clear();
}
Expand Down
47 changes: 43 additions & 4 deletions tile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,8 @@ double simplify_partial(partial *p, drawvec const &shared_nodes, node *shared_no
// unioned exactly
//
// don't try to scale up because these are still world coordinates
geom = clean_or_clip_poly(geom, 0, 0, false, false);
// positive winding because these are world coordinates
geom = clean_or_clip_poly(geom, 0, 0, false, false, true);
}

// continues to simplify to line_detail even if we have extra detail
Expand Down Expand Up @@ -611,7 +612,42 @@ void *partial_feature_worker(void *v) {
int z = (*partials)[i].z;
int out_detail = (*partials)[i].extra_detail;

#if 0
if ((*partials)[i].geoms[0].size() < 1) {
fprintf(stderr, "expected at least one geometry in partial_feature_worker\n");
exit(EXIT_IMPOSSIBLE);
}
for (size_t x = 1; x < (*partials)[i].geoms.size(); x++) {
for (auto const &d : (*partials)[i].geoms[x]) {
(*partials)[i].geoms[0].push_back(d);
}
}
(*partials)[i].geoms.resize(1);
#endif

if ((*partials)[i].geoms.size() != 1) {
fprintf(stderr, "expected single geometry in partial_feature_worker\n");
exit(EXIT_IMPOSSIBLE);
}
drawvec geom = (*partials)[i].geoms[0];

if (t == VT_POLYGON) {
// clean multi-ring polygons with positive winding before scaling
// so that polygon dust will be unioned on positively

size_t ring_count = 0;
for (size_t x = 0; x < geom.size(); x++) {
if (geom[x].op == VT_MOVETO) {
ring_count++;

if (ring_count == 2) {
geom = clean_or_clip_poly(geom, 0, 0, false, false, false);
break;
}
}
}
}

to_tile_scale(geom, z, out_detail);

if (t == VT_POLYGON) {
Expand All @@ -620,7 +656,8 @@ void *partial_feature_worker(void *v) {
{
drawvec before = geom;
// we can try scaling up because this is now tile scale
geom = clean_or_clip_poly(geom, 0, 0, false, true);
// even-odd since we have scaled
geom = clean_or_clip_poly(geom, 0, 0, false, true, true);
if (additional[A_DEBUG_POLYGON]) {
check_polygon(geom);
}
Expand Down Expand Up @@ -2293,7 +2330,8 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
for (auto &g : partials[simplified_geometry_through].geoms) {
if (partials[simplified_geometry_through].t == VT_POLYGON) {
// don't scale up because this is still world coordinates
g = clean_or_clip_poly(g, 0, 0, false, false);
// positive winding because this before scaling
g = clean_or_clip_poly(g, 0, 0, false, false, false);
}
}
}
Expand Down Expand Up @@ -2533,7 +2571,8 @@ long long write_tile(decompressor *geoms, std::atomic<long long> *geompos_in, ch
if (layer_features[x].type == VT_POLYGON) {
if (layer_features[x].coalesced) {
// we can try scaling up because this is tile coordinates
layer_features[x].geom = clean_or_clip_poly(layer_features[x].geom, 0, 0, false, true);
// positive winding because we are trying to union features here
layer_features[x].geom = clean_or_clip_poly(layer_features[x].geom, 0, 0, false, true, false);
}

layer_features[x].geom = close_poly(layer_features[x].geom);
Expand Down
Loading