[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)
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2007-2017 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.
// 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
@ -111,7 +111,7 @@ template <typename Point, typename Policy>
struct wkt_point
{
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() << "(";
stream_coordinate<Point, 0, dimension<Point>::type::value>::apply(os, p);
@ -123,12 +123,18 @@ 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, typename PrefixPolicy, typename SuffixPolicy>
template
<
typename Range,
bool ForceClosurePossible,
typename PrefixPolicy,
typename SuffixPolicy
>
struct wkt_range
{
template <typename Char, typename Traits>
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;
@ -153,7 +159,8 @@ struct wkt_range
}
// optionally, close range to ring by repeating the first point
if (force_closed
if (ForceClosurePossible
&& force_closure
&& boost::size(range) > 1
&& detail::disjoint::disjoint_point_point(*begin, *(end - 1)))
{
@ -164,12 +171,6 @@ struct wkt_range
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:
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)
\note Used in polygon, all multi-geometries
*/
template <typename Range>
template <typename Range, bool ForceClosurePossible = true>
struct wkt_sequence
: wkt_range
<
Range,
ForceClosurePossible,
opening_parenthesis,
closing_parenthesis
>
@ -194,15 +196,14 @@ struct wkt_poly
{
template <typename Char, typename Traits>
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;
bool const force_closed = true;
os << PrefixPolicy::apply();
// TODO: check EMPTY here
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
rings = interior_rings(poly);
@ -210,10 +211,11 @@ struct wkt_poly
it = boost::begin(rings); it != boost::end(rings); ++it)
{
os << ",";
wkt_sequence<ring>::apply(os, *it, force_closed);
wkt_sequence<ring>::apply(os, *it, force_closure);
}
os << ")";
}
};
template <typename Multi, typename StreamPolicy, typename PrefixPolicy>
@ -221,7 +223,7 @@ struct wkt_multi
{
template <typename Char, typename Traits>
static inline void apply(std::basic_ostream<Char, Traits>& os,
Multi const& geometry)
Multi const& geometry, bool force_closure)
{
os << PrefixPolicy::apply();
// TODO: check EMPTY here
@ -236,7 +238,7 @@ struct wkt_multi
{
os << ",";
}
StreamPolicy::apply(os, *it);
StreamPolicy::apply(os, *it, force_closure);
}
os << ")";
@ -250,14 +252,14 @@ struct wkt_box
template <typename Char, typename Traits>
static inline void apply(std::basic_ostream<Char, Traits>& os,
Box const& box)
Box const& box, bool force_closure)
{
// Convert to ring, then stream
typedef model::ring<point_type> ring_type;
// Convert to open cw ring, then stream
typedef model::ring<point_type, true, false> ring_type;
ring_type ring;
geometry::convert(box, ring);
os << "POLYGON(";
wkt_sequence<ring_type>::apply(os, ring);
wkt_sequence<ring_type>::apply(os, ring, force_closure);
os << ")";
}
@ -278,7 +280,7 @@ struct wkt_segment
template <typename Char, typename Traits>
static inline void apply(std::basic_ostream<Char, Traits>& os,
Segment const& segment)
Segment const& segment, bool)
{
// Convert to two points, then stream
typedef boost::array<point_type, 2> sequence;
@ -290,7 +292,7 @@ struct wkt_segment
// In Boost.Geometry a segment is represented
// in WKT-format like (for 2D): LINESTRING(x y,x y)
os << "LINESTRING";
wkt_sequence<sequence>::apply(os, points);
wkt_sequence<sequence, false>::apply(os, points, false);
}
private:
@ -324,6 +326,7 @@ struct wkt<Linestring, linestring_tag>
: detail::wkt::wkt_range
<
Linestring,
false,
detail::wkt::prefix_linestring_par,
detail::wkt::closing_parenthesis
>
@ -355,6 +358,7 @@ struct wkt<Ring, ring_tag>
: detail::wkt::wkt_range
<
Ring,
true,
detail::wkt::prefix_ring_par_par,
detail::wkt::double_closing_parenthesis
>
@ -393,7 +397,8 @@ struct wkt<Multi, multi_linestring_tag>
Multi,
detail::wkt::wkt_sequence
<
typename boost::range_value<Multi>::type
typename boost::range_value<Multi>::type,
false
>,
detail::wkt::prefix_multilinestring
>
@ -418,9 +423,10 @@ template <typename Geometry>
struct devarianted_wkt
{
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>
{
OutputStream& m_os;
bool m_force_closure;
visitor(OutputStream& os)
visitor(OutputStream& os, bool force_closure)
: m_os(os)
, m_force_closure(force_closure)
{}
template <typename Geometry>
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>
static inline void apply(
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:
inline wkt_manipulator(Geometry const& g)
inline wkt_manipulator(Geometry const& g, bool force_closure = true)
: m_geometry(g)
, m_force_closure(force_closure)
{}
template <typename Char, typename Traits>
@ -482,13 +491,14 @@ public:
std::basic_ostream<Char, Traits>& os,
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();
return os;
}
private:
Geometry const& m_geometry;
bool m_force_closure;
};
/*!