diff --git a/README.md b/README.md index 972614a..f4d166a 100644 --- a/README.md +++ b/README.md @@ -81,3 +81,22 @@ int main() { mapbox::util::apply_visitor(visitor,geom); } ``` + +Geometry types with a custom point type: + +```cpp +#include + +// geometry.hpp provides a `geometry_t` template that supports any point type with a +// `coordinate_type` member. +struct my_point { + using coordinate_type = double; + double x; + double y; + double elevation; +}; + +using my_geometry = mapbox::geometry::geometry_t; +using my_line_string = my_geometry::line_string_type; +using my_polygon = my_geometry::polygon_type; +// etc. diff --git a/include/mapbox/geometry/geometry.hpp b/include/mapbox/geometry/geometry.hpp index cf70d8e..a40e12f 100644 --- a/include/mapbox/geometry/geometry.hpp +++ b/include/mapbox/geometry/geometry.hpp @@ -14,38 +14,52 @@ namespace mapbox { namespace geometry { -template class Cont = std::vector> -struct geometry_collection; - -template -using geometry_base = mapbox::util::variant, - line_string, - polygon, - multi_point, - multi_line_string, - multi_polygon, - geometry_collection>; - -template -struct geometry : geometry_base +template class Cont = std::vector> +struct geometry_collection_t; + +template +using geometry_base_t = mapbox::util::variant, + polygon_t, + multi_point_t, + multi_line_string_t, + multi_polygon_t, + geometry_collection_t>; + +template +struct geometry_t : geometry_base_t { - using coordinate_type = T; - using geometry_base::geometry_base; + using point_type = Point; + using line_string_type = line_string_t; + using polygon_type = polygon_t; + using multi_point_type = multi_point_t; + using multi_line_string_type = multi_line_string_t; + using multi_polygon_type = multi_polygon_t; + using geometry_collection_type = geometry_collection_t; + using coordinate_type = typename point_type::coordinate_type; + using geometry_base_t::geometry_base_t; /* * The default constructor would create a point geometry with default-constructed coordinates; * i.e. (0, 0). Since this is not particularly useful, and could hide bugs, it is disabled. */ - geometry() = delete; + geometry_t() = delete; }; -template class Cont> -struct geometry_collection : Cont> +template +using geometry = geometry_t>; + +template class Container> +struct geometry_collection_t : Container> { - using coordinate_type = T; - using geometry_type = geometry; - using container_type = Cont; + using point_type = Point; + using coordinate_type = typename point_type::coordinate_type; + using geometry_type = geometry_t; + using container_type = Container; using container_type::container_type; }; +template class Container = std::vector> +using geometry_collection = geometry_collection_t, Container>; + }} diff --git a/include/mapbox/geometry/line_string.hpp b/include/mapbox/geometry/line_string.hpp index 03a0954..c13dc0b 100644 --- a/include/mapbox/geometry/line_string.hpp +++ b/include/mapbox/geometry/line_string.hpp @@ -7,13 +7,16 @@ namespace mapbox { namespace geometry { -template class Cont = std::vector> -struct line_string : Cont > +template class Container = std::vector> +struct line_string_t : Container { - using coordinate_type = T; - using point_type = point; - using container_type = Cont; + using point_type = Point; + using coordinate_type = typename point_type::coordinate_type; + using container_type = Container; using container_type::container_type; }; +template class Container = std::vector> +using line_string = line_string_t, Container>; + }} diff --git a/include/mapbox/geometry/multi_line_string.hpp b/include/mapbox/geometry/multi_line_string.hpp index 4864dd2..e91d90a 100644 --- a/include/mapbox/geometry/multi_line_string.hpp +++ b/include/mapbox/geometry/multi_line_string.hpp @@ -7,13 +7,17 @@ namespace mapbox { namespace geometry { -template class Cont = std::vector> -struct multi_line_string : Cont> +template class Container = std::vector> +struct multi_line_string_t : Container> { - using coordinate_type = T; - using line_string_type = line_string; - using container_type = Cont; + using point_type = Point; + using coordinate_type = typename point_type::coordinate_type; + using line_string_type = line_string_t; + using container_type = Container; using container_type::container_type; }; +template class Container = std::vector> +using multi_line_string = multi_line_string_t, Container>; + }} diff --git a/include/mapbox/geometry/multi_point.hpp b/include/mapbox/geometry/multi_point.hpp index eb81cd4..24060c6 100644 --- a/include/mapbox/geometry/multi_point.hpp +++ b/include/mapbox/geometry/multi_point.hpp @@ -7,13 +7,16 @@ namespace mapbox { namespace geometry { -template class Cont = std::vector> -struct multi_point : Cont> +template class Container = std::vector> +struct multi_point_t : Container { - using coordinate_type = T; - using point_type = point; - using container_type = Cont; + using point_type = Point; + using coordinate_type = typename point_type::coordinate_type; + using container_type = Container; using container_type::container_type; }; +template class Container = std::vector> +using multi_point = multi_point_t, Container>; + }} diff --git a/include/mapbox/geometry/multi_polygon.hpp b/include/mapbox/geometry/multi_polygon.hpp index d5da1cb..1f92665 100644 --- a/include/mapbox/geometry/multi_polygon.hpp +++ b/include/mapbox/geometry/multi_polygon.hpp @@ -7,13 +7,17 @@ namespace mapbox { namespace geometry { -template class Cont = std::vector> -struct multi_polygon : Cont> +template class Container = std::vector> +struct multi_polygon_t : Container> { - using coordinate_type = T; - using polygon_type = polygon; - using container_type = Cont; + using point_type = Point; + using coordinate_type = typename point_type::coordinate_type; + using polygon_type = polygon_t; + using container_type = Container; using container_type::container_type; }; +template class Container = std::vector> +using multi_polygon = multi_polygon_t, Container>; + }} diff --git a/include/mapbox/geometry/polygon.hpp b/include/mapbox/geometry/polygon.hpp index fab9f4d..510e2b5 100644 --- a/include/mapbox/geometry/polygon.hpp +++ b/include/mapbox/geometry/polygon.hpp @@ -8,22 +8,26 @@ namespace mapbox { namespace geometry { -template class Cont = std::vector> -struct linear_ring : Cont> +template class Container = std::vector> +struct linear_ring_t : Container { - using coordinate_type = T; - using point_type = point; - using container_type = Cont; + using point_type = Point; + using coordinate_type = typename point_type::coordinate_type; + using container_type = Container; using container_type::container_type; }; -template class Cont = std::vector> -struct polygon : Cont> +template class Container = std::vector> +struct polygon_t : Container> { - using coordinate_type = T; - using linear_ring_type = linear_ring; - using container_type = Cont; + using point_type = Point; + using coordinate_type = typename point_type::coordinate_type; + using linear_ring_type = linear_ring_t; + using container_type = Container; using container_type::container_type; }; +template class Container = std::vector> +using polygon = polygon_t, Container>; + }} diff --git a/tests/test.cpp b/tests/test.cpp index 2dba1c5..75f54cc 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -193,6 +193,21 @@ static void testEnvelope() { assert(envelope(geometry_collection({point(0, 0)})) == box({0, 0}, {0, 0})); } +static void testCustomPointType() { + struct point_3d { + using coordinate_type = double; + double x; + double y; + double z; + }; + + using custom_geometry = geometry_t; + using custom_polygon = custom_geometry::polygon_type; + + custom_geometry g { custom_polygon({{{0, 1, 2}, {3, 4, 5}}}) }; + assert(g.get()[0][0].x == 0); +} + int main() { testPoint(); testMultiPoint(); @@ -207,5 +222,6 @@ int main() { testForEachPoint(); testEnvelope(); + testCustomPointType(); return 0; }