diff options
Diffstat (limited to 'boost/geometry/io/wkt/read.hpp')
-rw-r--r-- | boost/geometry/io/wkt/read.hpp | 115 |
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) { |