1 #pragma once
2
3 #ifdef DEBUG
4 #include <iostream>
5 #include <sstream>
6 #endif
7
8 #include <queue>
9
10 #include <mapbox/geometry/wagyu/bound.hpp>
11
12 namespace mapbox {
13 namespace geometry {
14 namespace wagyu {
15
16 template <typename T>
17 struct local_minimum {
18 bound<T> left_bound;
19 bound<T> right_bound;
20 T y;
21 bool minimum_has_horizontal;
22
local_minimummapbox::geometry::wagyu::local_minimum23 local_minimum(bound<T>&& left_bound_, bound<T>&& right_bound_, T y_, bool has_horz_)
24 : left_bound(std::move(left_bound_)),
25 right_bound(std::move(right_bound_)),
26 y(y_),
27 minimum_has_horizontal(has_horz_) {
28 }
29 };
30
31 template <typename T>
32 using local_minimum_list = std::deque<local_minimum<T>>;
33
34 template <typename T>
35 using local_minimum_itr = typename local_minimum_list<T>::iterator;
36
37 template <typename T>
38 using local_minimum_ptr = local_minimum<T>*;
39
40 template <typename T>
41 using local_minimum_ptr_list = std::vector<local_minimum_ptr<T>>;
42
43 template <typename T>
44 using local_minimum_ptr_list_itr = typename local_minimum_ptr_list<T>::iterator;
45
46 template <typename T>
47 struct local_minimum_sorter {
operator ()mapbox::geometry::wagyu::local_minimum_sorter48 inline bool operator()(local_minimum_ptr<T> const& locMin1,
49 local_minimum_ptr<T> const& locMin2) {
50 if (locMin2->y == locMin1->y) {
51 return locMin2->minimum_has_horizontal != locMin1->minimum_has_horizontal &&
52 locMin1->minimum_has_horizontal;
53 }
54 return locMin2->y < locMin1->y;
55 }
56 };
57
58 #ifdef DEBUG
59
60 template <class charT, class traits, typename T>
operator <<(std::basic_ostream<charT,traits> & out,const local_minimum<T> & lm)61 inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& out,
62 const local_minimum<T>& lm) {
63 out << " Local Minimum:" << std::endl;
64 out << " y: " << lm.y << std::endl;
65 if (lm.minimum_has_horizontal) {
66 out << " minimum_has_horizontal: true" << std::endl;
67 } else {
68 out << " minimum_has_horizontal: false" << std::endl;
69 }
70 out << " left_bound: " << std::endl;
71 out << lm.left_bound << std::endl;
72 out << " right_bound: " << std::endl;
73 out << lm.right_bound << std::endl;
74 return out;
75 }
76
77 template <class charT, class traits, typename T>
operator <<(std::basic_ostream<charT,traits> & out,const local_minimum_ptr_list<T> & lms)78 inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& out,
79 const local_minimum_ptr_list<T>& lms) {
80 for (auto const& lm : lms) {
81 out << *lm;
82 }
83 return out;
84 }
85
86 template <typename T>
output_all_edges(local_minimum_ptr_list<T> const & lms)87 std::string output_all_edges(local_minimum_ptr_list<T> const& lms) {
88 std::ostringstream out;
89 out << "[";
90 bool first = true;
91 for (auto const& lm : lms) {
92 for (auto const& e : lm->left_bound.edges) {
93 if (first) {
94 first = false;
95 } else {
96 out << ",";
97 }
98 out << "[[" << e.bot.x << "," << e.bot.y << "],[";
99 out << e.top.x << "," << e.top.y << "]]";
100 }
101 for (auto const& e : lm->right_bound.edges) {
102 if (first) {
103 first = false;
104 } else {
105 out << ",";
106 }
107 out << "[[" << e.bot.x << "," << e.bot.y << "],[";
108 out << e.top.x << "," << e.top.y << "]]";
109 }
110 }
111 out << "]";
112 return out.str();
113 }
114
115 #endif
116 }
117 }
118 }
119