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.hpp115
1 files changed, 89 insertions, 26 deletions
diff --git a/boost/geometry/io/wkt/read.hpp b/boost/geometry/io/wkt/read.hpp
index 748eecdbe6..2415f21a69 100644
--- a/boost/geometry/io/wkt/read.hpp
+++ b/boost/geometry/io/wkt/read.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -29,6 +34,7 @@
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/append.hpp>
#include <boost/geometry/algorithms/clear.hpp>
+#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
@@ -38,6 +44,7 @@
#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/tag_cast.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
@@ -98,7 +105,9 @@ namespace detail { namespace wkt
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
-template <typename Point, std::size_t Dimension, std::size_t DimensionCount>
+template <typename Point,
+ std::size_t Dimension = 0,
+ std::size_t DimensionCount = geometry::dimension<Point>::value>
struct parsing_assigner
{
static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
@@ -208,12 +217,7 @@ struct container_inserter
while (it != end && *it != ")")
{
- parsing_assigner
- <
- Point,
- 0,
- dimension<Point>::value
- >::apply(it, end, point, wkt);
+ parsing_assigner<Point>::apply(it, end, point, wkt);
out = point;
++out;
if (it != end && *it == ",")
@@ -227,35 +231,94 @@ struct container_inserter
};
+template <typename Geometry,
+ closure_selector Closure = closure<Geometry>::value>
+struct stateful_range_appender
+{
+ typedef typename geometry::point_type<Geometry>::type point_type;
+
+ // NOTE: Geometry is a reference
+ inline void append(Geometry geom, point_type const& point, bool)
+ {
+ geometry::append(geom, point);
+ }
+};
+
+template <typename Geometry>
+struct stateful_range_appender<Geometry, open>
+{
+ typedef typename geometry::point_type<Geometry>::type point_type;
+ typedef typename boost::range_size
+ <
+ typename util::bare_type<Geometry>::type
+ >::type size_type;
+
+ BOOST_STATIC_ASSERT(( boost::is_same
+ <
+ typename tag<Geometry>::type,
+ ring_tag
+ >::value ));
+
+ inline stateful_range_appender()
+ : pt_index(0)
+ {}
+
+ // NOTE: Geometry is a reference
+ inline void append(Geometry geom, point_type const& point, bool is_next_expected)
+ {
+ bool should_append = true;
+
+ if (pt_index == 0)
+ {
+ first_point = point;
+ //should_append = true;
+ }
+ else
+ {
+ // NOTE: if there is not enough Points, they're always appended
+ should_append
+ = is_next_expected
+ || pt_index < core_detail::closure::minimum_ring_size<open>::value
+ || !detail::equals::equals_point_point(point, first_point);
+ }
+ ++pt_index;
+
+ if (should_append)
+ {
+ geometry::append(geom, point);
+ }
+ }
+
+private:
+ size_type pt_index;
+ point_type first_point;
+};
+
// Geometry is a value-type or reference-type
template <typename Geometry>
struct container_appender
{
- typedef typename geometry::point_type
- <
- typename boost::remove_reference<Geometry>::type
- >::type point_type;
+ typedef typename geometry::point_type<Geometry>::type point_type;
static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
- std::string const& wkt, Geometry out)
+ std::string const& wkt, Geometry out)
{
handle_open_parenthesis(it, end, wkt);
- point_type point;
+ stateful_range_appender<Geometry> appender;
// Parse points until closing parenthesis
-
while (it != end && *it != ")")
{
- parsing_assigner
- <
- point_type,
- 0,
- dimension<point_type>::value
- >::apply(it, end, point, wkt);
-
- geometry::append(out, point);
- if (it != end && *it == ",")
+ point_type point;
+
+ parsing_assigner<point_type>::apply(it, end, point, wkt);
+
+ bool const is_next_expected = it != end && *it == ",";
+
+ appender.append(out, point, is_next_expected);
+
+ if (is_next_expected)
{
++it;
}
@@ -276,7 +339,7 @@ struct point_parser
std::string const& wkt, P& point)
{
handle_open_parenthesis(it, end, wkt);
- parsing_assigner<P, 0, dimension<P>::value>::apply(it, end, point, wkt);
+ parsing_assigner<P>::apply(it, end, point, wkt);
handle_close_parenthesis(it, end, wkt);
}
};
@@ -512,7 +575,7 @@ 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);
+ parsing_assigner<P>::apply(it, end, point, wkt);
}
};
@@ -617,7 +680,7 @@ struct box_parser
}
check_end(it, end, wkt);
- int index = 0;
+ unsigned int index = 0;
std::size_t n = boost::size(points);
if (n == 2)
{