mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-11 13:34:10 +00:00
commit
11d627808a
@ -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,92 @@ 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;
|
||||
|
||||
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)
|
||||
{}
|
||||
|
||||
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;
|
||||
}
|
||||
@ -276,7 +337,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 +573,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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -280,7 +280,7 @@ void test_open_rings()
|
||||
test::apply(from_wkt<OG>("POLYGON((0 0,0 0,0 0))"), false);
|
||||
test::apply(from_wkt<OG>("POLYGON((0 0,1 0,1 0))"), false);
|
||||
test::apply(from_wkt<OG>("POLYGON((0 0,1 0,0 0))"), false);
|
||||
test::apply(from_wkt<OG>("POLYGON((0 0,1 0,1 1,0 0))"),
|
||||
test::apply(from_wkt<OG>("POLYGON((0 0,1 0,1 1,0 0,0 0))"),
|
||||
AllowDuplicates);
|
||||
test::apply(from_wkt<OG>("POLYGON((0 0,1 0,1 0,1 1))"),
|
||||
AllowDuplicates);
|
||||
@ -426,7 +426,7 @@ void test_open_polygons()
|
||||
test::apply(from_wkt<OG>("POLYGON((0 0,0 0,0 0))"), false);
|
||||
test::apply(from_wkt<OG>("POLYGON((0 0,1 0,1 0))"), false);
|
||||
test::apply(from_wkt<OG>("POLYGON((0 0,1 0,0 0))"), false);
|
||||
test::apply(from_wkt<OG>("POLYGON((0 0,1 0,1 1,0 0))"), AllowDuplicates);
|
||||
test::apply(from_wkt<OG>("POLYGON((0 0,1 0,1 1,0 0,0 0))"), AllowDuplicates);
|
||||
test::apply(from_wkt<OG>("POLYGON((0 0,1 0,1 0,1 1))"), AllowDuplicates);
|
||||
test::apply(from_wkt<OG>("POLYGON((0 0,1 0,1 0,1 1,0 0))"),
|
||||
AllowDuplicates);
|
||||
@ -438,7 +438,7 @@ void test_open_polygons()
|
||||
false);
|
||||
test::apply(from_wkt<OG>("POLYGON((0 0,10 0,10 10,0 10),(1 1,2 1,1 1))"),
|
||||
false);
|
||||
test::apply(from_wkt<OG>("POLYGON((0 0,10 0,10 10,0 10),(1 1,2 2,2 1,1 1))"),
|
||||
test::apply(from_wkt<OG>("POLYGON((0 0,10 0,10 10,0 10),(1 1,2 2,2 1,1 1,1 1))"),
|
||||
AllowDuplicates);
|
||||
test::apply(from_wkt<OG>("POLYGON((0 0,10 0,10 10,0 10),(1 1,2 2,2 2,2 1))"),
|
||||
AllowDuplicates);
|
||||
|
@ -86,11 +86,11 @@ int test_main(int, char* [])
|
||||
|
||||
// test open geometries
|
||||
test_num_points<open_ring>("POLYGON((0 0,1 1,0 1))", 3u, 4u);
|
||||
test_num_points<open_ring>("POLYGON((0 0,1 1,0 1,0 0))", 4u, 5u);
|
||||
test_num_points<open_ring>("POLYGON((0 0,1 1,0 1,0 0))", 3u, 4u);
|
||||
test_num_points<open_polygon>("POLYGON((0 0,10 10,0 10))", 3u, 4u);
|
||||
test_num_points<open_polygon>("POLYGON((0 0,10 10,0 10,0 0))", 4u, 5u);
|
||||
test_num_points<open_polygon>("POLYGON((0 0,10 10,0 10,0 0))", 3u, 4u);
|
||||
test_num_points<open_multi_polygon>("MULTIPOLYGON(((0 0,0 10,10 10,10 0)),((0 10,1 10,1 9)))", 7u, 9u);
|
||||
test_num_points<open_multi_polygon>("MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)),((0 10,1 10,1 9,0 10)))", 9u, 11u);
|
||||
test_num_points<open_multi_polygon>("MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)),((0 10,1 10,1 9,0 10)))", 7u, 9u);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -88,10 +88,6 @@ void test_ordered_ring(std::string const& wkt_point,
|
||||
{
|
||||
std::reverse(boost::begin(ring), boost::end(ring));
|
||||
}
|
||||
if (! Closed)
|
||||
{
|
||||
ring.resize(ring.size() - 1);
|
||||
}
|
||||
|
||||
bg::read_wkt(wkt_point, point);
|
||||
|
||||
|
@ -5,6 +5,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.
|
||||
|
||||
@ -45,6 +50,33 @@ void test_all();
|
||||
#define GEOMETRY_TEST_MULTI
|
||||
#include "io/wkt/wkt.cpp"
|
||||
|
||||
template <typename T>
|
||||
void test_order_closure()
|
||||
{
|
||||
using namespace boost::geometry;
|
||||
typedef bg::model::point<T, 2, bg::cs::cartesian> Pt;
|
||||
typedef bg::model::polygon<Pt, true, true> PCWC;
|
||||
typedef bg::model::polygon<Pt, true, false> PCWO;
|
||||
typedef bg::model::polygon<Pt, false, true> PCCWC;
|
||||
typedef bg::model::polygon<Pt, false, false> PCCWO;
|
||||
typedef bg::model::multi_polygon<PCWC> MPCWC;
|
||||
typedef bg::model::multi_polygon<PCWO> MPCWO;
|
||||
typedef bg::model::multi_polygon<PCCWC> MPCCWC;
|
||||
typedef bg::model::multi_polygon<PCCWO> MPCCWO;
|
||||
|
||||
std::string wkt_cwc = "MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0)),((0 0,0 -3,-3 -3,-3 0,0 0),(-1 -1,-2 -1,-2 -2,-1 -2,-1 -1)))";
|
||||
std::string wkt_cwo = "MULTIPOLYGON(((0 0,0 2,2 2,2 0)),((0 0,0 -3,-3 -3,-3 0),(-1 -1,-2 -1,-2 -2,-1 -2)))";
|
||||
std::string wkt_ccwc = "MULTIPOLYGON(((0 0,2 0,2 2,0 2,0 0)),((0 0,-3 0,-3 -3,0 -3,0 0),(-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))";
|
||||
std::string wkt_ccwo = "MULTIPOLYGON(((0 0,2 0,2 2,0 2)),((0 0,-3 0,-3 -3,0 -3),(-1 -1,-1 -2,-2 -2,-2 -1)))";
|
||||
|
||||
test_wkt<MPCWC>(wkt_cwc, wkt_cwc, 15, 0, 12, 24);
|
||||
test_wkt<MPCWO>(wkt_cwc, wkt_cwc, 12, 0, 12, 24);
|
||||
test_wkt<MPCWO>(wkt_cwo, wkt_cwc, 12, 0, 12, 24);
|
||||
test_wkt<MPCCWC>(wkt_ccwc, wkt_ccwc, 15, 0, 12, 24);
|
||||
test_wkt<MPCCWO>(wkt_ccwc, wkt_ccwc, 12, 0, 12, 24);
|
||||
test_wkt<MPCCWO>(wkt_ccwo, wkt_ccwc, 12, 0, 12, 24);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_all()
|
||||
{
|
||||
@ -79,6 +111,8 @@ void test_all()
|
||||
test_wrong_wkt<bg::model::multi_point<P> >(
|
||||
"MULTIPOINT(16 17), (18 19)",
|
||||
"too much tokens at ',' in 'multipoint(16 17), (18 19)'");
|
||||
|
||||
test_order_closure<T>();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -5,6 +5,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.
|
||||
|
||||
@ -42,8 +47,8 @@ void check_wkt(G const& geometry, std::string const& expected)
|
||||
}
|
||||
|
||||
template <typename G>
|
||||
void test_wkt(std::string const& wkt, std::size_t n, double len = 0,
|
||||
double ar = 0, double peri = 0)
|
||||
void test_wkt(std::string const& wkt, std::string const& expected,
|
||||
std::size_t n, double len = 0, double ar = 0, double peri = 0)
|
||||
{
|
||||
G geometry;
|
||||
|
||||
@ -67,8 +72,15 @@ void test_wkt(std::string const& wkt, std::size_t n, double len = 0,
|
||||
BOOST_CHECK_CLOSE(double(bg::perimeter(geometry)), peri, 0.0001);
|
||||
}
|
||||
|
||||
check_wkt(geometry, wkt);
|
||||
check_wkt(boost::variant<G>(geometry), wkt);
|
||||
check_wkt(geometry, expected);
|
||||
check_wkt(boost::variant<G>(geometry), expected);
|
||||
}
|
||||
|
||||
template <typename G>
|
||||
void test_wkt(std::string const& wkt,
|
||||
std::size_t n, double len = 0, double ar = 0, double peri = 0)
|
||||
{
|
||||
test_wkt<G>(wkt, wkt, n, len, ar, peri);
|
||||
}
|
||||
|
||||
template <typename G>
|
||||
@ -135,6 +147,44 @@ void test_wkt_output_iterator(std::string const& wkt)
|
||||
|
||||
|
||||
#ifndef GEOMETRY_TEST_MULTI
|
||||
template <typename T>
|
||||
void test_order_closure()
|
||||
{
|
||||
using namespace boost::geometry;
|
||||
typedef bg::model::point<T, 2, bg::cs::cartesian> Pt;
|
||||
typedef bg::model::polygon<Pt, true, true> PCWC;
|
||||
typedef bg::model::polygon<Pt, true, false> PCWO;
|
||||
typedef bg::model::polygon<Pt, false, true> PCCWC;
|
||||
typedef bg::model::polygon<Pt, false, false> PCCWO;
|
||||
|
||||
{
|
||||
std::string wkt_cwc = "POLYGON((0 0,0 2,2 2,2 0,0 0))";
|
||||
std::string wkt_cwo = "POLYGON((0 0,0 2,2 2,2 0))";
|
||||
std::string wkt_ccwc = "POLYGON((0 0,2 0,2 2,0 2,0 0))";
|
||||
std::string wkt_ccwo = "POLYGON((0 0,2 0,2 2,0 2))";
|
||||
|
||||
test_wkt<PCWC>(wkt_cwc, 5, 0, 4, 8);
|
||||
test_wkt<PCWO>(wkt_cwc, 4, 0, 4, 8);
|
||||
test_wkt<PCWO>(wkt_cwo, wkt_cwc, 4, 0, 4, 8);
|
||||
test_wkt<PCCWC>(wkt_ccwc, 5, 0, 4, 8);
|
||||
test_wkt<PCCWO>(wkt_ccwc, 4, 0, 4, 8);
|
||||
test_wkt<PCCWO>(wkt_ccwo, wkt_ccwc, 4, 0, 4, 8);
|
||||
}
|
||||
{
|
||||
std::string wkt_cwc = "POLYGON((0 0,0 3,3 3,3 0,0 0),(1 1,2 1,2 2,1 2,1 1))";
|
||||
std::string wkt_cwo = "POLYGON((0 0,0 3,3 3,3 0),(1 1,2 1,2 2,1 2))";
|
||||
std::string wkt_ccwc = "POLYGON((0 0,3 0,3 3,0 3,0 0),(1 1,1 2,2 2,2 1,1 1))";
|
||||
std::string wkt_ccwo = "POLYGON((0 0,3 0,3 3,0 3),(1 1,1 2,2 2,2 1,1 1))";
|
||||
|
||||
test_wkt<PCWC>(wkt_cwc, 10, 0, 8, 16);
|
||||
test_wkt<PCWO>(wkt_cwc, 8, 0, 8, 16);
|
||||
test_wkt<PCWO>(wkt_cwo, wkt_cwc, 8, 0, 8, 16);
|
||||
test_wkt<PCCWC>(wkt_ccwc, 10, 0, 8, 16);
|
||||
test_wkt<PCCWO>(wkt_ccwc, 8, 0, 8, 16);
|
||||
test_wkt<PCCWO>(wkt_ccwo, wkt_ccwc, 8, 0, 8, 16);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_all()
|
||||
{
|
||||
@ -201,10 +251,11 @@ void test_all()
|
||||
// Deprecated:
|
||||
// test_wkt_output_iterator<bg::model::linestring<P> >("LINESTRING(1 1,2 2,3 3)");
|
||||
// test_wkt_output_iterator<bg::model::ring<P> >("POLYGON((1 1,2 2,3 3))");
|
||||
|
||||
test_order_closure<T>();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int test_main(int, char* [])
|
||||
{
|
||||
test_all<double>();
|
||||
|
Loading…
x
Reference in New Issue
Block a user