summaryrefslogtreecommitdiff
path: root/boost/geometry/io/wkt/read.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/io/wkt/read.hpp')
-rw-r--r--boost/geometry/io/wkt/read.hpp169
1 files changed, 144 insertions, 25 deletions
diff --git a/boost/geometry/io/wkt/read.hpp b/boost/geometry/io/wkt/read.hpp
index e926939d51..748eecdbe6 100644
--- a/boost/geometry/io/wkt/read.hpp
+++ b/boost/geometry/io/wkt/read.hpp
@@ -14,6 +14,7 @@
#ifndef BOOST_GEOMETRY_IO_WKT_READ_HPP
#define BOOST_GEOMETRY_IO_WKT_READ_HPP
+#include <cstddef>
#include <string>
#include <boost/lexical_cast.hpp>
@@ -36,6 +37,8 @@
#include <boost/geometry/core/geometry_id.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/mutable_range.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
@@ -306,8 +309,6 @@ struct ring_parser
};
-
-
/*!
\brief Internal, parses a polygon from a string like this "((x y,x y),(x y,x y))"
\note used for parsing polygons and multi-polygons
@@ -358,6 +359,7 @@ struct polygon_parser
}
};
+
inline bool one_of(tokenizer::iterator const& it, std::string const& value,
bool& is_present)
{
@@ -423,10 +425,21 @@ inline bool initialize(tokenizer const& tokens,
handle_empty_z_m(it, tokens.end(), has_empty, has_z, has_m);
+// Silence warning C4127: conditional expression is constant
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable : 4127)
+#endif
+
if (has_z && dimension<Geometry>::type::value < 3)
{
throw read_wkt_exception("Z only allowed for 3 or more dimensions", wkt);
}
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
if (has_empty)
{
check_end(it, tokens.end(), wkt);
@@ -458,7 +471,101 @@ struct geometry_parser
};
+template <typename MultiGeometry, template<typename> class Parser, typename PrefixPolicy>
+struct multi_parser
+{
+ static inline void apply(std::string const& wkt, MultiGeometry& geometry)
+ {
+ traits::clear<MultiGeometry>::apply(geometry);
+
+ tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+ tokenizer::iterator it;
+ if (initialize<MultiGeometry>(tokens, PrefixPolicy::apply(), wkt, it))
+ {
+ handle_open_parenthesis(it, tokens.end(), wkt);
+
+ // Parse sub-geometries
+ while(it != tokens.end() && *it != ")")
+ {
+ traits::resize<MultiGeometry>::apply(geometry, boost::size(geometry) + 1);
+ Parser
+ <
+ typename boost::range_value<MultiGeometry>::type
+ >::apply(it, tokens.end(), wkt, *(boost::end(geometry) - 1));
+ if (it != tokens.end() && *it == ",")
+ {
+ // Skip "," after multi-element is parsed
+ ++it;
+ }
+ }
+
+ handle_close_parenthesis(it, tokens.end(), wkt);
+ }
+
+ check_end(it, tokens.end(), wkt);
+ }
+};
+
+template <typename P>
+struct noparenthesis_point_parser
+{
+ static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+ std::string const& wkt, P& point)
+ {
+ parsing_assigner<P, 0, dimension<P>::value>::apply(it, end, point, wkt);
+ }
+};
+
+template <typename MultiGeometry, typename PrefixPolicy>
+struct multi_point_parser
+{
+ static inline void apply(std::string const& wkt, MultiGeometry& geometry)
+ {
+ traits::clear<MultiGeometry>::apply(geometry);
+
+ tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+ tokenizer::iterator it;
+ if (initialize<MultiGeometry>(tokens, PrefixPolicy::apply(), wkt, it))
+ {
+ handle_open_parenthesis(it, tokens.end(), wkt);
+
+ // If first point definition starts with "(" then parse points as (x y)
+ // otherwise as "x y"
+ bool using_brackets = (it != tokens.end() && *it == "(");
+
+ while(it != tokens.end() && *it != ")")
+ {
+ traits::resize<MultiGeometry>::apply(geometry, boost::size(geometry) + 1);
+
+ if (using_brackets)
+ {
+ point_parser
+ <
+ typename boost::range_value<MultiGeometry>::type
+ >::apply(it, tokens.end(), wkt, *(boost::end(geometry) - 1));
+ }
+ else
+ {
+ noparenthesis_point_parser
+ <
+ typename boost::range_value<MultiGeometry>::type
+ >::apply(it, tokens.end(), wkt, *(boost::end(geometry) - 1));
+ }
+
+ if (it != tokens.end() && *it == ",")
+ {
+ // Skip "," after point is parsed
+ ++it;
+ }
+ }
+
+ handle_close_parenthesis(it, tokens.end(), wkt);
+ }
+
+ check_end(it, tokens.end(), wkt);
+ }
+};
/*!
@@ -511,7 +618,7 @@ struct box_parser
check_end(it, end, wkt);
int index = 0;
- int n = boost::size(points);
+ std::size_t n = boost::size(points);
if (n == 2)
{
index = 1;
@@ -578,7 +685,6 @@ struct segment_parser
};
-
}} // namespace detail::wkt
#endif // DOXYGEN_NO_DETAIL
@@ -632,6 +738,36 @@ struct read_wkt<polygon_tag, Geometry>
{};
+template <typename MultiGeometry>
+struct read_wkt<multi_point_tag, MultiGeometry>
+ : detail::wkt::multi_point_parser
+ <
+ MultiGeometry,
+ detail::wkt::prefix_multipoint
+ >
+{};
+
+template <typename MultiGeometry>
+struct read_wkt<multi_linestring_tag, MultiGeometry>
+ : detail::wkt::multi_parser
+ <
+ MultiGeometry,
+ detail::wkt::linestring_parser,
+ detail::wkt::prefix_multilinestring
+ >
+{};
+
+template <typename MultiGeometry>
+struct read_wkt<multi_polygon_tag, MultiGeometry>
+ : detail::wkt::multi_parser
+ <
+ MultiGeometry,
+ detail::wkt::polygon_parser,
+ detail::wkt::prefix_multipolygon
+ >
+{};
+
+
// Box (Non-OGC)
template <typename Box>
struct read_wkt<box_tag, Box>
@@ -651,28 +787,11 @@ struct read_wkt<segment_tag, Segment>
/*!
\brief Parses OGC Well-Known Text (\ref WKT) into a geometry (any geometry)
\ingroup wkt
+\tparam Geometry \tparam_geometry
\param wkt string containing \ref WKT
-\param geometry output geometry
-\par Example:
-\note It is case insensitive and can have the WKT forms "point", "point m", "point z", "point zm", "point mz"
-\note Empty sequences can have forms as "LINESTRING ()" or "POLYGON(())"
-Small example showing how to use read_wkt to build a point
-\dontinclude doxygen_1.cpp
-\skip example_from_wkt_point
-\line {
-\until }
-\par Example:
-Small example showing how to use read_wkt to build a linestring
-\dontinclude doxygen_1.cpp
-\skip example_from_wkt_linestring
-\line {
-\until }
-\par Example:
-Small example showing how to use read_wkt to build a polygon
-\dontinclude doxygen_1.cpp
-\skip example_from_wkt_polygon
-\line {
-\until }
+\param geometry \param_geometry output geometry
+\ingroup wkt
+\qbk{[include reference/io/read_wkt.qbk]}
*/
template <typename Geometry>
inline void read_wkt(std::string const& wkt, Geometry& geometry)