#pragma once #include "geometry/point2d.hpp" #include "geometry/region2d.hpp" #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wshorten-64-to-32" #include "3party/boost/boost/polygon/detail/polygon_sort_adaptor.hpp" #include "3party/boost/boost/polygon/polygon.hpp" #pragma clang diagnostic pop #else #include "3party/boost/boost/polygon/detail/polygon_sort_adaptor.hpp" #include "3party/boost/boost/polygon/polygon.hpp" #endif #include "std/vector.hpp" namespace boost { namespace polygon { typedef int32_t my_coord_t; //////////////////////////////////////////////////////////////////////////////// // Point concept. //////////////////////////////////////////////////////////////////////////////// typedef m2::PointI my_point_t; template <> struct geometry_concept { typedef point_concept type; }; template <> struct point_traits { typedef my_point_t::value_type coordinate_type; static inline coordinate_type get(my_point_t const & p, orientation_2d o) { return ((o == HORIZONTAL) ? p.x : p.y); } }; template <> struct point_mutable_traits { typedef my_point_t::value_type CoordT; static inline void set(my_point_t & p, orientation_2d o, CoordT v) { if (o == HORIZONTAL) p.x = v; else p.y = v; } static inline my_point_t construct(CoordT x, CoordT y) { return my_point_t(x, y); } }; //////////////////////////////////////////////////////////////////////////////// // Polygon concept. //////////////////////////////////////////////////////////////////////////////// typedef m2::RegionI my_region_t; template <> struct geometry_concept { typedef polygon_concept type; }; template <> struct polygon_traits { typedef my_region_t::CoordT coordinate_type; typedef my_region_t::IteratorT iterator_type; typedef my_region_t::ValueT point_type; // Get the begin iterator static inline iterator_type begin_points(my_region_t const & t) { return t.Begin(); } // Get the end iterator static inline iterator_type end_points(my_region_t const & t) { return t.End(); } // Get the number of sides of the polygon static inline size_t size(my_region_t const & t) { return t.Size(); } // Get the winding direction of the polygon static inline winding_direction winding(my_region_t const & /*t*/) { return unknown_winding; } }; struct my_point_getter { my_point_t operator() (point_data const & t) { return my_point_t(t.x(), t.y()); } }; template <> struct polygon_mutable_traits { // expects stl style iterators template static inline my_region_t & set_points(my_region_t & t, IterT b, IterT e) { t.AssignEx(b, e, my_point_getter()); return t; } }; //////////////////////////////////////////////////////////////////////////////// // Polygon set concept. //////////////////////////////////////////////////////////////////////////////// typedef vector my_region_set_t; template <> struct geometry_concept { typedef polygon_set_concept type; }; // next we map to the concept through traits template <> struct polygon_set_traits { typedef my_coord_t coordinate_type; typedef my_region_set_t::const_iterator iterator_type; typedef my_region_set_t operator_arg_type; static inline iterator_type begin(my_region_set_t const & t) { return t.begin(); } static inline iterator_type end(my_region_set_t const & t) { return t.end(); } // don't worry about these, just return false from them static inline bool clean(my_region_set_t const & /*t*/) { return false; } static inline bool sorted(my_region_set_t const & /*t*/) { return false; } }; template <> struct polygon_set_mutable_traits { template static inline void set(my_region_set_t & poly_set, IterT b, IterT e) { poly_set.clear(); // this is kind of cheesy. I am copying the unknown input geometry // into my own polygon set and then calling get to populate the vector polygon_set_data ps; ps.insert(b, e); ps.get(poly_set); // if you had your own odd-ball polygon set you would probably have // to iterate through each polygon at this point and do something extra } }; }}