1 #pragma once
2 
3 #include <mapbox/geometry/wagyu/ring.hpp>
4 #include <mapbox/geometry/wagyu/ring_util.hpp>
5 
6 #include <mapbox/geometry/multi_polygon.hpp>
7 
8 namespace mapbox {
9 namespace geometry {
10 namespace wagyu {
11 
12 template <typename T1, typename T2>
push_ring_to_polygon(mapbox::geometry::polygon<T2> & poly,ring_ptr<T1> r,bool reverse_output)13 void push_ring_to_polygon(mapbox::geometry::polygon<T2>& poly,
14                           ring_ptr<T1> r,
15                           bool reverse_output) {
16     mapbox::geometry::linear_ring<T2> lr;
17     lr.reserve(r->size() + 1);
18     auto firstPt = r->points;
19     auto ptIt = r->points;
20     if (reverse_output) {
21         do {
22             lr.emplace_back(static_cast<T2>(ptIt->x), static_cast<T2>(ptIt->y));
23             ptIt = ptIt->next;
24         } while (ptIt != firstPt);
25     } else {
26         do {
27             lr.emplace_back(static_cast<T2>(ptIt->x), static_cast<T2>(ptIt->y));
28             ptIt = ptIt->prev;
29         } while (ptIt != firstPt);
30     }
31     lr.emplace_back(firstPt->x, firstPt->y); // close the ring
32     poly.push_back(lr);
33 }
34 
35 template <typename T1, typename T2>
build_result_polygons(mapbox::geometry::multi_polygon<T2> & solution,ring_vector<T1> const & rings,bool reverse_output)36 void build_result_polygons(mapbox::geometry::multi_polygon<T2>& solution,
37                            ring_vector<T1>const& rings,
38                            bool reverse_output) {
39     for (auto r : rings) {
40         if (r == nullptr) {
41             continue;
42         }
43         assert(r->points);
44         solution.emplace_back();
45         push_ring_to_polygon(solution.back(), r, reverse_output);
46         for (auto c : r->children) {
47             if (c == nullptr) {
48                 continue;
49             }
50             assert(c->points);
51             push_ring_to_polygon(solution.back(), c, reverse_output);
52         }
53         for (auto c : r->children) {
54             if (c == nullptr) {
55                 continue;
56             }
57             if (!c->children.empty()) {
58                 build_result_polygons(solution, c->children, reverse_output);
59             }
60         }
61     }
62 }
63 
64 template <typename T1, typename T2>
build_result(mapbox::geometry::multi_polygon<T2> & solution,ring_manager<T1> const & rings,bool reverse_output)65 void build_result(mapbox::geometry::multi_polygon<T2>& solution,
66                   ring_manager<T1>const& rings,
67                   bool reverse_output) {
68     build_result_polygons(solution, rings.children, reverse_output);
69 }
70 }
71 }
72 }
73