diff --git a/src/mbgl/tile/geometry_tile_data.cpp b/src/mbgl/tile/geometry_tile_data.cpp index b635c194e..680f8d149 100644 --- a/src/mbgl/tile/geometry_tile_data.cpp +++ b/src/mbgl/tile/geometry_tile_data.cpp @@ -17,8 +17,8 @@ static double signedArea(const GeometryCoordinates& ring) { return sum; } -static LinearRing toWagyuPath(const GeometryCoordinates& ring) { - LinearRing result; +static LinearRing toWagyuPath(const GeometryCoordinates& ring) { + LinearRing result; result.reserve(ring.size()); for (const auto& p : ring) { result.emplace_back(p.x, p.y); @@ -26,85 +26,29 @@ static LinearRing toWagyuPath(const GeometryCoordinates& ring) { return result; } -static void pushWagyuRing(GeometryCollection & solution, - mapbox::geometry::wagyu::ring_ptr r) { - GeometryCoordinates lr; - lr.reserve(r->size() + 1); - auto firstPt = r->points; - auto ptIt = r->points; - do { - lr.emplace_back(ptIt->x, ptIt->y); - ptIt = ptIt->prev; - } while (ptIt != firstPt); - lr.emplace_back(firstPt->x, firstPt->y); // close the ring - solution.push_back(lr); -} - -static void buildWagyuResults(GeometryCollection & solution, - mapbox::geometry::wagyu::ring_vector& rings) { - for (auto r : rings) { - if (r == nullptr) { - continue; - } - assert(r->points); - if (r->size() < 3) { - continue; - } - solution.emplace_back(); - pushWagyuRing(solution, r); - for (auto c : r->children) { - if (c == nullptr) { - continue; - } - assert(c->points); - if (c->size() < 3) { - continue; - } - pushWagyuRing(solution, c); - } - for (auto c : r->children) { - if (c == nullptr) { - continue; - } - if (!c->children.empty()) { - buildWagyuResults(solution, c->children); - } +static GeometryCollection toGeometryCollection(MultiPolygon&& multipolygon) { + GeometryCollection result; + for (auto& polygon : multipolygon) { + for (auto& ring : polygon) { + result.emplace_back(std::move(ring)); } } + return result; } GeometryCollection fixupPolygons(const GeometryCollection& rings) { using namespace mapbox::geometry::wagyu; - - // This is code that is pulled from the wagyu main class, we - // are doing this to have our own custom build result, - // rather then copying output twice from the wagyu algorithm. - local_minimum_list minima_list; + wagyu clipper; for (const auto& ring : rings) { - // Convert ring to LinearRing type prior to adding them - add_linear_ring(toWagyuPath(ring), minima_list, polygon_type_subject); + clipper.add_ring(toWagyuPath(ring)); } - // Core part of wagyu algorithm - ring_manager manager; - - build_hot_pixels(minima_list, manager); - - execute_vatti(minima_list, manager, clip_type_union, fill_type_even_odd, fill_type_even_odd); - - correct_topology(manager); + MultiPolygon multipolygon; + clipper.execute(clip_type_union, multipolygon, fill_type_even_odd, fill_type_even_odd); - // Finally lets build results - GeometryCollection result; - - // This calls code based on wagyu/build_results.hpp - // rather then returning a multipolygon however, we are - // going to return a GeometryCollection - buildWagyuResults(result, manager.children); - - return result; + return toGeometryCollection(std::move(multipolygon)); } std::vector classifyRings(const GeometryCollection& rings) { diff --git a/src/mbgl/tile/geometry_tile_data.hpp b/src/mbgl/tile/geometry_tile_data.hpp index 8a10ec058..285f86cc7 100644 --- a/src/mbgl/tile/geometry_tile_data.hpp +++ b/src/mbgl/tile/geometry_tile_data.hpp @@ -21,6 +21,13 @@ using GeometryCoordinate = Point; class GeometryCoordinates : public std::vector { public: using coordinate_type = int16_t; + + GeometryCoordinates() = default; + GeometryCoordinates(const std::vector& v) + : std::vector(v) {} + GeometryCoordinates(std::vector&& v) + : std::vector(std::move(v)) {} + using std::vector::vector; };