From 2278e697d02fbcae0a88a655ec9cb4958272b7ea Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Tue, 14 Oct 2014 01:34:39 +0200 Subject: [PATCH] [read_wkt] Don't append duplicated, closing Points in open Rings/Polygons. Note that Points are still appended if there is not enough Points in the input, i.e. the number is < 3 for open Rings. --- include/boost/geometry/io/wkt/read.hpp | 57 ++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/include/boost/geometry/io/wkt/read.hpp b/include/boost/geometry/io/wkt/read.hpp index 748eecdbe..62e7febbc 100644 --- a/include/boost/geometry/io/wkt/read.hpp +++ b/include/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 #include #include +#include #include #include @@ -231,18 +237,18 @@ struct container_inserter template struct container_appender { - typedef typename geometry::point_type - < - typename boost::remove_reference::type - >::type point_type; + typedef typename boost::remove_reference::type bare_geometry; + typedef typename geometry::point_type::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; - + point_type first_point; + typename boost::range_size::type pt_index = 0; + // Parse points until closing parenthesis while (it != end && *it != ")") @@ -254,8 +260,43 @@ struct container_appender dimension::value >::apply(it, end, point, wkt); - geometry::append(out, point); - if (it != end && *it == ",") + bool should_append = true; + bool const is_next_expected = it != end && *it == ","; + + if ( closure::value == open ) + { + // sanity check - only Rings, Polygons and MultiPolygons may be open + // this is important for the minimum_ring_size condition + BOOST_STATIC_ASSERT(( closure::value != open + || boost::is_same::type, + areal_tag + >::type, areal_tag>::value + )); + + 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::value + || !detail::equals::equals_point_point(point, first_point); + } + ++pt_index; + } + + if ( should_append ) + { + geometry::append(out, point); + } + + if ( is_next_expected ) { ++it; }