mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-02 21:02:13 +00:00
[extensions][wkb] Change handling of wkb geometry_type to be more generic
The geometry type is changed to be more flexible and able to handle multiple formats and different dimensions in the future.
This commit is contained in:
@@ -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<Geometry>::type
|
||||
>
|
||||
struct geometry_type : not_implemented<Tag>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Geometry, typename CheckPolicy>
|
||||
struct geometry_type<Geometry, CheckPolicy, point_tag>
|
||||
{
|
||||
static bool check(boost::uint32_t value)
|
||||
{
|
||||
return value == get_impl<dimension<Geometry>::value>();
|
||||
}
|
||||
|
||||
static boost::uint32_t get()
|
||||
{
|
||||
return get_impl<dimension<Geometry>::value>();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template <int dimension>
|
||||
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 <typename Geometry, typename CheckPolicy>
|
||||
struct geometry_type<Geometry, CheckPolicy, linestring_tag>
|
||||
{
|
||||
static bool check(boost::uint32_t value)
|
||||
{
|
||||
return value == get_impl<dimension<Geometry>::value>();
|
||||
}
|
||||
|
||||
static boost::uint32_t get()
|
||||
{
|
||||
return get_impl<dimension<Geometry>::value>();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template <int dimension>
|
||||
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 <typename Geometry, typename CheckPolicy>
|
||||
struct geometry_type<Geometry, CheckPolicy, polygon_tag>
|
||||
{
|
||||
static bool check(boost::uint32_t value)
|
||||
{
|
||||
return value == get_impl<dimension<Geometry>::value>();
|
||||
}
|
||||
|
||||
static boost::uint32_t get()
|
||||
{
|
||||
return get_impl<dimension<Geometry>::value>();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template <int dimension>
|
||||
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
|
||||
|
||||
@@ -101,23 +101,17 @@ struct byte_order_parser
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct geometry_type_parser
|
||||
{
|
||||
template <typename Iterator>
|
||||
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<boost::uint32_t>::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<Geometry>::check(value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -127,7 +121,8 @@ template <typename P, int I, int N>
|
||||
struct parsing_assigner
|
||||
{
|
||||
template <typename Iterator>
|
||||
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<P>::type coordinate_type;
|
||||
|
||||
@@ -154,7 +149,8 @@ template <typename P, int N>
|
||||
struct parsing_assigner<P, N, N>
|
||||
{
|
||||
template <typename Iterator>
|
||||
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 <typename P>
|
||||
struct point_parser
|
||||
{
|
||||
template <typename Iterator>
|
||||
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<P>::parse(it, end, order))
|
||||
{
|
||||
if (geometry_type::point == type && it != end)
|
||||
if (it != end)
|
||||
{
|
||||
parsing_assigner<P, 0, dimension<P>::value>::run(it, end, point, order);
|
||||
}
|
||||
@@ -189,7 +183,8 @@ template <typename C>
|
||||
struct point_container_parser
|
||||
{
|
||||
template <typename Iterator>
|
||||
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<C>::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<C> 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<point_type, 0, dimension<point_type>::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 <typename L>
|
||||
struct linestring_parser
|
||||
{
|
||||
template <typename Iterator>
|
||||
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<L>::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<L>::parse(it, end, order))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -258,17 +250,16 @@ template <typename Polygon>
|
||||
struct polygon_parser
|
||||
{
|
||||
template <typename Iterator>
|
||||
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<Polygon>::parse(it, end, order))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
boost::uint32_t num_rings(0);
|
||||
if (geometry_type::polygon != type ||
|
||||
!value_parser<boost::uint32_t>::parse(it, end, num_rings, order))
|
||||
if (!value_parser<boost::uint32_t>::parse(it, end, num_rings, order))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -276,7 +267,7 @@ struct polygon_parser
|
||||
typedef typename ring_type<Polygon>::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
|
||||
|
||||
Reference in New Issue
Block a user