add boost on mac
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_ALWAYS_SIMPLE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_ALWAYS_SIMPLE_HPP
|
||||
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/is_simple.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace is_simple
|
||||
{
|
||||
|
||||
|
||||
template <typename Geometry>
|
||||
struct always_simple
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry const&, Strategy const&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::is_simple
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
// A point is always simple
|
||||
template <typename Point>
|
||||
struct is_simple<Point, point_tag>
|
||||
: detail::is_simple::always_simple<Point>
|
||||
{};
|
||||
|
||||
|
||||
// A valid segment is always simple.
|
||||
// A segment is a curve.
|
||||
// A curve is simple if it does not pass through the same point twice,
|
||||
// with the possible exception of its two endpoints
|
||||
//
|
||||
// Reference: OGC 06-103r4 (6.1.6.1)
|
||||
template <typename Segment>
|
||||
struct is_simple<Segment, segment_tag>
|
||||
: detail::is_simple::always_simple<Segment>
|
||||
{};
|
||||
|
||||
|
||||
// A valid box is always simple
|
||||
// A box is a Polygon, and it satisfies the conditions for Polygon validity.
|
||||
//
|
||||
// Reference (for polygon validity): OGC 06-103r4 (6.1.11.1)
|
||||
template <typename Box>
|
||||
struct is_simple<Box, box_tag>
|
||||
: detail::is_simple::always_simple<Box>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_ALWAYS_SIMPLE_HPP
|
||||
@@ -0,0 +1,157 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_AREAL_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_AREAL_HPP
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/ring_type.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/is_simple/failure_policy.hpp>
|
||||
#include <boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/is_simple.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace is_simple
|
||||
{
|
||||
|
||||
|
||||
template <typename Ring>
|
||||
struct is_simple_ring
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Ring const& ring, Strategy const&)
|
||||
{
|
||||
return apply(ring);
|
||||
}
|
||||
|
||||
static inline bool apply(Ring const& ring)
|
||||
{
|
||||
simplicity_failure_policy policy;
|
||||
return ! boost::empty(ring)
|
||||
&& ! detail::is_valid::has_duplicates
|
||||
<
|
||||
Ring, geometry::closure<Ring>::value
|
||||
>::apply(ring, policy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Polygon>
|
||||
class is_simple_polygon
|
||||
{
|
||||
private:
|
||||
template <typename InteriorRings>
|
||||
static inline
|
||||
bool are_simple_interior_rings(InteriorRings const& interior_rings)
|
||||
{
|
||||
return
|
||||
detail::check_iterator_range
|
||||
<
|
||||
is_simple_ring
|
||||
<
|
||||
typename boost::range_value<InteriorRings>::type
|
||||
>
|
||||
>::apply(boost::begin(interior_rings),
|
||||
boost::end(interior_rings));
|
||||
}
|
||||
|
||||
public:
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Polygon const& polygon, Strategy const&)
|
||||
{
|
||||
return apply(polygon);
|
||||
}
|
||||
|
||||
static inline bool apply(Polygon const& polygon)
|
||||
{
|
||||
return
|
||||
is_simple_ring
|
||||
<
|
||||
typename ring_type<Polygon>::type
|
||||
>::apply(exterior_ring(polygon))
|
||||
&&
|
||||
are_simple_interior_rings(geometry::interior_rings(polygon));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::is_simple
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
// A Ring is a Polygon.
|
||||
// A Polygon is always a simple geometric object provided that it is valid.
|
||||
//
|
||||
// Reference (for polygon validity): OGC 06-103r4 (6.1.11.1)
|
||||
template <typename Ring>
|
||||
struct is_simple<Ring, ring_tag>
|
||||
: detail::is_simple::is_simple_ring<Ring>
|
||||
{};
|
||||
|
||||
|
||||
// A Polygon is always a simple geometric object provided that it is valid.
|
||||
//
|
||||
// Reference (for validity of Polygons): OGC 06-103r4 (6.1.11.1)
|
||||
template <typename Polygon>
|
||||
struct is_simple<Polygon, polygon_tag>
|
||||
: detail::is_simple::is_simple_polygon<Polygon>
|
||||
{};
|
||||
|
||||
|
||||
// Not clear what the definition is.
|
||||
// Right now we consider a MultiPolygon as simple if it is valid.
|
||||
//
|
||||
// Reference (for validity of MultiPolygons): OGC 06-103r4 (6.1.14)
|
||||
template <typename MultiPolygon>
|
||||
struct is_simple<MultiPolygon, multi_polygon_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(MultiPolygon const& multipolygon, Strategy const&)
|
||||
{
|
||||
return
|
||||
detail::check_iterator_range
|
||||
<
|
||||
detail::is_simple::is_simple_polygon
|
||||
<
|
||||
typename boost::range_value<MultiPolygon>::type
|
||||
>,
|
||||
true // allow empty multi-polygon
|
||||
>::apply(boost::begin(multipolygon), boost::end(multipolygon));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_AREAL_HPP
|
||||
@@ -0,0 +1,113 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_DEBUG_PRINT_BOUNDARY_POINTS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_DEBUG_PRINT_BOUNDARY_POINTS_HPP
|
||||
|
||||
#ifdef BOOST_GEOMETRY_TEST_DEBUG
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
#include <boost/geometry/io/dsv/write.hpp>
|
||||
|
||||
#include <boost/geometry/policies/compare.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/equals.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
#endif // BOOST_GEOMETRY_TEST_DEBUG
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace detail { namespace is_simple
|
||||
{
|
||||
|
||||
|
||||
#ifdef BOOST_GEOMETRY_TEST_DEBUG
|
||||
template <typename Linear, typename Tag = typename tag<Linear>::type>
|
||||
struct debug_boundary_points_printer
|
||||
: not_implemented<Linear>
|
||||
{};
|
||||
|
||||
template <typename Linestring>
|
||||
struct debug_boundary_points_printer<Linestring, linestring_tag>
|
||||
{
|
||||
static inline void apply(Linestring const& linestring)
|
||||
{
|
||||
std::cout << "boundary points: ";
|
||||
std::cout << " " << geometry::dsv(range::front(linestring));
|
||||
std::cout << " " << geometry::dsv(range::back(linestring));
|
||||
std::cout << std::endl << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename MultiLinestring>
|
||||
struct debug_boundary_points_printer<MultiLinestring, multi_linestring_tag>
|
||||
{
|
||||
static inline void apply(MultiLinestring const& multilinestring)
|
||||
{
|
||||
typedef typename point_type<MultiLinestring>::type point_type;
|
||||
typedef std::vector<point_type> point_vector;
|
||||
|
||||
point_vector boundary_points;
|
||||
for (typename boost::range_iterator<MultiLinestring const>::type it
|
||||
= boost::begin(multilinestring);
|
||||
it != boost::end(multilinestring); ++it)
|
||||
{
|
||||
if ( boost::size(*it) > 1
|
||||
&& !geometry::equals(range::front(*it), range::back(*it)) )
|
||||
{
|
||||
boundary_points.push_back( range::front(*it) );
|
||||
boundary_points.push_back( range::back(*it) );
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(boundary_points.begin(), boundary_points.end(),
|
||||
geometry::less<point_type>());
|
||||
|
||||
std::cout << "boundary points: ";
|
||||
for (typename point_vector::const_iterator
|
||||
pit = boundary_points.begin();
|
||||
pit != boundary_points.end(); ++pit)
|
||||
{
|
||||
std::cout << " " << geometry::dsv(*pit);
|
||||
}
|
||||
std::cout << std::endl << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Linear>
|
||||
inline void debug_print_boundary_points(Linear const& linear)
|
||||
{
|
||||
debug_boundary_points_printer<Linear>::apply(linear);
|
||||
}
|
||||
#else
|
||||
template <typename Linear>
|
||||
inline void debug_print_boundary_points(Linear const&)
|
||||
{
|
||||
}
|
||||
#endif // BOOST_GEOMETRY_TEST_DEBUG
|
||||
|
||||
|
||||
}} // namespace detail::is_simple
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_DEBUG_PRINT_BOUNDARY_POINTS_HPP
|
||||
@@ -0,0 +1,53 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_FAILURE_POLICY_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_FAILURE_POLICY_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/validity_failure_type.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace is_simple
|
||||
{
|
||||
|
||||
|
||||
struct simplicity_failure_policy
|
||||
{
|
||||
template <validity_failure_type Failure>
|
||||
static inline bool apply()
|
||||
{
|
||||
return Failure == no_failure;
|
||||
}
|
||||
|
||||
template <validity_failure_type Failure, typename Data>
|
||||
static inline bool apply(Data const&)
|
||||
{
|
||||
return apply<Failure>();
|
||||
}
|
||||
|
||||
template <validity_failure_type Failure, typename Data1, typename Data2>
|
||||
static inline bool apply(Data1 const&, Data2 const&)
|
||||
{
|
||||
return apply<Failure>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::is_simple
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_FAILURE_POLICY_HPP
|
||||
@@ -0,0 +1,18 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_IMPLEMENTATION_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_IMPLEMENTATION_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/detail/is_simple/always_simple.hpp>
|
||||
#include <boost/geometry/algorithms/detail/is_simple/areal.hpp>
|
||||
#include <boost/geometry/algorithms/detail/is_simple/linear.hpp>
|
||||
#include <boost/geometry/algorithms/detail/is_simple/multipoint.hpp>
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_IMPLEMENTATION_HPP
|
||||
@@ -0,0 +1,141 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_INTERFACE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_INTERFACE_HPP
|
||||
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/is_simple.hpp>
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/intersection.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace resolve_strategy
|
||||
{
|
||||
|
||||
struct is_simple
|
||||
{
|
||||
template <typename Geometry, typename Strategy>
|
||||
static inline bool apply(Geometry const& geometry,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return dispatch::is_simple<Geometry>::apply(geometry, strategy);
|
||||
}
|
||||
|
||||
template <typename Geometry>
|
||||
static inline bool apply(Geometry const& geometry,
|
||||
default_strategy)
|
||||
{
|
||||
// NOTE: Currently the strategy is only used for Linear geometries
|
||||
typedef typename strategy::intersection::services::default_strategy
|
||||
<
|
||||
typename cs_tag<Geometry>::type
|
||||
>::type strategy_type;
|
||||
|
||||
return dispatch::is_simple<Geometry>::apply(geometry, strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_strategy
|
||||
|
||||
namespace resolve_variant
|
||||
{
|
||||
|
||||
template <typename Geometry>
|
||||
struct is_simple
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry const& geometry, Strategy const& strategy)
|
||||
{
|
||||
concepts::check<Geometry const>();
|
||||
|
||||
return resolve_strategy::is_simple::apply(geometry, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct is_simple<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor : boost::static_visitor<bool>
|
||||
{
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry>
|
||||
bool operator()(Geometry const& geometry) const
|
||||
{
|
||||
return is_simple<Geometry>::apply(geometry, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool
|
||||
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(strategy), geometry);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_variant
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check{is simple}
|
||||
\ingroup is_simple
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Strategy \tparam_strategy{Is_simple}
|
||||
\param geometry \param_geometry
|
||||
\param strategy \param_strategy{is_simple}
|
||||
\return \return_check{is simple}
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{[include reference/algorithms/is_simple.qbk]}
|
||||
*/
|
||||
template <typename Geometry, typename Strategy>
|
||||
inline bool is_simple(Geometry const& geometry, Strategy const& strategy)
|
||||
{
|
||||
return resolve_variant::is_simple<Geometry>::apply(geometry, strategy);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check{is simple}
|
||||
\ingroup is_simple
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry
|
||||
\return \return_check{is simple}
|
||||
|
||||
\qbk{[include reference/algorithms/is_simple.qbk]}
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline bool is_simple(Geometry const& geometry)
|
||||
{
|
||||
return resolve_variant::is_simple<Geometry>::apply(geometry, default_strategy());
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_INTERFACE_HPP
|
||||
@@ -0,0 +1,364 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_LINEAR_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_LINEAR_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <deque>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/core/assert.hpp>
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
#include <boost/geometry/policies/predicate_based_interrupt_policy.hpp>
|
||||
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
|
||||
#include <boost/geometry/policies/robustness/segment_ratio.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/equals.hpp>
|
||||
#include <boost/geometry/algorithms/intersects.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/signed_size_type.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/disjoint/linear_linear.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
|
||||
#include <boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp>
|
||||
#include <boost/geometry/algorithms/detail/is_valid/has_spikes.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/is_simple/debug_print_boundary_points.hpp>
|
||||
#include <boost/geometry/algorithms/detail/is_simple/failure_policy.hpp>
|
||||
#include <boost/geometry/algorithms/detail/is_valid/debug_print_turns.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/is_simple.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/intersection.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace is_simple
|
||||
{
|
||||
|
||||
|
||||
template <typename Turn>
|
||||
inline bool check_segment_indices(Turn const& turn,
|
||||
signed_size_type last_index)
|
||||
{
|
||||
return
|
||||
(turn.operations[0].seg_id.segment_index == 0
|
||||
&& turn.operations[1].seg_id.segment_index == last_index)
|
||||
||
|
||||
(turn.operations[0].seg_id.segment_index == 0
|
||||
&& turn.operations[1].seg_id.segment_index == last_index);
|
||||
}
|
||||
|
||||
|
||||
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
|
||||
class is_acceptable_turn
|
||||
: not_implemented<Geometry>
|
||||
{};
|
||||
|
||||
template <typename Linestring>
|
||||
class is_acceptable_turn<Linestring, linestring_tag>
|
||||
{
|
||||
public:
|
||||
is_acceptable_turn(Linestring const& linestring)
|
||||
: m_linestring(linestring)
|
||||
, m_is_closed(geometry::equals(range::front(linestring),
|
||||
range::back(linestring)))
|
||||
{}
|
||||
|
||||
template <typename Turn>
|
||||
inline bool apply(Turn const& turn) const
|
||||
{
|
||||
BOOST_GEOMETRY_ASSERT(boost::size(m_linestring) > 1);
|
||||
return m_is_closed
|
||||
&& turn.method == overlay::method_none
|
||||
&& check_segment_indices(turn, boost::size(m_linestring) - 2)
|
||||
&& turn.operations[0].fraction.is_zero();
|
||||
}
|
||||
|
||||
private:
|
||||
Linestring const& m_linestring;
|
||||
bool const m_is_closed;
|
||||
};
|
||||
|
||||
template <typename MultiLinestring>
|
||||
class is_acceptable_turn<MultiLinestring, multi_linestring_tag>
|
||||
{
|
||||
private:
|
||||
typedef typename boost::range_value<MultiLinestring>::type linestring_type;
|
||||
typedef is_acceptable_turn<linestring_type> base_type;
|
||||
|
||||
template <typename Point, typename Linestring>
|
||||
static inline bool is_boundary_point_of(Point const& point,
|
||||
Linestring const& linestring)
|
||||
{
|
||||
BOOST_GEOMETRY_ASSERT(boost::size(linestring) > 1);
|
||||
return
|
||||
! geometry::equals(range::front(linestring),
|
||||
range::back(linestring))
|
||||
&&
|
||||
(geometry::equals(point, range::front(linestring))
|
||||
|| geometry::equals(point, range::back(linestring)));
|
||||
}
|
||||
|
||||
template <typename Turn, typename Linestring>
|
||||
static inline bool is_closing_point_of(Turn const& turn,
|
||||
Linestring const& linestring)
|
||||
{
|
||||
BOOST_GEOMETRY_ASSERT(boost::size(linestring) > 1);
|
||||
return
|
||||
turn.method == overlay::method_none
|
||||
&&
|
||||
check_segment_indices(turn, boost::size(linestring) - 2)
|
||||
&&
|
||||
geometry::equals(range::front(linestring), range::back(linestring))
|
||||
&&
|
||||
turn.operations[0].fraction.is_zero();
|
||||
;
|
||||
}
|
||||
|
||||
template <typename Linestring1, typename Linestring2>
|
||||
static inline bool have_same_boundary_points(Linestring1 const& ls1,
|
||||
Linestring2 const& ls2)
|
||||
{
|
||||
return
|
||||
geometry::equals(range::front(ls1), range::front(ls2))
|
||||
?
|
||||
geometry::equals(range::back(ls1), range::back(ls2))
|
||||
:
|
||||
(geometry::equals(range::front(ls1), range::back(ls2))
|
||||
&&
|
||||
geometry::equals(range::back(ls1), range::front(ls2)))
|
||||
;
|
||||
}
|
||||
|
||||
public:
|
||||
is_acceptable_turn(MultiLinestring const& multilinestring)
|
||||
: m_multilinestring(multilinestring)
|
||||
{}
|
||||
|
||||
template <typename Turn>
|
||||
inline bool apply(Turn const& turn) const
|
||||
{
|
||||
linestring_type const& ls1 =
|
||||
range::at(m_multilinestring, turn.operations[0].seg_id.multi_index);
|
||||
|
||||
linestring_type const& ls2 =
|
||||
range::at(m_multilinestring, turn.operations[1].seg_id.multi_index);
|
||||
|
||||
if (turn.operations[0].seg_id.multi_index
|
||||
== turn.operations[1].seg_id.multi_index)
|
||||
{
|
||||
return is_closing_point_of(turn, ls1);
|
||||
}
|
||||
|
||||
return
|
||||
is_boundary_point_of(turn.point, ls1)
|
||||
&& is_boundary_point_of(turn.point, ls2)
|
||||
&&
|
||||
( boost::size(ls1) != 2
|
||||
|| boost::size(ls2) != 2
|
||||
|| ! have_same_boundary_points(ls1, ls2) );
|
||||
}
|
||||
|
||||
private:
|
||||
MultiLinestring const& m_multilinestring;
|
||||
};
|
||||
|
||||
|
||||
template <typename Linear, typename Strategy>
|
||||
inline bool has_self_intersections(Linear const& linear, Strategy const& strategy)
|
||||
{
|
||||
typedef typename point_type<Linear>::type point_type;
|
||||
|
||||
// compute self turns
|
||||
typedef detail::overlay::turn_info
|
||||
<
|
||||
point_type,
|
||||
geometry::segment_ratio
|
||||
<
|
||||
typename geometry::coordinate_type<point_type>::type
|
||||
>
|
||||
> turn_info;
|
||||
|
||||
std::deque<turn_info> turns;
|
||||
|
||||
typedef detail::overlay::get_turn_info
|
||||
<
|
||||
detail::disjoint::assign_disjoint_policy
|
||||
> turn_policy;
|
||||
|
||||
is_acceptable_turn<Linear> predicate(linear);
|
||||
detail::overlay::predicate_based_interrupt_policy
|
||||
<
|
||||
is_acceptable_turn<Linear>
|
||||
> interrupt_policy(predicate);
|
||||
|
||||
// TODO: skip_adjacent should be set to false
|
||||
detail::self_get_turn_points::get_turns
|
||||
<
|
||||
false, turn_policy
|
||||
>::apply(linear,
|
||||
strategy,
|
||||
detail::no_rescale_policy(),
|
||||
turns,
|
||||
interrupt_policy, 0, true);
|
||||
|
||||
detail::is_valid::debug_print_turns(turns.begin(), turns.end());
|
||||
debug_print_boundary_points(linear);
|
||||
|
||||
return interrupt_policy.has_intersections;
|
||||
}
|
||||
|
||||
|
||||
template <typename Linestring, bool CheckSelfIntersections = true>
|
||||
struct is_simple_linestring
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Linestring const& linestring,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
simplicity_failure_policy policy;
|
||||
return ! boost::empty(linestring)
|
||||
&& ! detail::is_valid::has_duplicates
|
||||
<
|
||||
Linestring, closed
|
||||
>::apply(linestring, policy)
|
||||
&& ! detail::is_valid::has_spikes
|
||||
<
|
||||
Linestring, closed
|
||||
>::apply(linestring, policy, strategy.get_side_strategy());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Linestring>
|
||||
struct is_simple_linestring<Linestring, true>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Linestring const& linestring,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return is_simple_linestring
|
||||
<
|
||||
Linestring, false
|
||||
>::apply(linestring, strategy)
|
||||
&& ! has_self_intersections(linestring, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename MultiLinestring>
|
||||
struct is_simple_multilinestring
|
||||
{
|
||||
private:
|
||||
template <typename Strategy>
|
||||
struct per_linestring
|
||||
{
|
||||
per_linestring(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Linestring>
|
||||
inline bool apply(Linestring const& linestring) const
|
||||
{
|
||||
return detail::is_simple::is_simple_linestring
|
||||
<
|
||||
Linestring,
|
||||
false // do not compute self-intersections
|
||||
>::apply(linestring, m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
public:
|
||||
template <typename Strategy>
|
||||
static inline bool apply(MultiLinestring const& multilinestring,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef per_linestring<Strategy> per_ls;
|
||||
|
||||
// check each of the linestrings for simplicity
|
||||
// but do not compute self-intersections yet; these will be
|
||||
// computed for the entire multilinestring
|
||||
if ( ! detail::check_iterator_range
|
||||
<
|
||||
per_ls, // do not compute self-intersections
|
||||
true // allow empty multilinestring
|
||||
>::apply(boost::begin(multilinestring),
|
||||
boost::end(multilinestring),
|
||||
per_ls(strategy))
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ! has_self_intersections(multilinestring, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
}} // namespace detail::is_simple
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
// A linestring is a curve.
|
||||
// A curve is simple if it does not pass through the same point twice,
|
||||
// with the possible exception of its two endpoints
|
||||
//
|
||||
// Reference: OGC 06-103r4 (6.1.6.1)
|
||||
template <typename Linestring>
|
||||
struct is_simple<Linestring, linestring_tag>
|
||||
: detail::is_simple::is_simple_linestring<Linestring>
|
||||
{};
|
||||
|
||||
|
||||
// A MultiLinestring is a MultiCurve
|
||||
// A MultiCurve is simple if all of its elements are simple and the
|
||||
// only intersections between any two elements occur at Points that
|
||||
// are on the boundaries of both elements.
|
||||
//
|
||||
// Reference: OGC 06-103r4 (6.1.8.1; Fig. 9)
|
||||
template <typename MultiLinestring>
|
||||
struct is_simple<MultiLinestring, multi_linestring_tag>
|
||||
: detail::is_simple::is_simple_multilinestring<MultiLinestring>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_LINEAR_HPP
|
||||
@@ -0,0 +1,91 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_MULTIPOINT_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_MULTIPOINT_HPP
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/policies/compare.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp>
|
||||
#include <boost/geometry/algorithms/detail/is_simple/failure_policy.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/is_simple.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace is_simple
|
||||
{
|
||||
|
||||
|
||||
template <typename MultiPoint>
|
||||
struct is_simple_multipoint
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(MultiPoint const& multipoint, Strategy const&)
|
||||
{
|
||||
if (boost::empty(multipoint))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
MultiPoint mp(multipoint);
|
||||
std::sort(boost::begin(mp), boost::end(mp),
|
||||
geometry::less<typename point_type<MultiPoint>::type>());
|
||||
|
||||
simplicity_failure_policy policy;
|
||||
return !detail::is_valid::has_duplicates
|
||||
<
|
||||
MultiPoint, closed
|
||||
>::apply(mp, policy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::is_simple
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
// A MultiPoint is simple if no two Points in the MultiPoint are equal
|
||||
// (have identical coordinate values in X and Y)
|
||||
//
|
||||
// Reference: OGC 06-103r4 (6.1.5)
|
||||
template <typename MultiPoint>
|
||||
struct is_simple<MultiPoint, multi_point_tag>
|
||||
: detail::is_simple::is_simple_multipoint<MultiPoint>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_MULTIPOINT_HPP
|
||||
Reference in New Issue
Block a user