mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-09 23:24:02 +00:00
[wkt] support tabs, newlines and code cleanup
This commit is contained in:
parent
6a7224e369
commit
f92671b933
@ -1,7 +1,7 @@
|
||||
[/============================================================================
|
||||
Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
Copyright (c) 2009-2022 Barend Gehrels, Geodan, Amsterdam, the Netherlands.
|
||||
Copyright (c) 2009-2023 Barend Gehrels, Geodan, Amsterdam, the Netherlands.
|
||||
Copyright (c) 2009-2017 Bruno Lalande, Paris, France.
|
||||
Copyright (c) 2009-2017 Mateusz Loskot <mateusz@loskot.net>, London, UK.
|
||||
Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
|
||||
@ -19,6 +19,22 @@
|
||||
|
||||
[section:release_notes Release Notes]
|
||||
|
||||
[/=================]
|
||||
[heading Boost 1.82]
|
||||
[/=================]
|
||||
|
||||
[*Major improvements]
|
||||
|
||||
* [@https://github.com/boostorg/geometry/pull/1045 1045] Support geographic buffer for (multi)linestrings and (multi)polygons
|
||||
|
||||
[*Solved issues]
|
||||
|
||||
* [@https://github.com/boostorg/geometry/issues/705 705] WKT: allow tabs and new lines
|
||||
|
||||
[*Breaking changes]
|
||||
|
||||
* The WKT output presentation of an empty polygon is now POLYGON() to make it consistent with other geometries
|
||||
|
||||
[/=================]
|
||||
[heading Boost 1.81]
|
||||
[/=================]
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2007-2022 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
|
||||
@ -57,6 +57,20 @@ struct prefix_multipolygon
|
||||
static inline const char* apply() { return "MULTIPOLYGON"; }
|
||||
};
|
||||
|
||||
struct prefix_segment
|
||||
{
|
||||
static inline const char* apply() { return "SEGMENT"; }
|
||||
};
|
||||
struct prefix_box
|
||||
{
|
||||
static inline const char* apply() { return "BOX"; }
|
||||
};
|
||||
struct prefix_geometrycollection
|
||||
{
|
||||
static inline const char* apply() { return "GEOMETRYCOLLECTION"; }
|
||||
};
|
||||
|
||||
|
||||
}} // namespace wkt::impl
|
||||
#endif
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2007-2022 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
|
||||
@ -11,46 +11,13 @@
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_DETAIL_WKT_MULTI_HPP
|
||||
#define BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_DETAIL_WKT_MULTI_HPP
|
||||
#ifndef BOOST_GEOMETRY_IO_WKT_MULTI_HPP
|
||||
#define BOOST_GEOMETRY_IO_WKT_MULTI_HPP
|
||||
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/domains/gis/io/wkt/write.hpp>
|
||||
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.")
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace wkt
|
||||
{
|
||||
|
||||
struct prefix_null
|
||||
{
|
||||
static inline const char* apply() { return ""; }
|
||||
};
|
||||
|
||||
struct prefix_multipoint
|
||||
{
|
||||
static inline const char* apply() { return "MULTIPOINT"; }
|
||||
};
|
||||
|
||||
struct prefix_multilinestring
|
||||
{
|
||||
static inline const char* apply() { return "MULTILINESTRING"; }
|
||||
};
|
||||
|
||||
struct prefix_multipolygon
|
||||
{
|
||||
static inline const char* apply() { return "MULTIPOLYGON"; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
}} // namespace wkt::impl
|
||||
#endif
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_DETAIL_WKT_MULTI_HPP
|
||||
#endif // BOOST_GEOMETRY_IO_WKT_MULTI_HPP
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2007-2022 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
|
||||
@ -117,19 +117,26 @@ private :
|
||||
namespace detail { namespace wkt
|
||||
{
|
||||
|
||||
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
|
||||
inline auto make_tokenizer(std::string const& wkt)
|
||||
{
|
||||
using separator = boost::char_separator<char>;
|
||||
using tokenizer = boost::tokenizer<separator>;
|
||||
const tokenizer tokens(wkt, separator(" \n\t\r", ",()"));
|
||||
return tokens;
|
||||
}
|
||||
|
||||
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 const& end,
|
||||
template <typename TokenizerIterator>
|
||||
static inline void apply(TokenizerIterator& it,
|
||||
TokenizerIterator const& end,
|
||||
Point& point,
|
||||
std::string const& wkt)
|
||||
{
|
||||
typedef typename coordinate_type<Point>::type coordinate_type;
|
||||
using coordinate_type = typename coordinate_type<Point>::type;
|
||||
|
||||
// Stop at end of tokens, or at "," ot ")"
|
||||
bool finished = (it == end || *it == "," || *it == ")");
|
||||
@ -167,8 +174,9 @@ struct parsing_assigner
|
||||
template <typename Point, std::size_t DimensionCount>
|
||||
struct parsing_assigner<Point, DimensionCount, DimensionCount>
|
||||
{
|
||||
static inline void apply(tokenizer::iterator&,
|
||||
tokenizer::iterator const&,
|
||||
template <typename TokenizerIterator>
|
||||
static inline void apply(TokenizerIterator&,
|
||||
TokenizerIterator const&,
|
||||
Point&,
|
||||
std::string const&)
|
||||
{
|
||||
@ -226,9 +234,9 @@ template <typename Point>
|
||||
struct container_inserter
|
||||
{
|
||||
// Version with output iterator
|
||||
template <typename OutputIterator>
|
||||
static inline void apply(tokenizer::iterator& it,
|
||||
tokenizer::iterator const& end,
|
||||
template <typename TokenizerIterator, typename OutputIterator>
|
||||
static inline void apply(TokenizerIterator& it,
|
||||
TokenizerIterator const& end,
|
||||
std::string const& wkt,
|
||||
OutputIterator out)
|
||||
{
|
||||
@ -258,10 +266,8 @@ 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)
|
||||
inline void append(Geometry geom, typename geometry::point_type<Geometry>::type const& point, bool)
|
||||
{
|
||||
geometry::append(geom, point);
|
||||
}
|
||||
@ -270,13 +276,13 @@ struct stateful_range_appender
|
||||
template <typename Geometry>
|
||||
struct stateful_range_appender<Geometry, open>
|
||||
{
|
||||
typedef typename geometry::point_type<Geometry>::type point_type;
|
||||
typedef typename boost::range_size
|
||||
using point_type = typename geometry::point_type<Geometry>::type;
|
||||
using size_type = typename boost::range_size
|
||||
<
|
||||
typename util::remove_cptrref<Geometry>::type
|
||||
>::type size_type;
|
||||
>::type;
|
||||
|
||||
BOOST_STATIC_ASSERT(( util::is_ring<Geometry>::value ));
|
||||
BOOST_STATIC_ASSERT((util::is_ring<Geometry>::value));
|
||||
|
||||
inline stateful_range_appender()
|
||||
: pt_index(0)
|
||||
@ -290,11 +296,10 @@ struct stateful_range_appender<Geometry, open>
|
||||
if (pt_index == 0)
|
||||
{
|
||||
first_point = point;
|
||||
//should_append = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: if there is not enough Points, they're always appended
|
||||
// NOTE: if there are not enough Points, they're always appended
|
||||
should_append
|
||||
= is_next_expected
|
||||
|| pt_index < core_detail::closure::minimum_ring_size<open>::value
|
||||
@ -312,10 +317,10 @@ private:
|
||||
static inline bool disjoint(point_type const& p1, point_type const& p2)
|
||||
{
|
||||
// TODO: pass strategy
|
||||
typedef typename strategies::io::services::default_strategy
|
||||
using strategy_type = typename strategies::io::services::default_strategy
|
||||
<
|
||||
point_type
|
||||
>::type strategy_type;
|
||||
>::type;
|
||||
|
||||
return detail::disjoint::disjoint_point_point(p1, p2, strategy_type());
|
||||
}
|
||||
@ -328,10 +333,11 @@ private:
|
||||
template <typename Geometry>
|
||||
struct container_appender
|
||||
{
|
||||
typedef typename geometry::point_type<Geometry>::type point_type;
|
||||
using point_type = typename geometry::point_type<Geometry>::type;
|
||||
|
||||
static inline void apply(tokenizer::iterator& it,
|
||||
tokenizer::iterator const& end,
|
||||
template <typename TokenizerIterator>
|
||||
static inline void apply(TokenizerIterator& it,
|
||||
TokenizerIterator const& end,
|
||||
std::string const& wkt,
|
||||
Geometry out)
|
||||
{
|
||||
@ -367,8 +373,9 @@ struct container_appender
|
||||
template <typename P>
|
||||
struct point_parser
|
||||
{
|
||||
static inline void apply(tokenizer::iterator& it,
|
||||
tokenizer::iterator const& end,
|
||||
template <typename TokenizerIterator>
|
||||
static inline void apply(TokenizerIterator& it,
|
||||
TokenizerIterator const& end,
|
||||
std::string const& wkt,
|
||||
P& point)
|
||||
{
|
||||
@ -382,8 +389,9 @@ struct point_parser
|
||||
template <typename Geometry>
|
||||
struct linestring_parser
|
||||
{
|
||||
static inline void apply(tokenizer::iterator& it,
|
||||
tokenizer::iterator const& end,
|
||||
template <typename TokenizerIterator>
|
||||
static inline void apply(TokenizerIterator& it,
|
||||
TokenizerIterator const& end,
|
||||
std::string const& wkt,
|
||||
Geometry& geometry)
|
||||
{
|
||||
@ -395,8 +403,9 @@ struct linestring_parser
|
||||
template <typename Ring>
|
||||
struct ring_parser
|
||||
{
|
||||
static inline void apply(tokenizer::iterator& it,
|
||||
tokenizer::iterator const& end,
|
||||
template <typename TokenizerIterator>
|
||||
static inline void apply(TokenizerIterator& it,
|
||||
TokenizerIterator const& end,
|
||||
std::string const& wkt,
|
||||
Ring& ring)
|
||||
{
|
||||
@ -417,11 +426,12 @@ struct ring_parser
|
||||
template <typename Polygon>
|
||||
struct polygon_parser
|
||||
{
|
||||
typedef typename ring_return_type<Polygon>::type ring_return_type;
|
||||
typedef container_appender<ring_return_type> appender;
|
||||
using ring_return_type = typename ring_return_type<Polygon>::type;
|
||||
using appender = container_appender<ring_return_type>;
|
||||
|
||||
static inline void apply(tokenizer::iterator& it,
|
||||
tokenizer::iterator const& end,
|
||||
template <typename TokenizerIterator>
|
||||
static inline void apply(TokenizerIterator& it,
|
||||
TokenizerIterator const& end,
|
||||
std::string const& wkt,
|
||||
Polygon& poly)
|
||||
{
|
||||
@ -457,7 +467,8 @@ struct polygon_parser
|
||||
};
|
||||
|
||||
|
||||
inline bool one_of(tokenizer::iterator const& it,
|
||||
template <typename TokenizerIterator>
|
||||
inline bool one_of(TokenizerIterator const& it,
|
||||
std::string const& value,
|
||||
bool& is_present)
|
||||
{
|
||||
@ -469,7 +480,8 @@ inline bool one_of(tokenizer::iterator const& it,
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool one_of(tokenizer::iterator const& it,
|
||||
template <typename TokenizerIterator>
|
||||
inline bool one_of(TokenizerIterator const& it,
|
||||
std::string const& value,
|
||||
bool& present1,
|
||||
bool& present2)
|
||||
@ -484,8 +496,9 @@ inline bool one_of(tokenizer::iterator const& it,
|
||||
}
|
||||
|
||||
|
||||
inline void handle_empty_z_m(tokenizer::iterator& it,
|
||||
tokenizer::iterator const& end,
|
||||
template <typename TokenizerIterator>
|
||||
inline void handle_empty_z_m(TokenizerIterator& it,
|
||||
TokenizerIterator const& end,
|
||||
bool& has_empty,
|
||||
bool& has_z,
|
||||
bool& has_m)
|
||||
@ -535,9 +548,9 @@ struct dimension<Geometry, geometry_collection_tag>
|
||||
\brief Internal, starts parsing
|
||||
\param geometry_name string to compare with first token
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline bool initialize(tokenizer::iterator& it,
|
||||
tokenizer::iterator const& end,
|
||||
template <typename Geometry, typename TokenizerIterator>
|
||||
inline bool initialize(TokenizerIterator& it,
|
||||
TokenizerIterator const& end,
|
||||
std::string const& wkt,
|
||||
std::string const& geometry_name)
|
||||
{
|
||||
@ -552,8 +565,8 @@ inline bool initialize(tokenizer::iterator& it,
|
||||
|
||||
// Silence warning C4127: conditional expression is constant
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4127)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4127)
|
||||
#endif
|
||||
|
||||
if (has_z && dimension<Geometry>::value < 3)
|
||||
@ -570,7 +583,7 @@ inline bool initialize(tokenizer::iterator& it,
|
||||
return false;
|
||||
}
|
||||
// M is ignored at all.
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -582,17 +595,18 @@ struct geometry_parser
|
||||
{
|
||||
geometry::clear(geometry);
|
||||
|
||||
tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
|
||||
tokenizer::iterator it = tokens.begin();
|
||||
tokenizer::iterator const end = tokens.end();
|
||||
auto const tokens{make_tokenizer(wkt)};
|
||||
auto it = tokens.begin();
|
||||
auto const end = tokens.end();
|
||||
|
||||
apply(it, end, wkt, geometry);
|
||||
|
||||
check_end(it, end, wkt);
|
||||
}
|
||||
|
||||
static inline void apply(tokenizer::iterator& it,
|
||||
tokenizer::iterator const& end,
|
||||
template <typename TokenizerIterator>
|
||||
static inline void apply(TokenizerIterator& it,
|
||||
TokenizerIterator const& end,
|
||||
std::string const& wkt,
|
||||
Geometry& geometry)
|
||||
{
|
||||
@ -611,17 +625,18 @@ struct multi_parser
|
||||
{
|
||||
traits::clear<MultiGeometry>::apply(geometry);
|
||||
|
||||
tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
|
||||
tokenizer::iterator it = tokens.begin();
|
||||
tokenizer::iterator const end = tokens.end();
|
||||
auto const tokens{make_tokenizer(wkt)};
|
||||
auto it = tokens.begin();
|
||||
auto const end = tokens.end();
|
||||
|
||||
apply(it, end, wkt, geometry);
|
||||
|
||||
check_end(it, end, wkt);
|
||||
}
|
||||
|
||||
static inline void apply(tokenizer::iterator& it,
|
||||
tokenizer::iterator const& end,
|
||||
template <typename TokenizerIterator>
|
||||
static inline void apply(TokenizerIterator& it,
|
||||
TokenizerIterator const& end,
|
||||
std::string const& wkt,
|
||||
MultiGeometry& geometry)
|
||||
{
|
||||
@ -652,8 +667,9 @@ struct multi_parser
|
||||
template <typename P>
|
||||
struct noparenthesis_point_parser
|
||||
{
|
||||
static inline void apply(tokenizer::iterator& it,
|
||||
tokenizer::iterator const& end,
|
||||
template <typename TokenizerIterator>
|
||||
static inline void apply(TokenizerIterator& it,
|
||||
TokenizerIterator const& end,
|
||||
std::string const& wkt,
|
||||
P& point)
|
||||
{
|
||||
@ -668,17 +684,18 @@ struct multi_point_parser
|
||||
{
|
||||
traits::clear<MultiGeometry>::apply(geometry);
|
||||
|
||||
tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
|
||||
tokenizer::iterator it = tokens.begin();
|
||||
tokenizer::iterator const end = tokens.end();
|
||||
auto const tokens{make_tokenizer(wkt)};
|
||||
auto it = tokens.begin();
|
||||
auto const end = tokens.end();
|
||||
|
||||
apply(it, end, wkt, geometry);
|
||||
|
||||
check_end(it, end, wkt);
|
||||
}
|
||||
|
||||
static inline void apply(tokenizer::iterator& it,
|
||||
tokenizer::iterator const& end,
|
||||
template <typename TokenizerIterator>
|
||||
static inline void apply(TokenizerIterator& it,
|
||||
TokenizerIterator const& end,
|
||||
std::string const& wkt,
|
||||
MultiGeometry& geometry)
|
||||
{
|
||||
@ -735,17 +752,18 @@ struct box_parser
|
||||
{
|
||||
static inline void apply(std::string const& wkt, Box& box)
|
||||
{
|
||||
tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
|
||||
tokenizer::iterator it = tokens.begin();
|
||||
tokenizer::iterator end = tokens.end();
|
||||
auto const tokens{make_tokenizer(wkt)};
|
||||
auto it = tokens.begin();
|
||||
auto end = tokens.end();
|
||||
|
||||
apply(it, end, wkt, box);
|
||||
|
||||
check_end(it, end, wkt);
|
||||
}
|
||||
|
||||
static inline void apply(tokenizer::iterator& it,
|
||||
tokenizer::iterator const& end,
|
||||
template <typename TokenizerIterator>
|
||||
static inline void apply(TokenizerIterator& it,
|
||||
TokenizerIterator const& end,
|
||||
std::string const& wkt,
|
||||
Box& box)
|
||||
{
|
||||
@ -772,7 +790,7 @@ struct box_parser
|
||||
BOOST_THROW_EXCEPTION(read_wkt_exception("Should start with 'POLYGON' or 'BOX'", wkt));
|
||||
}
|
||||
|
||||
typedef typename point_type<Box>::type point_type;
|
||||
using point_type = typename point_type<Box>::type;
|
||||
std::vector<point_type> points;
|
||||
container_inserter<point_type>::apply(it, end, wkt, std::back_inserter(points));
|
||||
|
||||
@ -815,21 +833,24 @@ struct segment_parser
|
||||
{
|
||||
static inline void apply(std::string const& wkt, Segment& segment)
|
||||
{
|
||||
tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
|
||||
tokenizer::iterator it = tokens.begin();
|
||||
tokenizer::iterator end = tokens.end();
|
||||
auto const tokens{make_tokenizer(wkt)};
|
||||
auto it = tokens.begin();
|
||||
auto end = tokens.end();
|
||||
|
||||
apply(it, end, wkt, segment);
|
||||
|
||||
check_end(it, end, wkt);
|
||||
}
|
||||
|
||||
static inline void apply(tokenizer::iterator& it,
|
||||
tokenizer::iterator const& end,
|
||||
template <typename TokenizerIterator>
|
||||
static inline void apply(TokenizerIterator& it,
|
||||
TokenizerIterator const& end,
|
||||
std::string const& wkt,
|
||||
Segment& segment)
|
||||
{
|
||||
if (it != end && (boost::iequals(*it, "SEGMENT") || boost::iequals(*it, "LINESTRING")))
|
||||
if (it != end
|
||||
&& (boost::iequals(*it, prefix_segment::apply())
|
||||
|| boost::iequals(*it, prefix_linestring::apply())))
|
||||
{
|
||||
++it;
|
||||
}
|
||||
@ -838,7 +859,7 @@ struct segment_parser
|
||||
BOOST_THROW_EXCEPTION(read_wkt_exception("Should start with 'LINESTRING' or 'SEGMENT'", wkt));
|
||||
}
|
||||
|
||||
typedef typename point_type<Segment>::type point_type;
|
||||
using point_type = typename point_type<Segment>::type;
|
||||
std::vector<point_type> points;
|
||||
container_inserter<point_type>::apply(it, end, wkt, std::back_inserter(points));
|
||||
|
||||
@ -881,54 +902,67 @@ template
|
||||
>
|
||||
struct dynamic_readwkt_caller
|
||||
{
|
||||
static inline void apply(tokenizer::iterator& it,
|
||||
tokenizer::iterator const& end,
|
||||
template <typename TokenizerIterator>
|
||||
static inline void apply(TokenizerIterator& it,
|
||||
TokenizerIterator const& end,
|
||||
std::string const& wkt,
|
||||
Geometry& geometry)
|
||||
{
|
||||
if (boost::iequals(*it, "POINT"))
|
||||
static const char* tag_point = prefix_point::apply();
|
||||
static const char* tag_linestring = prefix_linestring::apply();
|
||||
static const char* tag_polygon = prefix_polygon::apply();
|
||||
|
||||
static const char* tag_multi_point = prefix_multipoint::apply();
|
||||
static const char* tag_multi_linestring = prefix_multilinestring::apply();
|
||||
static const char* tag_multi_polygon = prefix_multipolygon::apply();
|
||||
|
||||
static const char* tag_segment = prefix_segment::apply();
|
||||
static const char* tag_box = prefix_box::apply();
|
||||
static const char* tag_gc = prefix_geometrycollection::apply();
|
||||
|
||||
if (boost::iequals(*it, tag_point))
|
||||
{
|
||||
parse_geometry<util::is_point>("POINT", it, end, wkt, geometry);
|
||||
parse_geometry<util::is_point>(tag_point, it, end, wkt, geometry);
|
||||
}
|
||||
else if (boost::iequals(*it, "MULTIPOINT"))
|
||||
else if (boost::iequals(*it, tag_multi_point))
|
||||
{
|
||||
parse_geometry<util::is_multi_point>("MULTIPOINT", it, end, wkt, geometry);
|
||||
parse_geometry<util::is_multi_point>(tag_multi_point, it, end, wkt, geometry);
|
||||
}
|
||||
else if (boost::iequals(*it, "SEGMENT"))
|
||||
else if (boost::iequals(*it, tag_segment))
|
||||
{
|
||||
parse_geometry<util::is_segment>("SEGMENT", it, end, wkt, geometry);
|
||||
parse_geometry<util::is_segment>(tag_segment, it, end, wkt, geometry);
|
||||
}
|
||||
else if (boost::iequals(*it, "LINESTRING"))
|
||||
else if (boost::iequals(*it, tag_linestring))
|
||||
{
|
||||
parse_geometry<util::is_linestring>("LINESTRING", it, end, wkt, geometry, false)
|
||||
|| parse_geometry<util::is_segment>("LINESTRING", it, end, wkt, geometry);
|
||||
parse_geometry<util::is_linestring>(tag_linestring, it, end, wkt, geometry, false)
|
||||
|| parse_geometry<util::is_segment>(tag_linestring, it, end, wkt, geometry);
|
||||
}
|
||||
else if (boost::iequals(*it, "MULTILINESTRING"))
|
||||
else if (boost::iequals(*it, tag_multi_linestring))
|
||||
{
|
||||
parse_geometry<util::is_multi_linestring>("MULTILINESTRING", it, end, wkt, geometry);
|
||||
parse_geometry<util::is_multi_linestring>(tag_multi_linestring, it, end, wkt, geometry);
|
||||
}
|
||||
else if (boost::iequals(*it, "BOX"))
|
||||
else if (boost::iequals(*it, tag_box))
|
||||
{
|
||||
parse_geometry<util::is_box>("BOX", it, end, wkt, geometry);
|
||||
parse_geometry<util::is_box>(tag_box, it, end, wkt, geometry);
|
||||
}
|
||||
else if (boost::iequals(*it, "POLYGON"))
|
||||
else if (boost::iequals(*it, tag_polygon))
|
||||
{
|
||||
parse_geometry<util::is_polygon>("POLYGON", it, end, wkt, geometry, false)
|
||||
|| parse_geometry<util::is_ring>("POLYGON", it, end, wkt, geometry, false)
|
||||
|| parse_geometry<util::is_box>("POLYGON", it, end, wkt, geometry);
|
||||
parse_geometry<util::is_polygon>(tag_polygon, it, end, wkt, geometry, false)
|
||||
|| parse_geometry<util::is_ring>(tag_polygon, it, end, wkt, geometry, false)
|
||||
|| parse_geometry<util::is_box>(tag_polygon, it, end, wkt, geometry);
|
||||
}
|
||||
else if (boost::iequals(*it, "MULTIPOLYGON"))
|
||||
else if (boost::iequals(*it, tag_multi_polygon))
|
||||
{
|
||||
parse_geometry<util::is_multi_polygon>("MULTIPOLYGON", it, end, wkt, geometry);
|
||||
parse_geometry<util::is_multi_polygon>(tag_multi_polygon, it, end, wkt, geometry);
|
||||
}
|
||||
else if (boost::iequals(*it, "GEOMETRYCOLLECTION"))
|
||||
else if (boost::iequals(*it, tag_gc))
|
||||
{
|
||||
parse_geometry<util::is_geometry_collection>("GEOMETRYCOLLECTION", it, end, wkt, geometry);
|
||||
parse_geometry<util::is_geometry_collection>(tag_gc, it, end, wkt, geometry);
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_THROW_EXCEPTION(read_wkt_exception(
|
||||
"Should start with geometry's name, e.g. 'POINT', 'LINESTRING', 'POLYGON', etc.",
|
||||
"Should start with geometry's type, for example 'POINT', 'LINESTRING', 'POLYGON'",
|
||||
wkt));
|
||||
}
|
||||
}
|
||||
@ -937,6 +971,7 @@ private:
|
||||
template
|
||||
<
|
||||
template <typename> class UnaryPred,
|
||||
typename TokenizerIterator,
|
||||
typename Geom = typename util::sequence_find_if
|
||||
<
|
||||
typename traits::geometry_types<Geometry>::type, UnaryPred
|
||||
@ -944,8 +979,8 @@ private:
|
||||
std::enable_if_t<! std::is_void<Geom>::value, int> = 0
|
||||
>
|
||||
static bool parse_geometry(const char * ,
|
||||
tokenizer::iterator& it,
|
||||
tokenizer::iterator const& end,
|
||||
TokenizerIterator& it,
|
||||
TokenizerIterator const& end,
|
||||
std::string const& wkt,
|
||||
Geometry& geometry,
|
||||
bool = true)
|
||||
@ -959,6 +994,7 @@ private:
|
||||
template
|
||||
<
|
||||
template <typename> class UnaryPred,
|
||||
typename TokenizerIterator,
|
||||
typename Geom = typename util::sequence_find_if
|
||||
<
|
||||
typename traits::geometry_types<Geometry>::type, UnaryPred
|
||||
@ -966,8 +1002,8 @@ private:
|
||||
std::enable_if_t<std::is_void<Geom>::value, int> = 0
|
||||
>
|
||||
static bool parse_geometry(const char * name,
|
||||
tokenizer::iterator& ,
|
||||
tokenizer::iterator const& ,
|
||||
TokenizerIterator& ,
|
||||
TokenizerIterator const& ,
|
||||
std::string const& wkt,
|
||||
Geometry& ,
|
||||
bool throw_on_misfit = true)
|
||||
@ -1084,13 +1120,13 @@ struct read_wkt<DynamicGeometry, dynamic_geometry_tag>
|
||||
{
|
||||
static inline void apply(std::string const& wkt, DynamicGeometry& dynamic_geometry)
|
||||
{
|
||||
detail::wkt::tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
|
||||
detail::wkt::tokenizer::iterator it = tokens.begin();
|
||||
detail::wkt::tokenizer::iterator end = tokens.end();
|
||||
auto tokens{detail::wkt::make_tokenizer(wkt)};
|
||||
auto it = tokens.begin();
|
||||
auto end = tokens.end();
|
||||
if (it == end)
|
||||
{
|
||||
BOOST_THROW_EXCEPTION(read_wkt_exception(
|
||||
"Should start with geometry's name, e.g. 'POINT', 'LINESTRING', 'POLYGON', etc.",
|
||||
"Should start with geometry's type, for example 'POINT', 'LINESTRING', 'POLYGON'",
|
||||
wkt));
|
||||
}
|
||||
|
||||
@ -1111,21 +1147,23 @@ struct read_wkt<Geometry, geometry_collection_tag>
|
||||
{
|
||||
range::clear(geometry);
|
||||
|
||||
detail::wkt::tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
|
||||
detail::wkt::tokenizer::iterator it = tokens.begin();
|
||||
detail::wkt::tokenizer::iterator const end = tokens.end();
|
||||
auto tokens{detail::wkt::make_tokenizer(wkt)};
|
||||
auto it = tokens.begin();
|
||||
auto const end = tokens.end();
|
||||
|
||||
apply(it, end, wkt, geometry);
|
||||
|
||||
detail::wkt::check_end(it, end, wkt);
|
||||
}
|
||||
|
||||
static inline void apply(detail::wkt::tokenizer::iterator& it,
|
||||
detail::wkt::tokenizer::iterator const& end,
|
||||
template <typename TokenizerIterator>
|
||||
static inline void apply(TokenizerIterator& it,
|
||||
TokenizerIterator const& end,
|
||||
std::string const& wkt,
|
||||
Geometry& geometry)
|
||||
{
|
||||
if (detail::wkt::initialize<Geometry>(it, end, wkt, "GEOMETRYCOLLECTION"))
|
||||
if (detail::wkt::initialize<Geometry>(it, end, wkt,
|
||||
detail::wkt::prefix_geometrycollection::apply()))
|
||||
{
|
||||
detail::wkt::handle_open_parenthesis(it, end, wkt);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2017 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2007-2022 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2017 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2017 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2014-2017 Adam Wulkiewicz, Lodz, Poland.
|
||||
@ -88,32 +88,6 @@ struct stream_coordinate<P, Count, Count>
|
||||
{}
|
||||
};
|
||||
|
||||
struct prefix_linestring_par
|
||||
{
|
||||
static inline const char* apply() { return "LINESTRING("; }
|
||||
};
|
||||
|
||||
struct prefix_ring_par_par
|
||||
{
|
||||
// Note, double parentheses are intentional, indicating WKT ring begin/end
|
||||
static inline const char* apply() { return "POLYGON(("; }
|
||||
};
|
||||
|
||||
struct opening_parenthesis
|
||||
{
|
||||
static inline const char* apply() { return "("; }
|
||||
};
|
||||
|
||||
struct closing_parenthesis
|
||||
{
|
||||
static inline const char* apply() { return ")"; }
|
||||
};
|
||||
|
||||
struct double_closing_parenthesis
|
||||
{
|
||||
static inline const char* apply() { return "))"; }
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief Stream points as \ref WKT
|
||||
*/
|
||||
@ -131,14 +105,13 @@ struct wkt_point
|
||||
|
||||
/*!
|
||||
\brief Stream ranges as WKT
|
||||
\note policy is used to stream prefix/postfix, enabling derived classes to override this
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename Range,
|
||||
bool ForceClosurePossible,
|
||||
typename PrefixPolicy,
|
||||
typename SuffixPolicy
|
||||
bool ForceClosurePossible = false,
|
||||
bool WriteDoubleBrackets = false
|
||||
>
|
||||
struct wkt_range
|
||||
{
|
||||
@ -146,52 +119,60 @@ struct wkt_range
|
||||
static inline void apply(std::basic_ostream<Char, Traits>& os,
|
||||
Range const& range, bool force_closure = ForceClosurePossible)
|
||||
{
|
||||
typedef typename boost::range_iterator<Range const>::type iterator_type;
|
||||
|
||||
typedef stream_coordinate
|
||||
using stream_type = stream_coordinate
|
||||
<
|
||||
point_type, 0, dimension<point_type>::type::value
|
||||
> stream_type;
|
||||
>;
|
||||
|
||||
bool first = true;
|
||||
|
||||
os << PrefixPolicy::apply();
|
||||
os << "(";
|
||||
|
||||
// TODO: check EMPTY here
|
||||
|
||||
iterator_type begin = boost::begin(range);
|
||||
iterator_type end = boost::end(range);
|
||||
for (iterator_type it = begin; it != end; ++it)
|
||||
if (boost::size(range) > 0)
|
||||
{
|
||||
os << (first ? "" : ",");
|
||||
stream_type::apply(os, *it);
|
||||
first = false;
|
||||
if (WriteDoubleBrackets)
|
||||
{
|
||||
os << "(";
|
||||
}
|
||||
auto begin = boost::begin(range);
|
||||
auto end = boost::end(range);
|
||||
for (auto it = begin; it != end; ++it)
|
||||
{
|
||||
os << (first ? "" : ",");
|
||||
stream_type::apply(os, *it);
|
||||
first = false;
|
||||
}
|
||||
|
||||
// optionally, close range to ring by repeating the first point
|
||||
if (BOOST_GEOMETRY_CONDITION(ForceClosurePossible)
|
||||
&& force_closure
|
||||
&& boost::size(range) > 1
|
||||
&& wkt_range::disjoint(*begin, *(end - 1)))
|
||||
{
|
||||
os << ",";
|
||||
stream_type::apply(os, *begin);
|
||||
}
|
||||
if (WriteDoubleBrackets)
|
||||
{
|
||||
os << ")";
|
||||
}
|
||||
}
|
||||
|
||||
// optionally, close range to ring by repeating the first point
|
||||
if (BOOST_GEOMETRY_CONDITION(ForceClosurePossible)
|
||||
&& force_closure
|
||||
&& boost::size(range) > 1
|
||||
&& wkt_range::disjoint(*begin, *(end - 1)))
|
||||
{
|
||||
os << ",";
|
||||
stream_type::apply(os, *begin);
|
||||
}
|
||||
|
||||
os << SuffixPolicy::apply();
|
||||
os << ")";
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
typedef typename boost::range_value<Range>::type point_type;
|
||||
using point_type = typename boost::range_value<Range>::type;
|
||||
|
||||
static inline bool disjoint(point_type const& p1, point_type const& p2)
|
||||
{
|
||||
// TODO: pass strategy
|
||||
typedef typename strategies::io::services::default_strategy
|
||||
using strategy_type = typename strategies::io::services::default_strategy
|
||||
<
|
||||
point_type
|
||||
>::type strategy_type;
|
||||
>::type;
|
||||
|
||||
return detail::disjoint::disjoint_point_point(p1, p2, strategy_type());
|
||||
}
|
||||
@ -206,9 +187,8 @@ struct wkt_sequence
|
||||
: wkt_range
|
||||
<
|
||||
Range,
|
||||
ForceClosurePossible,
|
||||
opening_parenthesis,
|
||||
closing_parenthesis
|
||||
prefix_null,
|
||||
ForceClosurePossible
|
||||
>
|
||||
{};
|
||||
|
||||
@ -219,20 +199,29 @@ struct wkt_poly
|
||||
static inline void apply(std::basic_ostream<Char, Traits>& os,
|
||||
Polygon const& poly, bool force_closure)
|
||||
{
|
||||
typedef typename ring_type<Polygon const>::type ring;
|
||||
using ring = typename ring_type<Polygon const>::type;
|
||||
|
||||
auto const exterior = exterior_ring(poly);
|
||||
auto const rings = interior_rings(poly);
|
||||
|
||||
std::size_t point_count = boost::size(exterior);
|
||||
for (auto it = boost::begin(rings); it != boost::end(rings); ++it)
|
||||
{
|
||||
point_count += boost::size(*it);
|
||||
}
|
||||
|
||||
os << PrefixPolicy::apply();
|
||||
// TODO: check EMPTY here
|
||||
os << "(";
|
||||
wkt_sequence<ring>::apply(os, exterior_ring(poly), force_closure);
|
||||
|
||||
typename interior_return_type<Polygon const>::type
|
||||
rings = interior_rings(poly);
|
||||
for (typename detail::interior_iterator<Polygon const>::type
|
||||
it = boost::begin(rings); it != boost::end(rings); ++it)
|
||||
os << "(";
|
||||
if (point_count > 0)
|
||||
{
|
||||
os << ",";
|
||||
wkt_sequence<ring>::apply(os, *it, force_closure);
|
||||
wkt_sequence<ring>::apply(os, exterior, force_closure);
|
||||
|
||||
for (auto it = boost::begin(rings); it != boost::end(rings); ++it)
|
||||
{
|
||||
os << ",";
|
||||
wkt_sequence<ring>::apply(os, *it, force_closure);
|
||||
}
|
||||
}
|
||||
os << ")";
|
||||
}
|
||||
@ -247,13 +236,9 @@ struct wkt_multi
|
||||
Multi const& geometry, bool force_closure)
|
||||
{
|
||||
os << PrefixPolicy::apply();
|
||||
// TODO: check EMPTY here
|
||||
os << "(";
|
||||
|
||||
for (typename boost::range_iterator<Multi const>::type
|
||||
it = boost::begin(geometry);
|
||||
it != boost::end(geometry);
|
||||
++it)
|
||||
for (auto it = boost::begin(geometry); it != boost::end(geometry); ++it)
|
||||
{
|
||||
if (it != boost::begin(geometry))
|
||||
{
|
||||
@ -269,7 +254,7 @@ struct wkt_multi
|
||||
template <typename Box>
|
||||
struct wkt_box
|
||||
{
|
||||
typedef typename point_type<Box>::type point_type;
|
||||
using point_type = typename point_type<Box>::type;
|
||||
|
||||
template <typename Char, typename Traits>
|
||||
static inline void apply(std::basic_ostream<Char, Traits>& os,
|
||||
@ -313,14 +298,14 @@ struct wkt_box
|
||||
template <typename Segment>
|
||||
struct wkt_segment
|
||||
{
|
||||
typedef typename point_type<Segment>::type point_type;
|
||||
using point_type = typename point_type<Segment>::type;
|
||||
|
||||
template <typename Char, typename Traits>
|
||||
static inline void apply(std::basic_ostream<Char, Traits>& os,
|
||||
Segment const& segment, bool)
|
||||
{
|
||||
// Convert to two points, then stream
|
||||
typedef boost::array<point_type, 2> sequence;
|
||||
using sequence = boost::array<point_type, 2>;
|
||||
|
||||
sequence points;
|
||||
geometry::detail::assign_point_from_index<0>(segment, points[0]);
|
||||
@ -363,9 +348,7 @@ struct wkt<Linestring, linestring_tag>
|
||||
: detail::wkt::wkt_range
|
||||
<
|
||||
Linestring,
|
||||
false,
|
||||
detail::wkt::prefix_linestring_par,
|
||||
detail::wkt::closing_parenthesis
|
||||
detail::wkt::prefix_linestring
|
||||
>
|
||||
{};
|
||||
|
||||
@ -395,9 +378,9 @@ struct wkt<Ring, ring_tag>
|
||||
: detail::wkt::wkt_range
|
||||
<
|
||||
Ring,
|
||||
detail::wkt::prefix_polygon,
|
||||
true,
|
||||
detail::wkt::prefix_ring_par_par,
|
||||
detail::wkt::double_closing_parenthesis
|
||||
true
|
||||
>
|
||||
{};
|
||||
|
||||
|
@ -14,8 +14,7 @@
|
||||
#ifndef BOOST_GEOMETRY_MULTI_IO_WKT_DETAIL_PREFIX_HPP
|
||||
#define BOOST_GEOMETRY_MULTI_IO_WKT_DETAIL_PREFIX_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/io/wkt/detail/prefix.hpp>
|
||||
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.")
|
||||
|
||||
#endif // BOOST_GEOMETRY_MULTI_IO_WKT_DETAIL_PREFIX_HPP
|
||||
|
@ -87,12 +87,12 @@ void test_all()
|
||||
"POLYGON EMPTY"
|
||||
|
||||
, 0
|
||||
, "POLYGON(())"
|
||||
, "POLYGON(())"
|
||||
, "POLYGON()"
|
||||
, "POLYGON()"
|
||||
|
||||
, ""
|
||||
, 0
|
||||
, "POLYGON(())"
|
||||
, "POLYGON()"
|
||||
);
|
||||
test_geometry<bg::model::ring<P, true, false> > // open ring
|
||||
(
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2007-2022 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
|
||||
@ -51,9 +51,8 @@ void check_wkt(G const& geometry, std::string const& expected)
|
||||
template <typename G>
|
||||
void check_to_wkt(G const& geometry, std::string const& expected)
|
||||
{
|
||||
std::string out_string;
|
||||
out_string = bg::to_wkt(geometry);
|
||||
BOOST_CHECK_EQUAL(boost::to_upper_copy(out_string),
|
||||
std::string const out = bg::to_wkt(geometry);
|
||||
BOOST_CHECK_EQUAL(boost::to_upper_copy(out),
|
||||
boost::to_upper_copy(expected));
|
||||
}
|
||||
|
||||
@ -156,7 +155,6 @@ void test_wkt(std::string const& wkt,
|
||||
template <typename G>
|
||||
void test_relaxed_wkt_read_write(std::string const& wkt, std::string const& expected)
|
||||
{
|
||||
std::string e;
|
||||
G geometry;
|
||||
bg::read_wkt(wkt, geometry);
|
||||
std::ostringstream out;
|
||||
@ -168,11 +166,9 @@ void test_relaxed_wkt_read_write(std::string const& wkt, std::string const& expe
|
||||
template <typename G>
|
||||
void test_relaxed_wkt_to_from(std::string const& wkt, std::string const& expected)
|
||||
{
|
||||
std::string e;
|
||||
G geometry;
|
||||
geometry = bg::from_wkt<G>(wkt);
|
||||
std::string out;
|
||||
out = bg::to_wkt(geometry);
|
||||
std::string const out = bg::to_wkt(geometry);
|
||||
|
||||
BOOST_CHECK_EQUAL(boost::to_upper_copy(out), boost::to_upper_copy(expected));
|
||||
}
|
||||
@ -328,29 +324,32 @@ void test_all()
|
||||
//test_wkt<box<P> >("POLYGON((0 0,0 1,1 1,1 0,0 0))", 4, 0, 1, 4);
|
||||
test_wkt<bg::model::ring<P> >("POLYGON((0 0,0 1,1 1,1 0,0 0))", 5, 0, 1, 4);
|
||||
|
||||
// We accept empty sequences as well (much better than EMPTY)...
|
||||
// ...or even POINT() (see below)
|
||||
test_wkt<bg::model::linestring<P> >("LINESTRING()", 0, 0);
|
||||
test_wkt<bg::model::polygon<P> >("POLYGON(())", 0);
|
||||
// ... or even with empty holes
|
||||
test_wkt<bg::model::polygon<P> >("POLYGON((),(),())", 0);
|
||||
// which all make no valid geometries, but they can exist.
|
||||
test_relaxed_wkt<bg::model::linestring<P> >("LINESTRING EMPTY", "LINESTRING()");
|
||||
test_relaxed_wkt<bg::model::polygon<P> >("POLYGON EMPTY", "POLYGON()");
|
||||
test_relaxed_wkt<bg::model::ring<P> >("POLYGON EMPTY", "POLYGON()");
|
||||
|
||||
// Accept empty sequences as well
|
||||
test_relaxed_wkt<bg::model::linestring<P> >("LINESTRING()", "LINESTRING()");
|
||||
test_relaxed_wkt<bg::model::polygon<P> >("POLYGON()", "POLYGON()");
|
||||
test_relaxed_wkt<bg::model::polygon<P> >("POLYGON(())", "POLYGON()");
|
||||
test_relaxed_wkt<bg::model::polygon<P> >("POLYGON((),(),())", "POLYGON()");
|
||||
|
||||
// Invalid polygon with an inner ring coordinate is outputted as such
|
||||
test_relaxed_wkt<bg::model::polygon<P> >("POLYGON((),(),(1 2))", "POLYGON((),(),(1 2))");
|
||||
|
||||
// Non OGC: tabs and returns are allowed and handled as normal white space.
|
||||
test_relaxed_wkt<P>("POINT(1\n2)", "POINT(1 2)");
|
||||
test_relaxed_wkt<P>("POINT(1\t2)", "POINT(1 2)");
|
||||
test_relaxed_wkt<P>("POINT(1\r2)", "POINT(1 2)");
|
||||
|
||||
// These WKT's are incomplete or abnormal but they are considered OK
|
||||
test_relaxed_wkt<P>("POINT(1)", "POINT(1 0)");
|
||||
test_relaxed_wkt<P>("POINT()", "POINT(0 0)");
|
||||
test_relaxed_wkt<bg::model::linestring<P> >("LINESTRING(1,2,3)",
|
||||
"LINESTRING(1 0,2 0,3 0)");
|
||||
test_relaxed_wkt<bg::model::linestring<P> >("LINESTRING(1,2,3)", "LINESTRING(1 0,2 0,3 0)");
|
||||
test_relaxed_wkt<P>("POINT ( 1 2) ", "POINT(1 2)");
|
||||
test_relaxed_wkt<P>("POINT M ( 1 2)", "POINT(1 2)");
|
||||
test_relaxed_wkt<bg::model::box<P> >("BOX(1 1,2 2)", "POLYGON((1 1,1 2,2 2,2 1,1 1))");
|
||||
|
||||
test_relaxed_wkt<bg::model::linestring<P> >("LINESTRING EMPTY", "LINESTRING()");
|
||||
|
||||
test_relaxed_wkt<bg::model::polygon<P> >("POLYGON( ( ) , ( ) , ( ) )",
|
||||
"POLYGON((),(),())");
|
||||
test_relaxed_wkt<bg::model::polygon<P> >("POLYGON( ( ) , ( ) , ( ) )", "POLYGON()");
|
||||
|
||||
// Wrong WKT's
|
||||
test_wrong_wkt<P>("POINT(1 2", "expected ')'");
|
||||
@ -398,33 +397,3 @@ int test_main(int, char* [])
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Results can be checked in PostGIS by query below,
|
||||
or by MySQL (but replace length by glength and remove the perimeter)
|
||||
|
||||
Note:
|
||||
- PostGIS gives "3" for a numpoints of a multi-linestring of 6 points in total (!)
|
||||
--> "npoints" should be taken for all geometries
|
||||
- SQL Server 2008 gives "6"
|
||||
select geometry::STGeomFromText('MULTILINESTRING((1 1,2 2,3 3),(4 4,5 5,6 6))',0).STNumPoints()
|
||||
- MySQL gives "NULL"
|
||||
|
||||
select 1 as code,'np p' as header,npoints(geomfromtext('POINT(1 2)')) as contents
|
||||
union select 2,'length point', length(geomfromtext('POINT(1 2)'))
|
||||
union select 3,'peri point', perimeter(geomfromtext('POINT(1 2)'))
|
||||
union select 4,'area point',area(geomfromtext('POINT(1 2)'))
|
||||
|
||||
|
||||
union select 5,'# ls',npoints(geomfromtext('LINESTRING(1 1,2 2,3 3)'))
|
||||
union select 6,'length ls',length(geomfromtext('LINESTRING(1 1,2 2,3 3)'))
|
||||
union select 7,'peri ls',perimeter(geomfromtext('LINESTRING(1 1,2 2,3 3)'))
|
||||
union select 8,'aera ls',area(geomfromtext('LINESTRING(1 1,2 2,3 3)'))
|
||||
|
||||
union select 9,'# poly',npoints(geomfromtext('POLYGON((0 0,0 4,4 4,4 0,0 0),(1 1,1 2,2 2,2 1,1 1),(1 1,1 2,2 2,2 1,1 1))'))
|
||||
union select 10,'length poly',length(geomfromtext('POLYGON((0 0,0 4,4 4,4 0,0 0),(1 1,1 2,2 2,2 1,1 1),(1 1,1 2,2 2,2 1,1 1))'))
|
||||
union select 11,'peri poly',perimeter(geomfromtext('POLYGON((0 0,0 4,4 4,4 0,0 0),(1 1,1 2,2 2,2 1,1 1),(1 1,1 2,2 2,2 1,1 1))'))
|
||||
union select 12,'area poly',area(geomfromtext('POLYGON((0 0,0 4,4 4,4 0,0 0),(1 1,1 2,2 2,2 1,1 1),(1 1,1 2,2 2,2 1,1 1))'))
|
||||
|
||||
*/
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2007-2022 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
||||
|
||||
@ -76,6 +76,18 @@ void test_all()
|
||||
test_wkt<bg::model::multi_linestring<bg::model::linestring<P> > >("multilinestring((1 1,2 2,3 3),(4 4,5 5,6 6))", 6, 4 * sqrt(2.0));
|
||||
test_wkt<bg::model::multi_polygon<bg::model::polygon<P> > >("multipolygon(((0 0,0 2,2 2,2 0,0 0),(1 1,1 2,2 2,2 1,1 1)),((0 0,0 4,4 4,4 0,0 0)))", 15, 0, 21, 28);
|
||||
|
||||
// Support tabs, and new lines.
|
||||
test_relaxed_wkt<bg::model::multi_point<P> >("multipoint((1\t2),\n(3\r4))", "multipoint((1 2),(3 4))");
|
||||
|
||||
// Verify empty multi geometries
|
||||
test_relaxed_wkt<bg::model::multi_point<P> >("multipoint()", "multipoint()");
|
||||
test_relaxed_wkt<bg::model::multi_linestring<bg::model::linestring<P> >>("multilinestring()", "multilinestring()");
|
||||
test_relaxed_wkt<bg::model::multi_polygon<bg::model::polygon<P> > >("multipolygon()", "multipolygon()");
|
||||
|
||||
test_relaxed_wkt<bg::model::multi_point<P> >("multipoint empty", "multipoint()");
|
||||
test_relaxed_wkt<bg::model::multi_linestring<bg::model::linestring<P> >>("multilinestring empty", "multilinestring()");
|
||||
test_relaxed_wkt<bg::model::multi_polygon<bg::model::polygon<P> > >("multipolygon empty", "multipolygon()");
|
||||
|
||||
// Support for the official alternative syntax for multipoint
|
||||
// (provided by Aleksey Tulinov):
|
||||
test_relaxed_wkt<bg::model::multi_point<P> >("multipoint(1 2,3 4)", "multipoint((1 2),(3 4))");
|
||||
@ -103,24 +115,3 @@ void test_all()
|
||||
|
||||
test_order_closure<T>();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
... see comments in "wkt.cpp"
|
||||
|
||||
union select 13,'# mpoint',npoints(geomfromtext('MULTIPOINT((1 2),(3 4))'))
|
||||
union select 14,'length mpoint',length(geomfromtext('MULTIPOINT((1 2),(3 4))'))
|
||||
union select 15,'peri mpoint',perimeter(geomfromtext('MULTIPOINT((1 2),(3 4))'))
|
||||
union select 16,'area mpoint',area(geomfromtext('MULTIPOINT((1 2),(3 4))'))
|
||||
|
||||
union select 17,'# mls',npoints(geomfromtext('MULTILINESTRING((1 1,2 2,3 3),(4 4,5 5,6 6))'))
|
||||
union select 18,'length mls',length(geomfromtext('MULTILINESTRING((1 1,2 2,3 3),(4 4,5 5,6 6))'))
|
||||
union select 19,'peri mls',perimeter(geomfromtext('MULTILINESTRING((1 1,2 2,3 3),(4 4,5 5,6 6))'))
|
||||
union select 20,'area mls',area(geomfromtext('MULTILINESTRING((1 1,2 2,3 3),(4 4,5 5,6 6))'))
|
||||
|
||||
union select 21,'# mpoly',npoints(geomfromtext('MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0),(1 1,1 2,2 2,2 1,1 1)),((0 0,0 4,4 4,4 0,0 0)))'))
|
||||
union select 22,'length mpoly',length(geomfromtext('MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0),(1 1,1 2,2 2,2 1,1 1)),((0 0,0 4,4 4,4 0,0 0)))'))
|
||||
union select 23,'peri mpoly',perimeter(geomfromtext('MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0),(1 1,1 2,2 2,2 1,1 1)),((0 0,0 4,4 4,4 0,0 0)))'))
|
||||
union select 24,'area mpoly',area(geomfromtext('MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0),(1 1,1 2,2 2,2 1,1 1)),((0 0,0 4,4 4,4 0,0 0)))'))
|
||||
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user