Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/geometry/io/wkt/read.hpp @ 101:c530137014c0
Update Boost headers (1.58.0)
author | Chris Cannam |
---|---|
date | Mon, 07 Sep 2015 11:12:49 +0100 |
parents | 2665513ce2d3 |
children |
line wrap: on
line diff
--- a/DEPENDENCIES/generic/include/boost/geometry/io/wkt/read.hpp Fri Sep 04 12:01:02 2015 +0100 +++ b/DEPENDENCIES/generic/include/boost/geometry/io/wkt/read.hpp Mon Sep 07 11:12:49 2015 +0100 @@ -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. @@ -14,6 +19,7 @@ #ifndef BOOST_GEOMETRY_IO_WKT_READ_HPP #define BOOST_GEOMETRY_IO_WKT_READ_HPP +#include <cstddef> #include <string> #include <boost/lexical_cast.hpp> @@ -28,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> @@ -36,6 +43,9 @@ #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/tag_cast.hpp> +#include <boost/geometry/core/tags.hpp> #include <boost/geometry/geometries/concepts/check.hpp> @@ -95,7 +105,9 @@ 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, @@ -205,12 +217,7 @@ 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 == ",") @@ -224,35 +231,94 @@ }; +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); + point_type point; - geometry::append(out, point); - if (it != end && *it == ",") + 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; } @@ -273,7 +339,7 @@ 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); } }; @@ -306,8 +372,6 @@ }; - - /*! \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 +422,7 @@ } }; + inline bool one_of(tokenizer::iterator const& it, std::string const& value, bool& is_present) { @@ -469,7 +534,101 @@ }; +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>::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); + } +}; /*! @@ -521,8 +680,8 @@ } check_end(it, end, wkt); - int index = 0; - int n = boost::size(points); + unsigned int index = 0; + std::size_t n = boost::size(points); if (n == 2) { index = 1; @@ -589,7 +748,6 @@ }; - }} // namespace detail::wkt #endif // DOXYGEN_NO_DETAIL @@ -643,6 +801,36 @@ {}; +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> @@ -662,28 +850,11 @@ /*! \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)