[wkt] apply the wkt change for all geometries instead of only polygon.

This is necessary for the splitted correct_closure algorithm, which needs
an exact WKT representation of its geometry
This commit is contained in:
Barend Gehrels 2017-10-19 15:27:47 +02:00
parent 8069131100
commit 917b18e66c

View File

@ -1,12 +1,12 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2007-2017 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2008-2017 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2009-2017 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland. // Copyright (c) 2014-2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2015. // This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015, Oracle and/or its affiliates. // Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@ -111,7 +111,7 @@ template <typename Point, typename Policy>
struct wkt_point struct wkt_point
{ {
template <typename Char, typename Traits> template <typename Char, typename Traits>
static inline void apply(std::basic_ostream<Char, Traits>& os, Point const& p) static inline void apply(std::basic_ostream<Char, Traits>& os, Point const& p, bool)
{ {
os << Policy::apply() << "("; os << Policy::apply() << "(";
stream_coordinate<Point, 0, dimension<Point>::type::value>::apply(os, p); stream_coordinate<Point, 0, dimension<Point>::type::value>::apply(os, p);
@ -123,12 +123,18 @@ struct wkt_point
\brief Stream ranges as WKT \brief Stream ranges as WKT
\note policy is used to stream prefix/postfix, enabling derived classes to override this \note policy is used to stream prefix/postfix, enabling derived classes to override this
*/ */
template <typename Range, typename PrefixPolicy, typename SuffixPolicy> template
<
typename Range,
bool ForceClosurePossible,
typename PrefixPolicy,
typename SuffixPolicy
>
struct wkt_range struct wkt_range
{ {
template <typename Char, typename Traits> template <typename Char, typename Traits>
static inline void apply(std::basic_ostream<Char, Traits>& os, static inline void apply(std::basic_ostream<Char, Traits>& os,
Range const& range, bool force_closed) Range const& range, bool force_closure)
{ {
typedef typename boost::range_iterator<Range const>::type iterator_type; typedef typename boost::range_iterator<Range const>::type iterator_type;
@ -153,7 +159,8 @@ struct wkt_range
} }
// optionally, close range to ring by repeating the first point // optionally, close range to ring by repeating the first point
if (force_closed if (ForceClosurePossible
&& force_closure
&& boost::size(range) > 1 && boost::size(range) > 1
&& detail::disjoint::disjoint_point_point(*begin, *(end - 1))) && detail::disjoint::disjoint_point_point(*begin, *(end - 1)))
{ {
@ -164,12 +171,6 @@ struct wkt_range
os << SuffixPolicy::apply(); os << SuffixPolicy::apply();
} }
template <typename Char, typename Traits>
static inline void apply(std::basic_ostream<Char, Traits>& os,
Range const& range)
{
apply(os, range, false);
}
private: private:
typedef typename boost::range_value<Range>::type point_type; typedef typename boost::range_value<Range>::type point_type;
@ -179,11 +180,12 @@ private:
\brief Stream sequence of points as WKT-part, e.g. (1 2),(3 4) \brief Stream sequence of points as WKT-part, e.g. (1 2),(3 4)
\note Used in polygon, all multi-geometries \note Used in polygon, all multi-geometries
*/ */
template <typename Range> template <typename Range, bool ForceClosurePossible = true>
struct wkt_sequence struct wkt_sequence
: wkt_range : wkt_range
< <
Range, Range,
ForceClosurePossible,
opening_parenthesis, opening_parenthesis,
closing_parenthesis closing_parenthesis
> >
@ -194,15 +196,14 @@ struct wkt_poly
{ {
template <typename Char, typename Traits> template <typename Char, typename Traits>
static inline void apply(std::basic_ostream<Char, Traits>& os, static inline void apply(std::basic_ostream<Char, Traits>& os,
Polygon const& poly) Polygon const& poly, bool force_closure)
{ {
typedef typename ring_type<Polygon const>::type ring; typedef typename ring_type<Polygon const>::type ring;
bool const force_closed = true;
os << PrefixPolicy::apply(); os << PrefixPolicy::apply();
// TODO: check EMPTY here // TODO: check EMPTY here
os << "("; os << "(";
wkt_sequence<ring>::apply(os, exterior_ring(poly), force_closed); wkt_sequence<ring>::apply(os, exterior_ring(poly), force_closure);
typename interior_return_type<Polygon const>::type typename interior_return_type<Polygon const>::type
rings = interior_rings(poly); rings = interior_rings(poly);
@ -210,10 +211,11 @@ struct wkt_poly
it = boost::begin(rings); it != boost::end(rings); ++it) it = boost::begin(rings); it != boost::end(rings); ++it)
{ {
os << ","; os << ",";
wkt_sequence<ring>::apply(os, *it, force_closed); wkt_sequence<ring>::apply(os, *it, force_closure);
} }
os << ")"; os << ")";
} }
}; };
template <typename Multi, typename StreamPolicy, typename PrefixPolicy> template <typename Multi, typename StreamPolicy, typename PrefixPolicy>
@ -221,7 +223,7 @@ struct wkt_multi
{ {
template <typename Char, typename Traits> template <typename Char, typename Traits>
static inline void apply(std::basic_ostream<Char, Traits>& os, static inline void apply(std::basic_ostream<Char, Traits>& os,
Multi const& geometry) Multi const& geometry, bool force_closure)
{ {
os << PrefixPolicy::apply(); os << PrefixPolicy::apply();
// TODO: check EMPTY here // TODO: check EMPTY here
@ -236,7 +238,7 @@ struct wkt_multi
{ {
os << ","; os << ",";
} }
StreamPolicy::apply(os, *it); StreamPolicy::apply(os, *it, force_closure);
} }
os << ")"; os << ")";
@ -250,14 +252,14 @@ struct wkt_box
template <typename Char, typename Traits> template <typename Char, typename Traits>
static inline void apply(std::basic_ostream<Char, Traits>& os, static inline void apply(std::basic_ostream<Char, Traits>& os,
Box const& box) Box const& box, bool force_closure)
{ {
// Convert to ring, then stream // Convert to open cw ring, then stream
typedef model::ring<point_type> ring_type; typedef model::ring<point_type, true, false> ring_type;
ring_type ring; ring_type ring;
geometry::convert(box, ring); geometry::convert(box, ring);
os << "POLYGON("; os << "POLYGON(";
wkt_sequence<ring_type>::apply(os, ring); wkt_sequence<ring_type>::apply(os, ring, force_closure);
os << ")"; os << ")";
} }
@ -278,7 +280,7 @@ struct wkt_segment
template <typename Char, typename Traits> template <typename Char, typename Traits>
static inline void apply(std::basic_ostream<Char, Traits>& os, static inline void apply(std::basic_ostream<Char, Traits>& os,
Segment const& segment) Segment const& segment, bool)
{ {
// Convert to two points, then stream // Convert to two points, then stream
typedef boost::array<point_type, 2> sequence; typedef boost::array<point_type, 2> sequence;
@ -290,7 +292,7 @@ struct wkt_segment
// In Boost.Geometry a segment is represented // In Boost.Geometry a segment is represented
// in WKT-format like (for 2D): LINESTRING(x y,x y) // in WKT-format like (for 2D): LINESTRING(x y,x y)
os << "LINESTRING"; os << "LINESTRING";
wkt_sequence<sequence>::apply(os, points); wkt_sequence<sequence, false>::apply(os, points, false);
} }
private: private:
@ -324,6 +326,7 @@ struct wkt<Linestring, linestring_tag>
: detail::wkt::wkt_range : detail::wkt::wkt_range
< <
Linestring, Linestring,
false,
detail::wkt::prefix_linestring_par, detail::wkt::prefix_linestring_par,
detail::wkt::closing_parenthesis detail::wkt::closing_parenthesis
> >
@ -355,6 +358,7 @@ struct wkt<Ring, ring_tag>
: detail::wkt::wkt_range : detail::wkt::wkt_range
< <
Ring, Ring,
true,
detail::wkt::prefix_ring_par_par, detail::wkt::prefix_ring_par_par,
detail::wkt::double_closing_parenthesis detail::wkt::double_closing_parenthesis
> >
@ -393,7 +397,8 @@ struct wkt<Multi, multi_linestring_tag>
Multi, Multi,
detail::wkt::wkt_sequence detail::wkt::wkt_sequence
< <
typename boost::range_value<Multi>::type typename boost::range_value<Multi>::type,
false
>, >,
detail::wkt::prefix_multilinestring detail::wkt::prefix_multilinestring
> >
@ -418,9 +423,10 @@ template <typename Geometry>
struct devarianted_wkt struct devarianted_wkt
{ {
template <typename OutputStream> template <typename OutputStream>
static inline void apply(OutputStream& os, Geometry const& geometry) static inline void apply(OutputStream& os, Geometry const& geometry,
bool force_closure)
{ {
wkt<Geometry>::apply(os, geometry); wkt<Geometry>::apply(os, geometry, force_closure);
} }
}; };
@ -431,25 +437,27 @@ struct devarianted_wkt<variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
struct visitor: static_visitor<void> struct visitor: static_visitor<void>
{ {
OutputStream& m_os; OutputStream& m_os;
bool m_force_closure;
visitor(OutputStream& os) visitor(OutputStream& os, bool force_closure)
: m_os(os) : m_os(os)
, m_force_closure(force_closure)
{} {}
template <typename Geometry> template <typename Geometry>
inline void operator()(Geometry const& geometry) const inline void operator()(Geometry const& geometry) const
{ {
devarianted_wkt<Geometry>::apply(m_os, geometry); devarianted_wkt<Geometry>::apply(m_os, geometry, m_force_closure);
} }
}; };
template <typename OutputStream> template <typename OutputStream>
static inline void apply( static inline void apply(
OutputStream& os, OutputStream& os,
variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
) bool force_closure)
{ {
boost::apply_visitor(visitor<OutputStream>(os), geometry); boost::apply_visitor(visitor<OutputStream>(os, force_closure), geometry);
} }
}; };
@ -473,8 +481,9 @@ class wkt_manipulator
{ {
public: public:
inline wkt_manipulator(Geometry const& g) inline wkt_manipulator(Geometry const& g, bool force_closure = true)
: m_geometry(g) : m_geometry(g)
, m_force_closure(force_closure)
{} {}
template <typename Char, typename Traits> template <typename Char, typename Traits>
@ -482,13 +491,14 @@ public:
std::basic_ostream<Char, Traits>& os, std::basic_ostream<Char, Traits>& os,
wkt_manipulator const& m) wkt_manipulator const& m)
{ {
dispatch::devarianted_wkt<Geometry>::apply(os, m.m_geometry); dispatch::devarianted_wkt<Geometry>::apply(os, m.m_geometry, m.m_force_closure);
os.flush(); os.flush();
return os; return os;
} }
private: private:
Geometry const& m_geometry; Geometry const& m_geometry;
bool m_force_closure;
}; };
/*! /*!