diff --git a/include/boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp b/include/boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp index 34cd5330b..a8eaf2787 100644 --- a/include/boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp +++ b/include/boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp @@ -62,7 +62,7 @@ struct byte_order_type }; }; -struct geometry_type +struct geometry_type_ogc { enum enum_t { @@ -78,9 +78,131 @@ struct geometry_type }; }; -}} // namespace detail::endian +struct geometry_type_ewkt +{ + enum enum_t + { + point = 1, + linestring = 2, + polygon = 3, + + // TODO: Not implemented + //multipoint = 4, + //multilinestring = 5, + //multipolygon = 6, + //collection = 7 + + + pointz = 1001, + linestringz = 1002, + polygonz = 1003 + }; +}; + +struct ogc_policy +{ +}; + +struct ewkt_policy +{ +}; + +template +< + typename Geometry, + typename CheckPolicy = ogc_policy, + typename Tag = typename tag::type +> +struct geometry_type : not_implemented +{ +}; + +template +struct geometry_type +{ + static bool check(boost::uint32_t value) + { + return value == get_impl::value>(); + } + + static boost::uint32_t get() + { + return get_impl::value>(); + } + +private: + + template + static boost::uint32_t get_impl() + { + return geometry_type_ogc::point; + } + + template <> + static boost::uint32_t get_impl<3>() + { + return 1000 + geometry_type_ogc::point; + } +}; + +template +struct geometry_type +{ + static bool check(boost::uint32_t value) + { + return value == get_impl::value>(); + } + + static boost::uint32_t get() + { + return get_impl::value>(); + } + +private: + + template + static boost::uint32_t get_impl() + { + return geometry_type_ogc::linestring; + } + + template <> + static boost::uint32_t get_impl<3>() + { + return 1000 + geometry_type_ogc::linestring; + } +}; + +template +struct geometry_type +{ + static bool check(boost::uint32_t value) + { + return value == get_impl::value>(); + } + + static boost::uint32_t get() + { + return get_impl::value>(); + } + +private: + + template + static boost::uint32_t get_impl() + { + return geometry_type_ogc::polygon; + } + + template <> + static boost::uint32_t get_impl<3>() + { + return 1000 + geometry_type_ogc::polygon; + } +}; + +}} // namespace detail::wkb #endif // DOXYGEN_NO_IMPL }} // namespace boost::geometry - #endif // BOOST_GEOMETRY_IO_WKB_DETAIL_OGC_HPP diff --git a/include/boost/geometry/extensions/gis/io/wkb/detail/parser.hpp b/include/boost/geometry/extensions/gis/io/wkb/detail/parser.hpp index d91979b11..eeb1f5c88 100644 --- a/include/boost/geometry/extensions/gis/io/wkb/detail/parser.hpp +++ b/include/boost/geometry/extensions/gis/io/wkb/detail/parser.hpp @@ -101,23 +101,17 @@ struct byte_order_parser } }; +template struct geometry_type_parser { template - static bool parse(Iterator& it, Iterator end, geometry_type::enum_t& type, - byte_order_type::enum_t order) + static bool parse(Iterator& it, Iterator end, + byte_order_type::enum_t order) { boost::uint32_t value; if (value_parser::parse(it, end, value, order)) { - // TODO: Refine the test when multi* geometries are supported - - boost::uint32_t id = value & 0xff; - if (geometry_type::polygon >= id) - { - type = geometry_type::enum_t(id); - return true; - } + return geometry_type::check(value); } return false; } @@ -127,7 +121,8 @@ template struct parsing_assigner { template - static void run(Iterator& it, Iterator end, P& point, byte_order_type::enum_t order) + static void run(Iterator& it, Iterator end, P& point, + byte_order_type::enum_t order) { typedef typename coordinate_type

::type coordinate_type; @@ -154,7 +149,8 @@ template struct parsing_assigner { template - static void run(Iterator& it, Iterator end, P& point, byte_order_type::enum_t order) + static void run(Iterator& it, Iterator end, P& point, + byte_order_type::enum_t order) { // terminate boost::ignore_unused_variable_warning(it); @@ -168,14 +164,12 @@ template struct point_parser { template - static bool parse(Iterator& it, Iterator end, P& point, byte_order_type::enum_t order) + static bool parse(Iterator& it, Iterator end, P& point, + byte_order_type::enum_t order) { - // TODO: mloskot - Add assert on point dimension, 2d only - - geometry_type::enum_t type; - if (geometry_type_parser::parse(it, end, type, order)) + if (geometry_type_parser

::parse(it, end, order)) { - if (geometry_type::point == type && it != end) + if (it != end) { parsing_assigner::value>::run(it, end, point, order); } @@ -189,7 +183,8 @@ template struct point_container_parser { template - static bool parse(Iterator& it, Iterator end, C& container, byte_order_type::enum_t order) + static bool parse(Iterator& it, Iterator end, C& container, + byte_order_type::enum_t order) { typedef typename point_type::type point_type; @@ -208,15 +203,13 @@ struct point_container_parser if (std::distance(it, end) >= (container_size * point_size)) { point_type point_buffer; - std::back_insert_iterator output(std::back_inserter(container)); // Read coordinates into point and append point to line (ring) size_type points_parsed = 0; while (points_parsed < container_size && it != end) { parsing_assigner::value>::run(it, end, point_buffer, order); - output = point_buffer; - ++output; + boost::geometry::append(container, point_buffer); ++points_parsed; } @@ -225,6 +218,10 @@ struct point_container_parser return false; } } + else + { + return false; + } return true; } @@ -234,17 +231,12 @@ template struct linestring_parser { template - static bool parse(Iterator& it, Iterator end, L& linestring, byte_order_type::enum_t order) + static bool parse(Iterator& it, Iterator end, L& linestring, + byte_order_type::enum_t order) { typedef typename point_type::type point_type; - geometry_type::enum_t type; - if (!geometry_type_parser::parse(it, end, type, order)) - { - return false; - } - - if (geometry_type::linestring != type) + if (!geometry_type_parser::parse(it, end, order)) { return false; } @@ -258,17 +250,16 @@ template struct polygon_parser { template - static bool parse(Iterator& it, Iterator end, Polygon& polygon, byte_order_type::enum_t order) + static bool parse(Iterator& it, Iterator end, Polygon& polygon, + byte_order_type::enum_t order) { - geometry_type::enum_t type; - if (!geometry_type_parser::parse(it, end, type, order)) + if (!geometry_type_parser::parse(it, end, order)) { return false; } boost::uint32_t num_rings(0); - if (geometry_type::polygon != type || - !value_parser::parse(it, end, num_rings, order)) + if (!value_parser::parse(it, end, num_rings, order)) { return false; } @@ -276,7 +267,7 @@ struct polygon_parser typedef typename ring_type::type ring_type; std::size_t rings_parsed = 0; - while (rings_parsed < num_rings && it != end) //while (rings_parsed < num_rings && it != end) + while (rings_parsed < num_rings && it != end) { if (0 == rings_parsed) { @@ -311,6 +302,4 @@ struct polygon_parser #endif // DOXYGEN_NO_IMPL }} // namespace boost::geometry - - #endif // BOOST_GEOMETRY_IO_WKB_DETAIL_PARSER_HPP