mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-02 16:35:40 +02:00
Even-odd wagyu after scaling to counterbalance ring reversals
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
+2
-1
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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) {
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user