mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-11 13:34:10 +00:00
Merge pull request #397 from awulkiew/feature/relops_multi_point
Add missing relational operations for MultiPoint/Geometry
This commit is contained in:
commit
1a605740cc
@ -20,453 +20,8 @@
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/geometry/algorithms/detail/covered_by/interface.hpp>
|
||||
#include <boost/geometry/algorithms/detail/covered_by/implementation.hpp>
|
||||
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
#include <boost/geometry/algorithms/within.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
|
||||
#include <boost/geometry/strategies/cartesian/box_in_box.hpp>
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace covered_by {
|
||||
|
||||
struct use_point_in_geometry
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
|
||||
{
|
||||
return detail::within::point_in_geometry(geometry1, geometry2, strategy) >= 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct use_relate
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
|
||||
{
|
||||
typedef typename detail::de9im::static_mask_covered_by_type
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::type covered_by_mask;
|
||||
return geometry::relate(geometry1, geometry2, covered_by_mask(), strategy);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::covered_by
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Tag1 = typename tag<Geometry1>::type,
|
||||
typename Tag2 = typename tag<Geometry2>::type
|
||||
>
|
||||
struct covered_by
|
||||
: not_implemented<Tag1, Tag2>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Point, typename Box>
|
||||
struct covered_by<Point, Box, point_tag, box_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
|
||||
{
|
||||
::boost::ignore_unused_variable_warning(strategy);
|
||||
return strategy.apply(point, box);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box1, typename Box2>
|
||||
struct covered_by<Box1, Box2, box_tag, box_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
|
||||
{
|
||||
assert_dimension_equal<Box1, Box2>();
|
||||
::boost::ignore_unused_variable_warning(strategy);
|
||||
return strategy.apply(box1, box2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// P/P
|
||||
|
||||
template <typename Point1, typename Point2>
|
||||
struct covered_by<Point1, Point2, point_tag, point_tag>
|
||||
: public detail::covered_by::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename Point, typename MultiPoint>
|
||||
struct covered_by<Point, MultiPoint, point_tag, multi_point_tag>
|
||||
: public detail::covered_by::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename Point>
|
||||
struct covered_by<MultiPoint, Point, multi_point_tag, point_tag>
|
||||
: public detail::within::multi_point_point
|
||||
{};
|
||||
|
||||
template <typename MultiPoint1, typename MultiPoint2>
|
||||
struct covered_by<MultiPoint1, MultiPoint2, multi_point_tag, multi_point_tag>
|
||||
: public detail::within::multi_point_multi_point
|
||||
{};
|
||||
|
||||
// P/L
|
||||
|
||||
template <typename Point, typename Segment>
|
||||
struct covered_by<Point, Segment, point_tag, segment_tag>
|
||||
: public detail::covered_by::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename Point, typename Linestring>
|
||||
struct covered_by<Point, Linestring, point_tag, linestring_tag>
|
||||
: public detail::covered_by::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename Point, typename MultiLinestring>
|
||||
struct covered_by<Point, MultiLinestring, point_tag, multi_linestring_tag>
|
||||
: public detail::covered_by::use_point_in_geometry
|
||||
{};
|
||||
|
||||
// P/A
|
||||
|
||||
template <typename Point, typename Ring>
|
||||
struct covered_by<Point, Ring, point_tag, ring_tag>
|
||||
: public detail::covered_by::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename Point, typename Polygon>
|
||||
struct covered_by<Point, Polygon, point_tag, polygon_tag>
|
||||
: public detail::covered_by::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename Point, typename MultiPolygon>
|
||||
struct covered_by<Point, MultiPolygon, point_tag, multi_polygon_tag>
|
||||
: public detail::covered_by::use_point_in_geometry
|
||||
{};
|
||||
|
||||
// L/L
|
||||
|
||||
template <typename Linestring1, typename Linestring2>
|
||||
struct covered_by<Linestring1, Linestring2, linestring_tag, linestring_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename Linestring, typename MultiLinestring>
|
||||
struct covered_by<Linestring, MultiLinestring, linestring_tag, multi_linestring_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring, typename Linestring>
|
||||
struct covered_by<MultiLinestring, Linestring, multi_linestring_tag, linestring_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring1, typename MultiLinestring2>
|
||||
struct covered_by<MultiLinestring1, MultiLinestring2, multi_linestring_tag, multi_linestring_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
// L/A
|
||||
|
||||
template <typename Linestring, typename Ring>
|
||||
struct covered_by<Linestring, Ring, linestring_tag, ring_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring, typename Ring>
|
||||
struct covered_by<MultiLinestring, Ring, multi_linestring_tag, ring_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename Linestring, typename Polygon>
|
||||
struct covered_by<Linestring, Polygon, linestring_tag, polygon_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring, typename Polygon>
|
||||
struct covered_by<MultiLinestring, Polygon, multi_linestring_tag, polygon_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename Linestring, typename MultiPolygon>
|
||||
struct covered_by<Linestring, MultiPolygon, linestring_tag, multi_polygon_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring, typename MultiPolygon>
|
||||
struct covered_by<MultiLinestring, MultiPolygon, multi_linestring_tag, multi_polygon_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
// A/A
|
||||
|
||||
template <typename Ring1, typename Ring2>
|
||||
struct covered_by<Ring1, Ring2, ring_tag, ring_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename Ring, typename Polygon>
|
||||
struct covered_by<Ring, Polygon, ring_tag, polygon_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename Polygon, typename Ring>
|
||||
struct covered_by<Polygon, Ring, polygon_tag, ring_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename Polygon1, typename Polygon2>
|
||||
struct covered_by<Polygon1, Polygon2, polygon_tag, polygon_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename Ring, typename MultiPolygon>
|
||||
struct covered_by<Ring, MultiPolygon, ring_tag, multi_polygon_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiPolygon, typename Ring>
|
||||
struct covered_by<MultiPolygon, Ring, multi_polygon_tag, ring_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename Polygon, typename MultiPolygon>
|
||||
struct covered_by<Polygon, MultiPolygon, polygon_tag, multi_polygon_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiPolygon, typename Polygon>
|
||||
struct covered_by<MultiPolygon, Polygon, multi_polygon_tag, polygon_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiPolygon1, typename MultiPolygon2>
|
||||
struct covered_by<MultiPolygon1, MultiPolygon2, multi_polygon_tag, multi_polygon_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
namespace resolve_strategy {
|
||||
|
||||
struct covered_by
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concepts::within::check
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
|
||||
Strategy
|
||||
>();
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
assert_dimension_equal<Geometry1, Geometry2>();
|
||||
|
||||
return dispatch::covered_by<Geometry1, Geometry2>::apply(geometry1,
|
||||
geometry2,
|
||||
strategy);
|
||||
}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
default_strategy)
|
||||
{
|
||||
typedef typename strategy::covered_by::services::default_strategy
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
return covered_by::apply(geometry1, geometry2, strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_strategy
|
||||
|
||||
|
||||
namespace resolve_variant {
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct covered_by
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return resolve_strategy::covered_by
|
||||
::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
|
||||
struct covered_by<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: boost::static_visitor<bool>
|
||||
{
|
||||
Geometry2 const& m_geometry2;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry2 const& geometry2, Strategy const& strategy)
|
||||
: m_geometry2(geometry2), m_strategy(strategy) {}
|
||||
|
||||
template <typename Geometry1>
|
||||
bool operator()(Geometry1 const& geometry1) const
|
||||
{
|
||||
return covered_by<Geometry1, Geometry2>
|
||||
::apply(geometry1, m_geometry2, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool
|
||||
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct covered_by<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: boost::static_visitor<bool>
|
||||
{
|
||||
Geometry1 const& m_geometry1;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry1 const& geometry1, Strategy const& strategy)
|
||||
: m_geometry1(geometry1), m_strategy(strategy) {}
|
||||
|
||||
template <typename Geometry2>
|
||||
bool operator()(Geometry2 const& geometry2) const
|
||||
{
|
||||
return covered_by<Geometry1, Geometry2>
|
||||
::apply(m_geometry1, geometry2, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool
|
||||
apply(Geometry1 const& geometry1,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
template <
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T1),
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T2)
|
||||
>
|
||||
struct covered_by<
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
|
||||
>
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: boost::static_visitor<bool>
|
||||
{
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Strategy const& strategy): m_strategy(strategy) {}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
bool operator()(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2) const
|
||||
{
|
||||
return covered_by<Geometry1, Geometry2>
|
||||
::apply(geometry1, geometry2, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool
|
||||
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_variant
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check12{is inside or on border}
|
||||
\ingroup covered_by
|
||||
\details \details_check12{covered_by, is inside or on border}.
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry which might be inside or on the border of the second geometry
|
||||
\param geometry2 \param_geometry which might cover the first geometry
|
||||
\return true if geometry1 is inside of or on the border of geometry2,
|
||||
else false
|
||||
\note The default strategy is used for covered_by detection
|
||||
|
||||
\qbk{[include reference/algorithms/covered_by.qbk]}
|
||||
|
||||
*/
|
||||
template<typename Geometry1, typename Geometry2>
|
||||
inline bool covered_by(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
return resolve_variant::covered_by<Geometry1, Geometry2>
|
||||
::apply(geometry1, geometry2, default_strategy());
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief \brief_check12{is inside or on border} \brief_strategy
|
||||
\ingroup covered_by
|
||||
\details \details_check12{covered_by, is inside or on border}, \brief_strategy. \details_strategy_reasons
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry which might be inside or on the border of the second geometry
|
||||
\param geometry2 \param_geometry which might cover the first geometry
|
||||
\param strategy strategy to be used
|
||||
\return true if geometry1 is inside of or on the border of geometry2,
|
||||
else false
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{[include reference/algorithms/covered_by.qbk]}
|
||||
|
||||
*/
|
||||
template<typename Geometry1, typename Geometry2, typename Strategy>
|
||||
inline bool covered_by(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return resolve_variant::covered_by<Geometry1, Geometry2>
|
||||
::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP
|
||||
|
@ -0,0 +1,280 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2013, 2014, 2017.
|
||||
// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_COVERED_BY_IMPLEMENTATION_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_COVERED_BY_IMPLEMENTATION_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/covered_by/interface.hpp>
|
||||
#include <boost/geometry/algorithms/detail/within/implementation.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace covered_by {
|
||||
|
||||
struct use_point_in_geometry
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
|
||||
{
|
||||
return detail::within::point_in_geometry(geometry1, geometry2, strategy) >= 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct use_relate
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
|
||||
{
|
||||
typedef typename detail::de9im::static_mask_covered_by_type
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::type covered_by_mask;
|
||||
return geometry::relate(geometry1, geometry2, covered_by_mask(), strategy);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::covered_by
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template <typename Point, typename Box>
|
||||
struct covered_by<Point, Box, point_tag, box_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
|
||||
{
|
||||
::boost::ignore_unused_variable_warning(strategy);
|
||||
return strategy.apply(point, box);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box1, typename Box2>
|
||||
struct covered_by<Box1, Box2, box_tag, box_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
|
||||
{
|
||||
assert_dimension_equal<Box1, Box2>();
|
||||
::boost::ignore_unused_variable_warning(strategy);
|
||||
return strategy.apply(box1, box2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// P/P
|
||||
|
||||
template <typename Point1, typename Point2>
|
||||
struct covered_by<Point1, Point2, point_tag, point_tag>
|
||||
: public detail::covered_by::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename Point, typename MultiPoint>
|
||||
struct covered_by<Point, MultiPoint, point_tag, multi_point_tag>
|
||||
: public detail::covered_by::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename Point>
|
||||
struct covered_by<MultiPoint, Point, multi_point_tag, point_tag>
|
||||
: public detail::within::multi_point_point
|
||||
{};
|
||||
|
||||
template <typename MultiPoint1, typename MultiPoint2>
|
||||
struct covered_by<MultiPoint1, MultiPoint2, multi_point_tag, multi_point_tag>
|
||||
: public detail::within::multi_point_multi_point
|
||||
{};
|
||||
|
||||
// P/L
|
||||
|
||||
template <typename Point, typename Segment>
|
||||
struct covered_by<Point, Segment, point_tag, segment_tag>
|
||||
: public detail::covered_by::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename Point, typename Linestring>
|
||||
struct covered_by<Point, Linestring, point_tag, linestring_tag>
|
||||
: public detail::covered_by::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename Point, typename MultiLinestring>
|
||||
struct covered_by<Point, MultiLinestring, point_tag, multi_linestring_tag>
|
||||
: public detail::covered_by::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename Segment>
|
||||
struct covered_by<MultiPoint, Segment, multi_point_tag, segment_tag>
|
||||
: public detail::within::multi_point_single_geometry<false>
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename Linestring>
|
||||
struct covered_by<MultiPoint, Linestring, multi_point_tag, linestring_tag>
|
||||
: public detail::within::multi_point_single_geometry<false>
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename MultiLinestring>
|
||||
struct covered_by<MultiPoint, MultiLinestring, multi_point_tag, multi_linestring_tag>
|
||||
: public detail::within::multi_point_multi_geometry<false>
|
||||
{};
|
||||
|
||||
// P/A
|
||||
|
||||
template <typename Point, typename Ring>
|
||||
struct covered_by<Point, Ring, point_tag, ring_tag>
|
||||
: public detail::covered_by::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename Point, typename Polygon>
|
||||
struct covered_by<Point, Polygon, point_tag, polygon_tag>
|
||||
: public detail::covered_by::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename Point, typename MultiPolygon>
|
||||
struct covered_by<Point, MultiPolygon, point_tag, multi_polygon_tag>
|
||||
: public detail::covered_by::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename Ring>
|
||||
struct covered_by<MultiPoint, Ring, multi_point_tag, ring_tag>
|
||||
: public detail::within::multi_point_single_geometry<false>
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename Polygon>
|
||||
struct covered_by<MultiPoint, Polygon, multi_point_tag, polygon_tag>
|
||||
: public detail::within::multi_point_single_geometry<false>
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename MultiPolygon>
|
||||
struct covered_by<MultiPoint, MultiPolygon, multi_point_tag, multi_polygon_tag>
|
||||
: public detail::within::multi_point_multi_geometry<false>
|
||||
{};
|
||||
|
||||
// L/L
|
||||
|
||||
template <typename Linestring1, typename Linestring2>
|
||||
struct covered_by<Linestring1, Linestring2, linestring_tag, linestring_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename Linestring, typename MultiLinestring>
|
||||
struct covered_by<Linestring, MultiLinestring, linestring_tag, multi_linestring_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring, typename Linestring>
|
||||
struct covered_by<MultiLinestring, Linestring, multi_linestring_tag, linestring_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring1, typename MultiLinestring2>
|
||||
struct covered_by<MultiLinestring1, MultiLinestring2, multi_linestring_tag, multi_linestring_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
// L/A
|
||||
|
||||
template <typename Linestring, typename Ring>
|
||||
struct covered_by<Linestring, Ring, linestring_tag, ring_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring, typename Ring>
|
||||
struct covered_by<MultiLinestring, Ring, multi_linestring_tag, ring_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename Linestring, typename Polygon>
|
||||
struct covered_by<Linestring, Polygon, linestring_tag, polygon_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring, typename Polygon>
|
||||
struct covered_by<MultiLinestring, Polygon, multi_linestring_tag, polygon_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename Linestring, typename MultiPolygon>
|
||||
struct covered_by<Linestring, MultiPolygon, linestring_tag, multi_polygon_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring, typename MultiPolygon>
|
||||
struct covered_by<MultiLinestring, MultiPolygon, multi_linestring_tag, multi_polygon_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
// A/A
|
||||
|
||||
template <typename Ring1, typename Ring2>
|
||||
struct covered_by<Ring1, Ring2, ring_tag, ring_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename Ring, typename Polygon>
|
||||
struct covered_by<Ring, Polygon, ring_tag, polygon_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename Polygon, typename Ring>
|
||||
struct covered_by<Polygon, Ring, polygon_tag, ring_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename Polygon1, typename Polygon2>
|
||||
struct covered_by<Polygon1, Polygon2, polygon_tag, polygon_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename Ring, typename MultiPolygon>
|
||||
struct covered_by<Ring, MultiPolygon, ring_tag, multi_polygon_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiPolygon, typename Ring>
|
||||
struct covered_by<MultiPolygon, Ring, multi_polygon_tag, ring_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename Polygon, typename MultiPolygon>
|
||||
struct covered_by<Polygon, MultiPolygon, polygon_tag, multi_polygon_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiPolygon, typename Polygon>
|
||||
struct covered_by<MultiPolygon, Polygon, multi_polygon_tag, polygon_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiPolygon1, typename MultiPolygon2>
|
||||
struct covered_by<MultiPolygon1, MultiPolygon2, multi_polygon_tag, multi_polygon_tag>
|
||||
: public detail::covered_by::use_relate
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_COVERED_BY_IMPLEMENTATION_HPP
|
@ -0,0 +1,261 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2013, 2014, 2017.
|
||||
// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_COVERED_BY_INTERFACE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_COVERED_BY_INTERFACE_HPP
|
||||
|
||||
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/within/interface.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
|
||||
#include <boost/geometry/strategies/cartesian/box_in_box.hpp>
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Tag1 = typename tag<Geometry1>::type,
|
||||
typename Tag2 = typename tag<Geometry2>::type
|
||||
>
|
||||
struct covered_by
|
||||
: not_implemented<Tag1, Tag2>
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
namespace resolve_strategy {
|
||||
|
||||
struct covered_by
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concepts::within::check
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
|
||||
Strategy
|
||||
>();
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
assert_dimension_equal<Geometry1, Geometry2>();
|
||||
|
||||
return dispatch::covered_by<Geometry1, Geometry2>::apply(geometry1,
|
||||
geometry2,
|
||||
strategy);
|
||||
}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
default_strategy)
|
||||
{
|
||||
typedef typename strategy::covered_by::services::default_strategy
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
return covered_by::apply(geometry1, geometry2, strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_strategy
|
||||
|
||||
|
||||
namespace resolve_variant {
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct covered_by
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return resolve_strategy::covered_by
|
||||
::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
|
||||
struct covered_by<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: boost::static_visitor<bool>
|
||||
{
|
||||
Geometry2 const& m_geometry2;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry2 const& geometry2, Strategy const& strategy)
|
||||
: m_geometry2(geometry2), m_strategy(strategy) {}
|
||||
|
||||
template <typename Geometry1>
|
||||
bool operator()(Geometry1 const& geometry1) const
|
||||
{
|
||||
return covered_by<Geometry1, Geometry2>
|
||||
::apply(geometry1, m_geometry2, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool
|
||||
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct covered_by<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: boost::static_visitor<bool>
|
||||
{
|
||||
Geometry1 const& m_geometry1;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry1 const& geometry1, Strategy const& strategy)
|
||||
: m_geometry1(geometry1), m_strategy(strategy) {}
|
||||
|
||||
template <typename Geometry2>
|
||||
bool operator()(Geometry2 const& geometry2) const
|
||||
{
|
||||
return covered_by<Geometry1, Geometry2>
|
||||
::apply(m_geometry1, geometry2, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool
|
||||
apply(Geometry1 const& geometry1,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
template <
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T1),
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T2)
|
||||
>
|
||||
struct covered_by<
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
|
||||
>
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: boost::static_visitor<bool>
|
||||
{
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Strategy const& strategy): m_strategy(strategy) {}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
bool operator()(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2) const
|
||||
{
|
||||
return covered_by<Geometry1, Geometry2>
|
||||
::apply(geometry1, geometry2, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool
|
||||
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_variant
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check12{is inside or on border}
|
||||
\ingroup covered_by
|
||||
\details \details_check12{covered_by, is inside or on border}.
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry which might be inside or on the border of the second geometry
|
||||
\param geometry2 \param_geometry which might cover the first geometry
|
||||
\return true if geometry1 is inside of or on the border of geometry2,
|
||||
else false
|
||||
\note The default strategy is used for covered_by detection
|
||||
|
||||
\qbk{[include reference/algorithms/covered_by.qbk]}
|
||||
|
||||
*/
|
||||
template<typename Geometry1, typename Geometry2>
|
||||
inline bool covered_by(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
return resolve_variant::covered_by<Geometry1, Geometry2>
|
||||
::apply(geometry1, geometry2, default_strategy());
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief \brief_check12{is inside or on border} \brief_strategy
|
||||
\ingroup covered_by
|
||||
\details \details_check12{covered_by, is inside or on border}, \brief_strategy. \details_strategy_reasons
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry which might be inside or on the border of the second geometry
|
||||
\param geometry2 \param_geometry which might cover the first geometry
|
||||
\param strategy strategy to be used
|
||||
\return true if geometry1 is inside of or on the border of geometry2,
|
||||
else false
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{[include reference/algorithms/covered_by.qbk]}
|
||||
|
||||
*/
|
||||
template<typename Geometry1, typename Geometry2, typename Strategy>
|
||||
inline bool covered_by(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return resolve_variant::covered_by<Geometry1, Geometry2>
|
||||
::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_COVERED_BY_INTERFACE_HPP
|
@ -5,8 +5,8 @@
|
||||
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2013-2014.
|
||||
// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2017.
|
||||
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
@ -31,7 +31,9 @@
|
||||
|
||||
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/partition.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/box_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/point_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/point_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/less.hpp>
|
||||
@ -141,11 +143,7 @@ private:
|
||||
static inline bool apply(Box const& box, Point const& point)
|
||||
{
|
||||
// The default strategy is enough in this case
|
||||
typedef typename strategy::disjoint::services::default_strategy
|
||||
<
|
||||
Point, Box
|
||||
>::type strategy_type;
|
||||
return ! dispatch::disjoint<Point, Box>::apply(point, box, strategy_type());
|
||||
return ! detail::disjoint::disjoint_point_box(point, box);
|
||||
}
|
||||
};
|
||||
|
||||
@ -252,6 +250,176 @@ public:
|
||||
};
|
||||
|
||||
|
||||
template <typename MultiPoint, typename SingleGeometry>
|
||||
class multi_point_single_geometry
|
||||
{
|
||||
public:
|
||||
template <typename Strategy>
|
||||
static inline bool apply(MultiPoint const& multi_point, SingleGeometry const& single_geometry, Strategy const& strategy)
|
||||
{
|
||||
typedef typename point_type<MultiPoint>::type point1_type;
|
||||
typedef typename point_type<SingleGeometry>::type point2_type;
|
||||
typedef model::box<point2_type> box2_type;
|
||||
|
||||
box2_type box2;
|
||||
geometry::envelope(single_geometry, box2, strategy.get_envelope_strategy());
|
||||
geometry::detail::expand_by_epsilon(box2);
|
||||
|
||||
typedef typename boost::range_const_iterator<MultiPoint>::type iterator;
|
||||
for ( iterator it = boost::begin(multi_point) ; it != boost::end(multi_point) ; ++it )
|
||||
{
|
||||
// The default strategy is enough for Point/Box
|
||||
if (! detail::disjoint::disjoint_point_box(*it, box2)
|
||||
&& ! dispatch::disjoint<point1_type, SingleGeometry>::apply(*it, single_geometry, strategy))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool apply(SingleGeometry const& single_geometry, MultiPoint const& multi_point, Strategy const& strategy)
|
||||
{
|
||||
return apply(multi_point, single_geometry, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename MultiPoint, typename MultiGeometry>
|
||||
class multi_point_multi_geometry
|
||||
{
|
||||
private:
|
||||
struct expand_box_point
|
||||
{
|
||||
template <typename Box, typename Point>
|
||||
static inline void apply(Box& total, Point const& point)
|
||||
{
|
||||
geometry::expand(total, point);
|
||||
}
|
||||
};
|
||||
|
||||
struct expand_box_box_pair
|
||||
{
|
||||
template <typename Box, typename BoxPair>
|
||||
inline void apply(Box& total, BoxPair const& box_pair) const
|
||||
{
|
||||
geometry::expand(total, box_pair.first);
|
||||
}
|
||||
};
|
||||
|
||||
struct overlaps_box_point
|
||||
{
|
||||
template <typename Box, typename Point>
|
||||
static inline bool apply(Box const& box, Point const& point)
|
||||
{
|
||||
// The default strategy is enough for Point/Box
|
||||
return ! detail::disjoint::disjoint_point_box(point, box);
|
||||
}
|
||||
};
|
||||
|
||||
struct overlaps_box_box_pair
|
||||
{
|
||||
template <typename Box, typename BoxPair>
|
||||
inline bool apply(Box const& box, BoxPair const& box_pair) const
|
||||
{
|
||||
// The default strategy is enough for Box/Box
|
||||
return ! detail::disjoint::disjoint_box_box(box_pair.first, box);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename PtSegStrategy>
|
||||
class item_visitor_type
|
||||
{
|
||||
public:
|
||||
item_visitor_type(MultiGeometry const& multi_geometry,
|
||||
PtSegStrategy const& strategy)
|
||||
: m_intersection_found(false)
|
||||
, m_multi_geometry(multi_geometry)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Point, typename BoxPair>
|
||||
inline bool apply(Point const& point, BoxPair const& box_pair)
|
||||
{
|
||||
typedef typename boost::range_value<MultiGeometry>::type single_type;
|
||||
|
||||
// The default strategy is enough for Point/Box
|
||||
if (! m_intersection_found
|
||||
&& ! detail::disjoint::disjoint_point_box(point, box_pair.first)
|
||||
&& ! dispatch::disjoint<Point, single_type>::apply(point, range::at(m_multi_geometry, box_pair.second), m_strategy))
|
||||
{
|
||||
m_intersection_found = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool intersection_found() const { return m_intersection_found; }
|
||||
|
||||
private:
|
||||
bool m_intersection_found;
|
||||
MultiGeometry const& m_multi_geometry;
|
||||
PtSegStrategy const& m_strategy;
|
||||
};
|
||||
// structs for partition -- end
|
||||
|
||||
public:
|
||||
template <typename Strategy>
|
||||
static inline bool apply(MultiPoint const& multi_point, MultiGeometry const& multi_geometry, Strategy const& strategy)
|
||||
{
|
||||
typedef typename point_type<MultiPoint>::type point1_type;
|
||||
typedef typename point_type<MultiGeometry>::type point2_type;
|
||||
typedef model::box<point1_type> box1_type;
|
||||
typedef model::box<point2_type> box2_type;
|
||||
typedef std::pair<box2_type, std::size_t> box_pair_type;
|
||||
|
||||
typename Strategy::envelope_strategy_type const
|
||||
envelope_strategy = strategy.get_envelope_strategy();
|
||||
|
||||
std::size_t count2 = boost::size(multi_geometry);
|
||||
std::vector<box_pair_type> boxes(count2);
|
||||
for (std::size_t i = 0 ; i < count2 ; ++i)
|
||||
{
|
||||
geometry::envelope(range::at(multi_geometry, i), boxes[i].first, envelope_strategy);
|
||||
geometry::detail::expand_by_epsilon(boxes[i].first);
|
||||
boxes[i].second = i;
|
||||
}
|
||||
|
||||
item_visitor_type<Strategy> visitor(multi_geometry, strategy);
|
||||
|
||||
geometry::partition
|
||||
<
|
||||
box1_type
|
||||
>::apply(multi_point, boxes, visitor,
|
||||
expand_box_point(),
|
||||
overlaps_box_point(),
|
||||
expand_box_box_pair(),
|
||||
overlaps_box_box_pair());
|
||||
|
||||
return ! visitor.intersection_found();
|
||||
}
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool apply(MultiGeometry const& multi_geometry, MultiPoint const& multi_point, Strategy const& strategy)
|
||||
{
|
||||
return apply(multi_point, multi_geometry, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename MultiPoint, typename Areal, typename Tag = typename tag<Areal>::type>
|
||||
struct multipoint_areal
|
||||
: multi_point_single_geometry<MultiPoint, Areal>
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename Areal>
|
||||
struct multipoint_areal<MultiPoint, Areal, multi_polygon_tag>
|
||||
: multi_point_multi_geometry<MultiPoint, Areal>
|
||||
{};
|
||||
|
||||
|
||||
}} // namespace detail::disjoint
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
@ -336,6 +504,22 @@ struct disjoint
|
||||
{};
|
||||
|
||||
|
||||
template <typename Areal, typename MultiPoint, std::size_t DimensionCount>
|
||||
struct disjoint
|
||||
<
|
||||
Areal, MultiPoint, DimensionCount, areal_tag, multi_point_tag, false
|
||||
> : detail::disjoint::multipoint_areal<MultiPoint, Areal>
|
||||
{};
|
||||
|
||||
|
||||
template <typename MultiPoint, typename Areal, std::size_t DimensionCount>
|
||||
struct disjoint
|
||||
<
|
||||
MultiPoint, Areal, DimensionCount, multi_point_tag, areal_tag, false
|
||||
> : detail::disjoint::multipoint_areal<MultiPoint, Areal>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
@ -0,0 +1,397 @@
|
||||
// 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.
|
||||
|
||||
// This file was modified by Oracle on 2014, 2015, 2016, 2017.
|
||||
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_IMPLEMENTATION_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_IMPLEMENTATION_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/type_traits/is_base_of.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
|
||||
|
||||
// For trivial checks
|
||||
#include <boost/geometry/algorithms/area.hpp>
|
||||
#include <boost/geometry/algorithms/length.hpp>
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
#include <boost/geometry/util/select_coordinate_type.hpp>
|
||||
#include <boost/geometry/util/select_most_precise.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/equals/collect_vectors.hpp>
|
||||
#include <boost/geometry/algorithms/detail/equals/interface.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
|
||||
#include <boost/geometry/algorithms/relate.hpp>
|
||||
|
||||
#include <boost/geometry/views/detail/indexed_point_view.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace equals
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
std::size_t Dimension,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct point_point
|
||||
{
|
||||
template <typename Point1, typename Point2, typename Strategy>
|
||||
static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& strategy)
|
||||
{
|
||||
return ! detail::disjoint::point_point
|
||||
<
|
||||
Point1, Point2,
|
||||
Dimension, DimensionCount
|
||||
>::apply(point1, point2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
std::size_t Dimension,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct box_box
|
||||
{
|
||||
template <typename Box1, typename Box2, typename Strategy>
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
|
||||
{
|
||||
if (!geometry::math::equals(get<min_corner, Dimension>(box1), get<min_corner, Dimension>(box2))
|
||||
|| !geometry::math::equals(get<max_corner, Dimension>(box1), get<max_corner, Dimension>(box2)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return box_box<Dimension + 1, DimensionCount>::apply(box1, box2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t DimensionCount>
|
||||
struct box_box<DimensionCount, DimensionCount>
|
||||
{
|
||||
template <typename Box1, typename Box2, typename Strategy>
|
||||
static inline bool apply(Box1 const& , Box2 const& , Strategy const& )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct segment_segment
|
||||
{
|
||||
template <typename Segment1, typename Segment2, typename Strategy>
|
||||
static inline bool apply(Segment1 const& segment1, Segment2 const& segment2, Strategy const& )
|
||||
{
|
||||
return equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 0>(segment1),
|
||||
indexed_point_view<Segment2 const, 0>(segment2) )
|
||||
? equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 1>(segment1),
|
||||
indexed_point_view<Segment2 const, 1>(segment2) )
|
||||
: ( equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 0>(segment1),
|
||||
indexed_point_view<Segment2 const, 1>(segment2) )
|
||||
&& equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 1>(segment1),
|
||||
indexed_point_view<Segment2 const, 0>(segment2) )
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct area_check
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return geometry::math::equals(
|
||||
geometry::area(geometry1,
|
||||
strategy.template get_area_strategy<Geometry1>()),
|
||||
geometry::area(geometry2,
|
||||
strategy.template get_area_strategy<Geometry2>()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct length_check
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return geometry::math::equals(
|
||||
geometry::length(geometry1,
|
||||
strategy.template get_distance_strategy<Geometry1>()),
|
||||
geometry::length(geometry2,
|
||||
strategy.template get_distance_strategy<Geometry2>()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename IntersectionStrategy>
|
||||
struct collected_vector
|
||||
{
|
||||
typedef typename geometry::select_most_precise
|
||||
<
|
||||
typename select_coordinate_type
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::type,
|
||||
double
|
||||
>::type calculation_type;
|
||||
|
||||
typedef geometry::collected_vector
|
||||
<
|
||||
calculation_type,
|
||||
Geometry1,
|
||||
typename IntersectionStrategy::side_strategy_type
|
||||
> type;
|
||||
};
|
||||
|
||||
template <typename TrivialCheck>
|
||||
struct equals_by_collection
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
if (! TrivialCheck::apply(geometry1, geometry2, strategy))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef typename collected_vector
|
||||
<
|
||||
Geometry1, Geometry2, Strategy
|
||||
>::type collected_vector_type;
|
||||
|
||||
std::vector<collected_vector_type> c1, c2;
|
||||
|
||||
geometry::collect_vectors(c1, geometry1);
|
||||
geometry::collect_vectors(c2, geometry2);
|
||||
|
||||
if (boost::size(c1) != boost::size(c2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::sort(c1.begin(), c1.end());
|
||||
std::sort(c2.begin(), c2.end());
|
||||
|
||||
// Just check if these vectors are equal.
|
||||
return std::equal(c1.begin(), c1.end(), c2.begin());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Geometry1, typename Geometry2>
|
||||
struct equals_by_relate
|
||||
: detail::relate::relate_impl
|
||||
<
|
||||
detail::de9im::static_mask_equals_type,
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>
|
||||
{};
|
||||
|
||||
// If collect_vectors which is a SideStrategy-dispatched optimization
|
||||
// is implemented in a way consistent with the Intersection/Side Strategy
|
||||
// then collect_vectors is used, otherwise relate is used.
|
||||
// NOTE: the result could be conceptually different for invalid
|
||||
// geometries in different coordinate systems because collect_vectors
|
||||
// and relate treat invalid geometries differently.
|
||||
template<typename TrivialCheck>
|
||||
struct equals_by_collection_or_relate
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename boost::is_base_of
|
||||
<
|
||||
nyi::not_implemented_tag,
|
||||
typename collected_vector
|
||||
<
|
||||
Geometry1, Geometry2, Strategy
|
||||
>::type
|
||||
>::type enable_relate_type;
|
||||
|
||||
return apply(geometry1, geometry2, strategy, enable_relate_type());
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy,
|
||||
boost::false_type /*enable_relate*/)
|
||||
{
|
||||
return equals_by_collection<TrivialCheck>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy,
|
||||
boost::true_type /*enable_relate*/)
|
||||
{
|
||||
return equals_by_relate<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::equals
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template <typename P1, typename P2, std::size_t DimensionCount, bool Reverse>
|
||||
struct equals<P1, P2, point_tag, point_tag, DimensionCount, Reverse>
|
||||
: detail::equals::point_point<0, DimensionCount>
|
||||
{};
|
||||
|
||||
template <typename MultiPoint1, typename MultiPoint2, std::size_t DimensionCount, bool Reverse>
|
||||
struct equals<MultiPoint1, MultiPoint2, multi_point_tag, multi_point_tag, DimensionCount, Reverse>
|
||||
: detail::equals::equals_by_relate<MultiPoint1, MultiPoint2>
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename Point, std::size_t DimensionCount, bool Reverse>
|
||||
struct equals<Point, MultiPoint, point_tag, multi_point_tag, DimensionCount, Reverse>
|
||||
: detail::equals::equals_by_relate<Point, MultiPoint>
|
||||
{};
|
||||
|
||||
template <typename Box1, typename Box2, std::size_t DimensionCount, bool Reverse>
|
||||
struct equals<Box1, Box2, box_tag, box_tag, DimensionCount, Reverse>
|
||||
: detail::equals::box_box<0, DimensionCount>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Ring1, typename Ring2, bool Reverse>
|
||||
struct equals<Ring1, Ring2, ring_tag, ring_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon1, typename Polygon2, bool Reverse>
|
||||
struct equals<Polygon1, Polygon2, polygon_tag, polygon_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename Ring, bool Reverse>
|
||||
struct equals<Polygon, Ring, polygon_tag, ring_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Ring, typename Box, bool Reverse>
|
||||
struct equals<Ring, Box, ring_tag, box_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename Box, bool Reverse>
|
||||
struct equals<Polygon, Box, polygon_tag, box_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
template <typename Segment1, typename Segment2, std::size_t DimensionCount, bool Reverse>
|
||||
struct equals<Segment1, Segment2, segment_tag, segment_tag, DimensionCount, Reverse>
|
||||
: detail::equals::segment_segment
|
||||
{};
|
||||
|
||||
template <typename LineString1, typename LineString2, bool Reverse>
|
||||
struct equals<LineString1, LineString2, linestring_tag, linestring_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_relate<LineString1, LineString2>
|
||||
{};
|
||||
|
||||
template <typename LineString, typename MultiLineString, bool Reverse>
|
||||
struct equals<LineString, MultiLineString, linestring_tag, multi_linestring_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_relate<LineString, MultiLineString>
|
||||
{};
|
||||
|
||||
template <typename MultiLineString1, typename MultiLineString2, bool Reverse>
|
||||
struct equals<MultiLineString1, MultiLineString2, multi_linestring_tag, multi_linestring_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_relate<MultiLineString1, MultiLineString2>
|
||||
{};
|
||||
|
||||
|
||||
template <typename MultiPolygon1, typename MultiPolygon2, bool Reverse>
|
||||
struct equals
|
||||
<
|
||||
MultiPolygon1, MultiPolygon2,
|
||||
multi_polygon_tag, multi_polygon_tag,
|
||||
2,
|
||||
Reverse
|
||||
>
|
||||
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename MultiPolygon, bool Reverse>
|
||||
struct equals
|
||||
<
|
||||
Polygon, MultiPolygon,
|
||||
polygon_tag, multi_polygon_tag,
|
||||
2,
|
||||
Reverse
|
||||
>
|
||||
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
template <typename MultiPolygon, typename Ring, bool Reverse>
|
||||
struct equals
|
||||
<
|
||||
MultiPolygon, Ring,
|
||||
multi_polygon_tag, ring_tag,
|
||||
2,
|
||||
Reverse
|
||||
>
|
||||
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_IMPLEMENTATION_HPP
|
||||
|
317
include/boost/geometry/algorithms/detail/equals/interface.hpp
Normal file
317
include/boost/geometry/algorithms/detail/equals/interface.hpp
Normal file
@ -0,0 +1,317 @@
|
||||
// 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.
|
||||
|
||||
// This file was modified by Oracle on 2014, 2015, 2016, 2017.
|
||||
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_INTERFACE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_INTERFACE_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/reverse_dispatch.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/relate.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Tag1 = typename tag<Geometry1>::type,
|
||||
typename Tag2 = typename tag<Geometry2>::type,
|
||||
std::size_t DimensionCount = dimension<Geometry1>::type::value,
|
||||
bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
|
||||
>
|
||||
struct equals: not_implemented<Tag1, Tag2>
|
||||
{};
|
||||
|
||||
|
||||
// If reversal is needed, perform it
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Tag1, typename Tag2,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct equals<Geometry1, Geometry2, Tag1, Tag2, DimensionCount, true>
|
||||
: equals<Geometry2, Geometry1, Tag2, Tag1, DimensionCount, false>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
|
||||
{
|
||||
return equals
|
||||
<
|
||||
Geometry2, Geometry1,
|
||||
Tag2, Tag1,
|
||||
DimensionCount,
|
||||
false
|
||||
>::apply(g2, g1, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
namespace resolve_strategy
|
||||
{
|
||||
|
||||
struct equals
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return dispatch::equals
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
default_strategy)
|
||||
{
|
||||
typedef typename strategy::relate::services::default_strategy
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
return dispatch::equals
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_strategy
|
||||
|
||||
|
||||
namespace resolve_variant {
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct equals
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concepts::check_concepts_and_equal_dimensions
|
||||
<
|
||||
Geometry1 const,
|
||||
Geometry2 const
|
||||
>();
|
||||
|
||||
return resolve_strategy::equals
|
||||
::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
|
||||
struct equals<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: static_visitor<bool>
|
||||
{
|
||||
Geometry2 const& m_geometry2;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry2 const& geometry2, Strategy const& strategy)
|
||||
: m_geometry2(geometry2)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry1>
|
||||
inline bool operator()(Geometry1 const& geometry1) const
|
||||
{
|
||||
return equals<Geometry1, Geometry2>
|
||||
::apply(geometry1, m_geometry2, m_strategy);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool apply(
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy
|
||||
)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct equals<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: static_visitor<bool>
|
||||
{
|
||||
Geometry1 const& m_geometry1;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry1 const& geometry1, Strategy const& strategy)
|
||||
: m_geometry1(geometry1)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry2>
|
||||
inline bool operator()(Geometry2 const& geometry2) const
|
||||
{
|
||||
return equals<Geometry1, Geometry2>
|
||||
::apply(m_geometry1, geometry2, m_strategy);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool apply(
|
||||
Geometry1 const& geometry1,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
|
||||
Strategy const& strategy
|
||||
)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
template <
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T1),
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T2)
|
||||
>
|
||||
struct equals<
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
|
||||
>
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: static_visitor<bool>
|
||||
{
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline bool operator()(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2) const
|
||||
{
|
||||
return equals<Geometry1, Geometry2>
|
||||
::apply(geometry1, geometry2, m_strategy);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool apply(
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
|
||||
Strategy const& strategy
|
||||
)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_variant
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check{are spatially equal}
|
||||
\details \details_check12{equals, is spatially equal}. Spatially equal means
|
||||
that the same point set is included. A box can therefore be spatially equal
|
||||
to a ring or a polygon, or a linestring can be spatially equal to a
|
||||
multi-linestring or a segment. This only works theoretically, not all
|
||||
combinations are implemented yet.
|
||||
\ingroup equals
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam Strategy \tparam_strategy{Equals}
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param strategy \param_strategy{equals}
|
||||
\return \return_check2{are spatially equal}
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{[include reference/algorithms/equals.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
inline bool equals(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return resolve_variant::equals
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check{are spatially equal}
|
||||
\details \details_check12{equals, is spatially equal}. Spatially equal means
|
||||
that the same point set is included. A box can therefore be spatially equal
|
||||
to a ring or a polygon, or a linestring can be spatially equal to a
|
||||
multi-linestring or a segment. This only works theoretically, not all
|
||||
combinations are implemented yet.
|
||||
\ingroup equals
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\return \return_check2{are spatially equal}
|
||||
|
||||
\qbk{[include reference/algorithms/equals.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline bool equals(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
return resolve_variant::equals<Geometry1, Geometry2>
|
||||
::apply(geometry1, geometry2, default_strategy());
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_INTERFACE_HPP
|
||||
|
@ -0,0 +1,88 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2013-2017.
|
||||
// Modifications copyright (c) 2013-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
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTS_IMPLEMENTATION_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTS_IMPLEMENTATION_HPP
|
||||
|
||||
|
||||
#include <deque>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/intersects/interface.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/implementation.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
|
||||
#include <boost/geometry/policies/disjoint_interrupt_policy.hpp>
|
||||
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
|
||||
#include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/relate.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace intersects
|
||||
{
|
||||
|
||||
template <typename Geometry>
|
||||
struct self_intersects
|
||||
{
|
||||
static bool apply(Geometry const& geometry)
|
||||
{
|
||||
concepts::check<Geometry const>();
|
||||
|
||||
typedef typename geometry::point_type<Geometry>::type point_type;
|
||||
typedef typename strategy::relate::services::default_strategy
|
||||
<
|
||||
Geometry, Geometry
|
||||
>::type strategy_type;
|
||||
typedef detail::no_rescale_policy rescale_policy_type;
|
||||
|
||||
typedef detail::overlay::turn_info
|
||||
<
|
||||
point_type,
|
||||
typename segment_ratio_type<point_type, rescale_policy_type>::type
|
||||
> turn_info;
|
||||
|
||||
std::deque<turn_info> turns;
|
||||
|
||||
typedef detail::overlay::get_turn_info
|
||||
<
|
||||
detail::overlay::assign_null_policy
|
||||
> turn_policy;
|
||||
|
||||
strategy_type strategy;
|
||||
rescale_policy_type robust_policy;
|
||||
|
||||
detail::disjoint::disjoint_interrupt_policy policy;
|
||||
detail::self_get_turn_points::get_turns
|
||||
<
|
||||
turn_policy
|
||||
>::apply(geometry, strategy, robust_policy, turns, policy, 0);
|
||||
return policy.has_intersections;
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::intersects
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTS_IMPLEMENTATION_HPP
|
@ -0,0 +1,115 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2013-2017.
|
||||
// Modifications copyright (c) 2013-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
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTS_INTERFACE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTS_INTERFACE_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/disjoint/interface.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace intersects
|
||||
{
|
||||
|
||||
// Forward declaration
|
||||
template <typename Geometry>
|
||||
struct self_intersects;
|
||||
|
||||
}} // namespace detail::intersects
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check{has at least one intersection (crossing or self-tangency)}
|
||||
\note This function can be called for one geometry (self-intersection) and
|
||||
also for two geometries (intersection)
|
||||
\ingroup intersects
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry
|
||||
\return \return_check{is self-intersecting}
|
||||
|
||||
\qbk{distinguish,one geometry}
|
||||
\qbk{[def __one_parameter__]}
|
||||
\qbk{[include reference/algorithms/intersects.qbk]}
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline bool intersects(Geometry const& geometry)
|
||||
{
|
||||
return detail::intersects::self_intersects<Geometry>::apply(geometry);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check2{have at least one intersection}
|
||||
\ingroup intersects
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam Strategy \tparam_strategy{Intersects}
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param strategy \param_strategy{intersects}
|
||||
\return \return_check2{intersect each other}
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{[include reference/algorithms/intersects.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
inline bool intersects(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
|
||||
return ! geometry::disjoint(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check2{have at least one intersection}
|
||||
\ingroup intersects
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\return \return_check2{intersect each other}
|
||||
|
||||
\qbk{distinguish,two geometries}
|
||||
\qbk{[include reference/algorithms/intersects.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline bool intersects(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
|
||||
return ! geometry::disjoint(geometry1, geometry2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTS_INTERFACE_HPP
|
@ -0,0 +1,156 @@
|
||||
// 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.
|
||||
|
||||
// This file was modified by Oracle on 2014, 2015, 2017.
|
||||
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAPS_IMPLEMENTATION_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAPS_IMPLEMENTATION_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/relate.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlaps/interface.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlaps
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
std::size_t Dimension,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct box_box_loop
|
||||
{
|
||||
template <typename Box1, typename Box2>
|
||||
static inline void apply(Box1 const& b1, Box2 const& b2,
|
||||
bool& overlaps, bool& one_in_two, bool& two_in_one)
|
||||
{
|
||||
assert_dimension_equal<Box1, Box2>();
|
||||
|
||||
typedef typename coordinate_type<Box1>::type coordinate_type1;
|
||||
typedef typename coordinate_type<Box2>::type coordinate_type2;
|
||||
|
||||
coordinate_type1 const& min1 = get<min_corner, Dimension>(b1);
|
||||
coordinate_type1 const& max1 = get<max_corner, Dimension>(b1);
|
||||
coordinate_type2 const& min2 = get<min_corner, Dimension>(b2);
|
||||
coordinate_type2 const& max2 = get<max_corner, Dimension>(b2);
|
||||
|
||||
// We might use the (not yet accepted) Boost.Interval
|
||||
// submission in the future
|
||||
|
||||
// If:
|
||||
// B1: |-------|
|
||||
// B2: |------|
|
||||
// in any dimension -> no overlap
|
||||
if (max1 <= min2 || min1 >= max2)
|
||||
{
|
||||
overlaps = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// If:
|
||||
// B1: |--------------------|
|
||||
// B2: |-------------|
|
||||
// in all dimensions -> within, then no overlap
|
||||
// B1: |--------------------|
|
||||
// B2: |-------------|
|
||||
// this is "within-touch" -> then no overlap. So use < and >
|
||||
if (min1 < min2 || max1 > max2)
|
||||
{
|
||||
one_in_two = false;
|
||||
}
|
||||
|
||||
// Same other way round
|
||||
if (min2 < min1 || max2 > max1)
|
||||
{
|
||||
two_in_one = false;
|
||||
}
|
||||
|
||||
box_box_loop
|
||||
<
|
||||
Dimension + 1,
|
||||
DimensionCount
|
||||
>::apply(b1, b2, overlaps, one_in_two, two_in_one);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct box_box_loop<DimensionCount, DimensionCount>
|
||||
{
|
||||
template <typename Box1, typename Box2>
|
||||
static inline void apply(Box1 const& , Box2 const&, bool&, bool&, bool&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct box_box
|
||||
{
|
||||
template <typename Box1, typename Box2, typename Strategy>
|
||||
static inline bool apply(Box1 const& b1, Box2 const& b2, Strategy const& /*strategy*/)
|
||||
{
|
||||
bool overlaps = true;
|
||||
bool within1 = true;
|
||||
bool within2 = true;
|
||||
box_box_loop
|
||||
<
|
||||
0,
|
||||
dimension<Box1>::type::value
|
||||
>::apply(b1, b2, overlaps, within1, within2);
|
||||
|
||||
/*
|
||||
\see http://docs.codehaus.org/display/GEOTDOC/02+Geometry+Relationships#02GeometryRelationships-Overlaps
|
||||
where is stated that "inside" is not an "overlap",
|
||||
this is true and is implemented as such.
|
||||
*/
|
||||
return overlaps && ! within1 && ! within2;
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::overlaps
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template <typename Box1, typename Box2>
|
||||
struct overlaps<Box1, Box2, box_tag, box_tag>
|
||||
: detail::overlaps::box_box
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAPS_IMPLEMENTATION_HPP
|
124
include/boost/geometry/algorithms/detail/overlaps/interface.hpp
Normal file
124
include/boost/geometry/algorithms/detail/overlaps/interface.hpp
Normal file
@ -0,0 +1,124 @@
|
||||
// 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.
|
||||
|
||||
// This file was modified by Oracle on 2014, 2015, 2017.
|
||||
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAPS_INTERFACE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAPS_INTERFACE_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/relate.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Tag1 = typename tag<Geometry1>::type,
|
||||
typename Tag2 = typename tag<Geometry2>::type
|
||||
>
|
||||
struct overlaps
|
||||
: detail::relate::relate_impl
|
||||
<
|
||||
detail::de9im::static_mask_overlaps_type,
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check2{overlap}
|
||||
\ingroup overlaps
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam Strategy \tparam_strategy{Overlaps}
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param strategy \param_strategy{overlaps}
|
||||
\return \return_check2{overlap}
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{[include reference/algorithms/overlaps.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
inline bool overlaps(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
|
||||
return dispatch::overlaps
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief \brief_check2{overlap}
|
||||
\ingroup overlaps
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\return \return_check2{overlap}
|
||||
|
||||
\qbk{[include reference/algorithms/overlaps.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline bool overlaps(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
|
||||
typedef typename strategy::relate::services::default_strategy
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
return dispatch::overlaps
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply(geometry1, geometry2, strategy_type());
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAPS_INTERFACE_HPP
|
@ -23,6 +23,7 @@
|
||||
#include <boost/geometry/algorithms/detail/relate/point_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/linear_linear.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/linear_areal.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/areal_areal.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/intersection.hpp>
|
||||
@ -81,6 +82,16 @@ struct relate<Geometry, Point, Tag1, point_tag, TopDim1, 0, true>
|
||||
: detail::relate::geometry_point<Geometry, Point>
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename Geometry, typename Tag2, int TopDim2>
|
||||
struct relate<MultiPoint, Geometry, multi_point_tag, Tag2, 0, TopDim2, false>
|
||||
: detail::relate::multi_point_geometry<MultiPoint, Geometry>
|
||||
{};
|
||||
|
||||
template <typename Geometry, typename MultiPoint, typename Tag1, int TopDim1>
|
||||
struct relate<Geometry, MultiPoint, Tag1, multi_point_tag, TopDim1, 0, false>
|
||||
: detail::relate::geometry_multi_point<Geometry, MultiPoint>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Linear1, typename Linear2, typename Tag1, typename Tag2>
|
||||
struct relate<Linear1, Linear2, Tag1, Tag2, 1, 1, true>
|
||||
|
@ -0,0 +1,568 @@
|
||||
// Boost.Geometry
|
||||
|
||||
// Copyright (c) 2017 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_MULTI_POINT_GEOMETRY_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_MULTI_POINT_GEOMETRY_HPP
|
||||
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/disjoint/box_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/point_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/expand_by_epsilon.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/result.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/topology_check.hpp>
|
||||
#include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/envelope.hpp>
|
||||
|
||||
#include <boost/geometry/core/is_areal.hpp>
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/box.hpp>
|
||||
|
||||
#include <boost/geometry/index/rtree.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace relate
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Tag = typename tag<Geometry>::type
|
||||
>
|
||||
struct multi_point_geometry_eb
|
||||
{
|
||||
template <typename MultiPoint>
|
||||
static inline bool apply(MultiPoint const& ,
|
||||
detail::relate::topology_check<Geometry> const& )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct multi_point_geometry_eb<Geometry, linestring_tag>
|
||||
{
|
||||
template <typename Points>
|
||||
struct boundary_visitor
|
||||
{
|
||||
boundary_visitor(Points const& points)
|
||||
: m_points(points)
|
||||
, m_boundary_found(false)
|
||||
{}
|
||||
|
||||
template <typename Point>
|
||||
struct find_pred
|
||||
{
|
||||
find_pred(Point const& point)
|
||||
: m_point(point)
|
||||
{}
|
||||
|
||||
template <typename Pt>
|
||||
bool operator()(Pt const& pt) const
|
||||
{
|
||||
return detail::equals::equals_point_point(pt, m_point);
|
||||
}
|
||||
|
||||
Point const& m_point;
|
||||
};
|
||||
|
||||
template <typename Point>
|
||||
bool apply(Point const& boundary_point)
|
||||
{
|
||||
if (std::find_if(m_points.begin(), m_points.end(), find_pred<Point>(boundary_point)) == m_points.end())
|
||||
{
|
||||
m_boundary_found = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool result() const { return m_boundary_found; }
|
||||
|
||||
private:
|
||||
Points const& m_points;
|
||||
bool m_boundary_found;
|
||||
};
|
||||
|
||||
template <typename MultiPoint>
|
||||
static inline bool apply(MultiPoint const& multi_point,
|
||||
detail::relate::topology_check<Geometry> const& tc)
|
||||
{
|
||||
boundary_visitor<MultiPoint> visitor(multi_point);
|
||||
tc.for_each_boundary_point(visitor);
|
||||
return visitor.result();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct multi_point_geometry_eb<Geometry, multi_linestring_tag>
|
||||
{
|
||||
template <typename Points>
|
||||
struct boundary_visitor
|
||||
{
|
||||
boundary_visitor(Points const& points)
|
||||
: m_points(points)
|
||||
, m_boundary_found(false)
|
||||
{}
|
||||
|
||||
template <typename Point>
|
||||
bool apply(Point const& boundary_point)
|
||||
{
|
||||
if (! std::binary_search(m_points.begin(), m_points.end(), boundary_point, relate::less()))
|
||||
{
|
||||
m_boundary_found = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool result() const { return m_boundary_found; }
|
||||
|
||||
private:
|
||||
Points const& m_points;
|
||||
bool m_boundary_found;
|
||||
};
|
||||
|
||||
template <typename MultiPoint>
|
||||
static inline bool apply(MultiPoint const& multi_point,
|
||||
detail::relate::topology_check<Geometry> const& tc)
|
||||
{
|
||||
typedef typename boost::range_value<MultiPoint>::type point_type;
|
||||
typedef std::vector<point_type> points_type;
|
||||
points_type points(boost::begin(multi_point), boost::end(multi_point));
|
||||
std::sort(points.begin(), points.end(), relate::less());
|
||||
|
||||
boundary_visitor<points_type> visitor(points);
|
||||
tc.for_each_boundary_point(visitor);
|
||||
return visitor.result();
|
||||
}
|
||||
};
|
||||
|
||||
// SingleGeometry - Linear or Areal
|
||||
template <typename MultiPoint, typename SingleGeometry, bool Transpose = false>
|
||||
struct multi_point_single_geometry
|
||||
{
|
||||
static const bool interruption_enabled = true;
|
||||
|
||||
template <typename Result, typename Strategy>
|
||||
static inline void apply(MultiPoint const& multi_point,
|
||||
SingleGeometry const& single_geometry,
|
||||
Result & result,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename point_type<SingleGeometry>::type point2_type;
|
||||
typedef model::box<point2_type> box2_type;
|
||||
|
||||
box2_type box2;
|
||||
geometry::envelope(single_geometry, box2, strategy.get_envelope_strategy());
|
||||
geometry::detail::expand_by_epsilon(box2);
|
||||
|
||||
typedef typename boost::range_const_iterator<MultiPoint>::type iterator;
|
||||
for ( iterator it = boost::begin(multi_point) ; it != boost::end(multi_point) ; ++it )
|
||||
{
|
||||
if (! (relate::may_update<interior, interior, '0', Transpose>(result)
|
||||
|| relate::may_update<interior, boundary, '0', Transpose>(result)
|
||||
|| relate::may_update<interior, exterior, '0', Transpose>(result) ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// The default strategy is enough for Point/Box
|
||||
if (detail::disjoint::disjoint_point_box(*it, box2))
|
||||
{
|
||||
relate::set<interior, exterior, '0', Transpose>(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
int in_val = detail::within::point_in_geometry(*it, single_geometry, strategy);
|
||||
|
||||
if (in_val > 0) // within
|
||||
{
|
||||
relate::set<interior, interior, '0', Transpose>(result);
|
||||
}
|
||||
else if (in_val == 0)
|
||||
{
|
||||
relate::set<interior, boundary, '0', Transpose>(result);
|
||||
}
|
||||
else // in_val < 0 - not within
|
||||
{
|
||||
relate::set<interior, exterior, '0', Transpose>(result);
|
||||
}
|
||||
}
|
||||
|
||||
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
typedef detail::relate::topology_check<SingleGeometry> tc_t;
|
||||
if ( relate::may_update<exterior, interior, tc_t::interior, Transpose>(result)
|
||||
|| relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result) )
|
||||
{
|
||||
tc_t tc(single_geometry);
|
||||
|
||||
if ( relate::may_update<exterior, interior, tc_t::interior, Transpose>(result)
|
||||
&& tc.has_interior() )
|
||||
{
|
||||
// TODO: this is not true if a linestring is degenerated to a point
|
||||
// then the interior has topological dimension = 0, not 1
|
||||
relate::set<exterior, interior, tc_t::interior, Transpose>(result);
|
||||
}
|
||||
|
||||
if ( relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result)
|
||||
&& tc.has_boundary() )
|
||||
{
|
||||
if (multi_point_geometry_eb<SingleGeometry>::apply(multi_point, tc))
|
||||
relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
|
||||
}
|
||||
}
|
||||
|
||||
relate::set<exterior, exterior, result_dimension<MultiPoint>::value, Transpose>(result);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// MultiGeometry - Linear or Areal
|
||||
// part of the algorithm calculating II and IB when no IE has to be calculated
|
||||
// using partition()
|
||||
template <typename MultiPoint, typename MultiGeometry, bool Transpose>
|
||||
class multi_point_multi_geometry_ii_ib
|
||||
{
|
||||
struct expand_box_point
|
||||
{
|
||||
template <typename Box, typename Point>
|
||||
static inline void apply(Box& total, Point const& point)
|
||||
{
|
||||
geometry::expand(total, point);
|
||||
}
|
||||
};
|
||||
|
||||
struct expand_box_box_pair
|
||||
{
|
||||
template <typename Box, typename BoxPair>
|
||||
static inline void apply(Box& total, BoxPair const& box_pair)
|
||||
{
|
||||
geometry::expand(total, box_pair.first);
|
||||
}
|
||||
};
|
||||
|
||||
struct overlaps_box_point
|
||||
{
|
||||
template <typename Box, typename Point>
|
||||
static inline bool apply(Box const& box, Point const& point)
|
||||
{
|
||||
// The default strategy is enough for Point/Box
|
||||
return ! detail::disjoint::disjoint_point_box(point, box);
|
||||
}
|
||||
};
|
||||
|
||||
struct overlaps_box_box_pair
|
||||
{
|
||||
template <typename Box, typename BoxPair>
|
||||
static inline bool apply(Box const& box, BoxPair const& box_pair)
|
||||
{
|
||||
// The default strategy is enough for Box/Box
|
||||
return ! detail::disjoint::disjoint_box_box(box_pair.first, box);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Result, typename PtSegStrategy>
|
||||
class item_visitor_type
|
||||
{
|
||||
public:
|
||||
item_visitor_type(MultiGeometry const& multi_geometry,
|
||||
detail::relate::topology_check<MultiGeometry> const& tc,
|
||||
Result & result,
|
||||
PtSegStrategy const& strategy)
|
||||
: m_multi_geometry(multi_geometry)
|
||||
, m_tc(tc)
|
||||
, m_result(result)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Point, typename BoxPair>
|
||||
inline bool apply(Point const& point, BoxPair const& box_pair)
|
||||
{
|
||||
// The default strategy is enough for Point/Box
|
||||
if (! detail::disjoint::disjoint_point_box(point, box_pair.first))
|
||||
{
|
||||
typename boost::range_value<MultiGeometry>::type const&
|
||||
single = range::at(m_multi_geometry, box_pair.second);
|
||||
|
||||
int in_val = detail::within::point_in_geometry(point, single, m_strategy);
|
||||
|
||||
if (in_val > 0) // within
|
||||
{
|
||||
relate::set<interior, interior, '0', Transpose>(m_result);
|
||||
}
|
||||
else if (in_val == 0)
|
||||
{
|
||||
if (m_tc.check_boundary_point(point))
|
||||
relate::set<interior, boundary, '0', Transpose>(m_result);
|
||||
else
|
||||
relate::set<interior, interior, '0', Transpose>(m_result);
|
||||
}
|
||||
}
|
||||
|
||||
if ( BOOST_GEOMETRY_CONDITION(m_result.interrupt) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! (relate::may_update<interior, interior, '0', Transpose>(m_result)
|
||||
|| relate::may_update<interior, boundary, '0', Transpose>(m_result) ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
MultiGeometry const& m_multi_geometry;
|
||||
detail::relate::topology_check<MultiGeometry> const& m_tc;
|
||||
Result & m_result;
|
||||
PtSegStrategy const& m_strategy;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef typename point_type<MultiPoint>::type point1_type;
|
||||
typedef typename point_type<MultiGeometry>::type point2_type;
|
||||
typedef model::box<point1_type> box1_type;
|
||||
typedef model::box<point2_type> box2_type;
|
||||
typedef std::pair<box2_type, std::size_t> box_pair_type;
|
||||
|
||||
template <typename Result, typename Strategy>
|
||||
static inline void apply(MultiPoint const& multi_point,
|
||||
MultiGeometry const& multi_geometry,
|
||||
std::vector<box_pair_type> const& boxes,
|
||||
detail::relate::topology_check<MultiGeometry> const& tc,
|
||||
Result & result,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
item_visitor_type<Result, Strategy> visitor(multi_geometry, tc, result, strategy);
|
||||
|
||||
geometry::partition
|
||||
<
|
||||
box1_type
|
||||
>::apply(multi_point, boxes, visitor,
|
||||
expand_box_point(),
|
||||
overlaps_box_point(),
|
||||
expand_box_box_pair(),
|
||||
overlaps_box_box_pair());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// MultiGeometry - Linear or Areal
|
||||
// part of the algorithm calculating II, IB and IE
|
||||
// using rtree
|
||||
template <typename MultiPoint, typename MultiGeometry, bool Transpose>
|
||||
struct multi_point_multi_geometry_ii_ib_ie
|
||||
{
|
||||
typedef typename point_type<MultiPoint>::type point1_type;
|
||||
typedef typename point_type<MultiGeometry>::type point2_type;
|
||||
typedef model::box<point1_type> box1_type;
|
||||
typedef model::box<point2_type> box2_type;
|
||||
typedef std::pair<box2_type, std::size_t> box_pair_type;
|
||||
typedef std::vector<box_pair_type> boxes_type;
|
||||
typedef typename boxes_type::const_iterator boxes_iterator;
|
||||
|
||||
template <typename Result, typename Strategy>
|
||||
static inline void apply(MultiPoint const& multi_point,
|
||||
MultiGeometry const& multi_geometry,
|
||||
std::vector<box_pair_type> const& boxes,
|
||||
detail::relate::topology_check<MultiGeometry> const& tc,
|
||||
Result & result,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
index::rtree<box_pair_type, index::rstar<4> > rt(boxes.begin(), boxes.end());
|
||||
|
||||
typedef typename boost::range_const_iterator<MultiPoint>::type iterator;
|
||||
for ( iterator it = boost::begin(multi_point) ; it != boost::end(multi_point) ; ++it )
|
||||
{
|
||||
if (! (relate::may_update<interior, interior, '0', Transpose>(result)
|
||||
|| relate::may_update<interior, boundary, '0', Transpose>(result)
|
||||
|| relate::may_update<interior, exterior, '0', Transpose>(result) ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
typename boost::range_value<MultiPoint>::type const& point = *it;
|
||||
|
||||
boxes_type boxes_found;
|
||||
rt.query(index::intersects(point), std::back_inserter(boxes_found));
|
||||
|
||||
bool found_ii_or_ib = false;
|
||||
for (boxes_iterator bi = boxes_found.begin() ; bi != boxes_found.end() ; ++bi)
|
||||
{
|
||||
typename boost::range_value<MultiGeometry>::type const&
|
||||
single = range::at(multi_geometry, bi->second);
|
||||
|
||||
int in_val = detail::within::point_in_geometry(point, single, strategy);
|
||||
|
||||
if (in_val > 0) // within
|
||||
{
|
||||
relate::set<interior, interior, '0', Transpose>(result);
|
||||
found_ii_or_ib = true;
|
||||
}
|
||||
else if (in_val == 0) // on boundary of single
|
||||
{
|
||||
if (tc.check_boundary_point(point))
|
||||
relate::set<interior, boundary, '0', Transpose>(result);
|
||||
else
|
||||
relate::set<interior, interior, '0', Transpose>(result);
|
||||
found_ii_or_ib = true;
|
||||
}
|
||||
}
|
||||
|
||||
// neither interior nor boundary found -> exterior
|
||||
if (found_ii_or_ib == false)
|
||||
{
|
||||
relate::set<interior, exterior, '0', Transpose>(result);
|
||||
}
|
||||
|
||||
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// MultiGeometry - Linear or Areal
|
||||
template <typename MultiPoint, typename MultiGeometry, bool Transpose = false>
|
||||
struct multi_point_multi_geometry
|
||||
{
|
||||
static const bool interruption_enabled = true;
|
||||
|
||||
template <typename Result, typename Strategy>
|
||||
static inline void apply(MultiPoint const& multi_point,
|
||||
MultiGeometry const& multi_geometry,
|
||||
Result & result,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename point_type<MultiGeometry>::type point2_type;
|
||||
typedef model::box<point2_type> box2_type;
|
||||
typedef std::pair<box2_type, std::size_t> box_pair_type;
|
||||
|
||||
typename Strategy::envelope_strategy_type const
|
||||
envelope_strategy = strategy.get_envelope_strategy();
|
||||
|
||||
std::size_t count2 = boost::size(multi_geometry);
|
||||
std::vector<box_pair_type> boxes(count2);
|
||||
for (std::size_t i = 0 ; i < count2 ; ++i)
|
||||
{
|
||||
geometry::envelope(range::at(multi_geometry, i), boxes[i].first, envelope_strategy);
|
||||
geometry::detail::expand_by_epsilon(boxes[i].first);
|
||||
boxes[i].second = i;
|
||||
}
|
||||
|
||||
typedef detail::relate::topology_check<MultiGeometry> tc_t;
|
||||
tc_t tc(multi_geometry);
|
||||
|
||||
if ( relate::may_update<interior, interior, '0', Transpose>(result)
|
||||
|| relate::may_update<interior, boundary, '0', Transpose>(result)
|
||||
|| relate::may_update<interior, exterior, '0', Transpose>(result) )
|
||||
{
|
||||
// If there is no need to calculate IE, use partition
|
||||
if (! relate::may_update<interior, exterior, '0', Transpose>(result) )
|
||||
{
|
||||
multi_point_multi_geometry_ii_ib<MultiPoint, MultiGeometry, Transpose>
|
||||
::apply(multi_point, multi_geometry, boxes, tc, result, strategy);
|
||||
}
|
||||
else // otherwise use rtree
|
||||
{
|
||||
multi_point_multi_geometry_ii_ib_ie<MultiPoint, MultiGeometry, Transpose>
|
||||
::apply(multi_point, multi_geometry, boxes, tc, result, strategy);
|
||||
}
|
||||
}
|
||||
|
||||
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( relate::may_update<exterior, interior, tc_t::interior, Transpose>(result)
|
||||
|| relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result) )
|
||||
{
|
||||
if ( relate::may_update<exterior, interior, tc_t::interior, Transpose>(result)
|
||||
&& tc.has_interior() )
|
||||
{
|
||||
// TODO: this is not true if a linestring is degenerated to a point
|
||||
// then the interior has topological dimension = 0, not 1
|
||||
relate::set<exterior, interior, tc_t::interior, Transpose>(result);
|
||||
}
|
||||
|
||||
if ( relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result)
|
||||
&& tc.has_boundary() )
|
||||
{
|
||||
if (multi_point_geometry_eb<MultiGeometry>::apply(multi_point, tc))
|
||||
relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
|
||||
}
|
||||
}
|
||||
|
||||
relate::set<exterior, exterior, result_dimension<MultiPoint>::value, Transpose>(result);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename MultiPoint, typename Geometry,
|
||||
bool Transpose = false,
|
||||
bool isMulti = boost::is_same
|
||||
<
|
||||
typename tag_cast
|
||||
<
|
||||
typename tag<Geometry>::type, multi_tag
|
||||
>::type,
|
||||
multi_tag
|
||||
>::value
|
||||
>
|
||||
struct multi_point_geometry
|
||||
: multi_point_single_geometry<MultiPoint, Geometry, Transpose>
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename Geometry, bool Transpose>
|
||||
struct multi_point_geometry<MultiPoint, Geometry, Transpose, true>
|
||||
: multi_point_multi_geometry<MultiPoint, Geometry, Transpose>
|
||||
{};
|
||||
|
||||
|
||||
// transposed result of multi_point_geometry
|
||||
template <typename Geometry, typename MultiPoint>
|
||||
struct geometry_multi_point
|
||||
{
|
||||
static const bool interruption_enabled = true;
|
||||
|
||||
template <typename Result, typename Strategy>
|
||||
static inline void apply(Geometry const& geometry, MultiPoint const& multi_point,
|
||||
Result & result, Strategy const& strategy)
|
||||
{
|
||||
multi_point_geometry<MultiPoint, Geometry, true>::apply(multi_point, geometry, result, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::relate
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_MULTI_POINT_GEOMETRY_HPP
|
@ -60,29 +60,27 @@ struct point_geometry
|
||||
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
||||
return;
|
||||
|
||||
// the point is on the boundary
|
||||
if ( pig == 0 )
|
||||
typedef detail::relate::topology_check<Geometry> tc_t;
|
||||
if ( relate::may_update<exterior, interior, tc_t::interior, Transpose>(result)
|
||||
|| relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result) )
|
||||
{
|
||||
// NOTE: even for MLs, if there is at least one boundary point,
|
||||
// somewhere there must be another one
|
||||
|
||||
// check if there are other boundaries outside
|
||||
typedef detail::relate::topology_check<Geometry> tc_t;
|
||||
//tc_t tc(geometry, point);
|
||||
//if ( tc.has_interior )
|
||||
// the point is on the boundary
|
||||
if ( pig == 0 )
|
||||
{
|
||||
// NOTE: even for MLs, if there is at least one boundary point,
|
||||
// somewhere there must be another one
|
||||
relate::set<exterior, interior, tc_t::interior, Transpose>(result);
|
||||
//if ( tc.has_boundary )
|
||||
relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if there is a boundary in Geometry
|
||||
typedef detail::relate::topology_check<Geometry> tc_t;
|
||||
tc_t tc(geometry);
|
||||
if ( tc.has_interior )
|
||||
relate::set<exterior, interior, tc_t::interior, Transpose>(result);
|
||||
if ( tc.has_boundary )
|
||||
relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if there is a boundary in Geometry
|
||||
tc_t tc(geometry);
|
||||
if ( tc.has_interior() )
|
||||
relate::set<exterior, interior, tc_t::interior, Transpose>(result);
|
||||
if ( tc.has_boundary() )
|
||||
relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -165,22 +165,41 @@ struct multipoint_multipoint
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: ADD A CHECK TO THE RESULT INDICATING IF THE FIRST AND/OR SECOND GEOMETRY MUST BE ANALYSED
|
||||
// The geometry containing smaller number of points will be analysed first
|
||||
if ( boost::size(multi_point1) < boost::size(multi_point2) )
|
||||
{
|
||||
search_both<false>(multi_point1, multi_point2, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
search_both<true>(multi_point2, multi_point1, result);
|
||||
}
|
||||
|
||||
// TODO: if I/I is set for one MPt, this won't be changed when the other one in analysed
|
||||
// so if e.g. only I/I must be analysed we musn't check the other MPt
|
||||
relate::set<exterior, exterior, result_dimension<MultiPoint1>::value>(result);
|
||||
}
|
||||
|
||||
// TODO: Also, the geometry with the smaller number of points may be analysed first
|
||||
//if ( boost::size(multi_point1) < boost::size(multi_point2) )
|
||||
template <bool Transpose, typename MPt1, typename MPt2, typename Result>
|
||||
static inline void search_both(MPt1 const& first_sorted_mpt, MPt2 const& first_iterated_mpt,
|
||||
Result & result)
|
||||
{
|
||||
if ( relate::may_update<interior, interior, '0'>(result)
|
||||
|| relate::may_update<interior, exterior, '0'>(result)
|
||||
|| relate::may_update<exterior, interior, '0'>(result) )
|
||||
{
|
||||
// NlogN + MlogN
|
||||
bool is_disjoint = search<Transpose>(first_sorted_mpt, first_iterated_mpt, result);
|
||||
|
||||
// NlogN + MlogN
|
||||
bool all_handled = search<false>(multi_point1, multi_point2, result);
|
||||
|
||||
if ( BOOST_GEOMETRY_CONDITION(all_handled || result.interrupt) )
|
||||
return;
|
||||
if ( BOOST_GEOMETRY_CONDITION(is_disjoint || result.interrupt) )
|
||||
return;
|
||||
}
|
||||
|
||||
// MlogM + NlogM
|
||||
search<true>(multi_point2, multi_point1, result);
|
||||
if ( relate::may_update<interior, interior, '0'>(result)
|
||||
|| relate::may_update<interior, exterior, '0'>(result)
|
||||
|| relate::may_update<exterior, interior, '0'>(result) )
|
||||
{
|
||||
// MlogM + NlogM
|
||||
search<! Transpose>(first_iterated_mpt, first_sorted_mpt, result);
|
||||
}
|
||||
}
|
||||
|
||||
template <bool Transpose,
|
||||
@ -215,9 +234,6 @@ struct multipoint_multipoint
|
||||
break;
|
||||
}
|
||||
|
||||
// an optimization
|
||||
bool all_handled = false;
|
||||
|
||||
if ( found_inside ) // some point of MP2 is equal to some of MP1
|
||||
{
|
||||
// TODO: if I/I is set for one MPt, this won't be changed when the other one in analysed
|
||||
@ -234,14 +250,10 @@ struct multipoint_multipoint
|
||||
{
|
||||
relate::set<interior, exterior, '0', Transpose>(result);
|
||||
relate::set<exterior, interior, '0', Transpose>(result);
|
||||
|
||||
// if no point is intersecting the other MPt then we musn't analyse the reversed case
|
||||
all_handled = true;
|
||||
}
|
||||
|
||||
relate::set<exterior, exterior, result_dimension<point_type>::value, Transpose>(result);
|
||||
|
||||
return all_handled;
|
||||
// if no point is intersecting the other MPt then we musn't analyse the reversed case
|
||||
return ! found_inside;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,22 +1,23 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_TOPOLOGY_CHECK_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_TOPOLOGY_CHECK_HPP
|
||||
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
|
||||
#include <boost/geometry/policies/compare.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/less.hpp>
|
||||
|
||||
#include <boost/geometry/util/has_nan_coordinate.hpp>
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry {
|
||||
|
||||
@ -51,31 +52,63 @@ struct topology_check<Linestring, linestring_tag>
|
||||
static const char interior = '1';
|
||||
static const char boundary = '0';
|
||||
|
||||
bool has_interior;
|
||||
bool has_boundary;
|
||||
|
||||
topology_check(Linestring const& ls)
|
||||
: m_ls(ls)
|
||||
, m_is_initialized(false)
|
||||
{}
|
||||
|
||||
bool has_interior() const
|
||||
{
|
||||
init(ls, 0); /*dummy param*/
|
||||
init();
|
||||
return m_has_interior;
|
||||
}
|
||||
|
||||
template <typename IgnoreBoundaryPoint>
|
||||
topology_check(Linestring const& ls, IgnoreBoundaryPoint const& ibp)
|
||||
bool has_boundary() const
|
||||
{
|
||||
init(ls, ibp); /*dummy param, won't be used*/
|
||||
init();
|
||||
return m_has_boundary;
|
||||
}
|
||||
|
||||
// Even if some point is on the boundary, if the Linestring has the boundary,
|
||||
// there will be second boundary point different than IgnoreBoundaryPoint
|
||||
template <typename IgnoreBoundaryPoint>
|
||||
void init(Linestring const& ls, IgnoreBoundaryPoint const&)
|
||||
/*template <typename Point>
|
||||
bool check_boundary_point(Point const& point) const
|
||||
{
|
||||
std::size_t count = boost::size(ls);
|
||||
has_interior = count > 0;
|
||||
init();
|
||||
return m_has_boundary
|
||||
&& ( equals::equals_point_point(point, range::front(m_ls))
|
||||
|| equals::equals_point_point(point, range::back(m_ls)) );
|
||||
}*/
|
||||
|
||||
template <typename Visitor>
|
||||
void for_each_boundary_point(Visitor & visitor) const
|
||||
{
|
||||
init();
|
||||
if (m_has_boundary)
|
||||
{
|
||||
if (visitor.apply(range::front(m_ls)))
|
||||
visitor.apply(range::back(m_ls));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void init() const
|
||||
{
|
||||
if (m_is_initialized)
|
||||
return;
|
||||
|
||||
std::size_t count = boost::size(m_ls);
|
||||
m_has_interior = count > 0;
|
||||
// NOTE: Linestring with all points equal is treated as 1d linear ring
|
||||
has_boundary = count > 1
|
||||
&& ! detail::equals::equals_point_point(range::front(ls), range::back(ls));
|
||||
m_has_boundary = count > 1
|
||||
&& ! detail::equals::equals_point_point(range::front(m_ls), range::back(m_ls));
|
||||
|
||||
m_is_initialized = true;
|
||||
}
|
||||
|
||||
Linestring const& m_ls;
|
||||
mutable bool m_is_initialized;
|
||||
|
||||
mutable bool m_has_interior;
|
||||
mutable bool m_has_boundary;
|
||||
};
|
||||
|
||||
template <typename MultiLinestring>
|
||||
@ -84,29 +117,56 @@ struct topology_check<MultiLinestring, multi_linestring_tag>
|
||||
static const char interior = '1';
|
||||
static const char boundary = '0';
|
||||
|
||||
bool has_interior;
|
||||
bool has_boundary;
|
||||
|
||||
topology_check(MultiLinestring const& mls)
|
||||
: m_mls(mls)
|
||||
, m_is_initialized(false)
|
||||
{}
|
||||
|
||||
bool has_interior() const
|
||||
{
|
||||
init(mls, not_ignoring_counter());
|
||||
init();
|
||||
return m_has_interior;
|
||||
}
|
||||
|
||||
template <typename IgnoreBoundaryPoint>
|
||||
topology_check(MultiLinestring const& mls, IgnoreBoundaryPoint const& ibp)
|
||||
bool has_boundary() const
|
||||
{
|
||||
init(mls, ignoring_counter<IgnoreBoundaryPoint>(ibp));
|
||||
init();
|
||||
return m_has_boundary;
|
||||
}
|
||||
|
||||
template <typename OddCounter>
|
||||
void init(MultiLinestring const& mls, OddCounter const& odd_counter)
|
||||
template <typename Point>
|
||||
bool check_boundary_point(Point const& point) const
|
||||
{
|
||||
typedef typename geometry::point_type<MultiLinestring>::type point_type;
|
||||
std::vector<point_type> endpoints;
|
||||
endpoints.reserve(boost::size(mls) * 2);
|
||||
init();
|
||||
|
||||
if (! m_has_boundary)
|
||||
return false;
|
||||
|
||||
std::size_t count = count_equal(m_endpoints.begin(), m_endpoints.end(), point);
|
||||
|
||||
return count % 2 != 0; // odd count -> boundary
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
void for_each_boundary_point(Visitor & visitor) const
|
||||
{
|
||||
init();
|
||||
if (m_has_boundary)
|
||||
{
|
||||
for_each_boundary_point(m_endpoints.begin(), m_endpoints.end(), visitor);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void init() const
|
||||
{
|
||||
if (m_is_initialized)
|
||||
return;
|
||||
|
||||
m_endpoints.reserve(boost::size(m_mls) * 2);
|
||||
|
||||
typedef typename boost::range_iterator<MultiLinestring const>::type ls_iterator;
|
||||
for ( ls_iterator it = boost::begin(mls) ; it != boost::end(mls) ; ++it )
|
||||
for ( ls_iterator it = boost::begin(m_mls) ; it != boost::end(m_mls) ; ++it )
|
||||
{
|
||||
typename boost::range_reference<MultiLinestring const>::type
|
||||
ls = *it;
|
||||
@ -115,7 +175,7 @@ struct topology_check<MultiLinestring, multi_linestring_tag>
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
has_interior = true;
|
||||
m_has_interior = true;
|
||||
}
|
||||
|
||||
if (count > 1)
|
||||
@ -138,62 +198,59 @@ struct topology_check<MultiLinestring, multi_linestring_tag>
|
||||
// is not used anywhere in the code, still it's safer this way
|
||||
if (! geometry::has_nan_coordinate(front_pt))
|
||||
{
|
||||
endpoints.push_back(front_pt);
|
||||
m_endpoints.push_back(front_pt);
|
||||
}
|
||||
if (! geometry::has_nan_coordinate(back_pt))
|
||||
{
|
||||
endpoints.push_back(back_pt);
|
||||
m_endpoints.push_back(back_pt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
has_boundary = false;
|
||||
m_has_boundary = false;
|
||||
|
||||
if ( !endpoints.empty() )
|
||||
if (! m_endpoints.empty() )
|
||||
{
|
||||
std::sort(endpoints.begin(), endpoints.end(), geometry::less<point_type>());
|
||||
has_boundary = odd_counter(endpoints.begin(), endpoints.end());
|
||||
std::sort(m_endpoints.begin(), m_endpoints.end(), relate::less());
|
||||
m_has_boundary = find_odd_count(m_endpoints.begin(), m_endpoints.end());
|
||||
}
|
||||
|
||||
m_is_initialized = true;
|
||||
}
|
||||
|
||||
struct not_ignoring_counter
|
||||
template <typename It, typename Point>
|
||||
static inline std::size_t count_equal(It first, It last, Point const& point)
|
||||
{
|
||||
template <typename It>
|
||||
bool operator()(It first, It last) const
|
||||
{
|
||||
return find_odd_count(first, last);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Point>
|
||||
struct ignoring_counter
|
||||
{
|
||||
ignoring_counter(Point const& pt) : m_pt(pt) {}
|
||||
|
||||
template <typename It>
|
||||
bool operator()(It first, It last) const
|
||||
{
|
||||
typedef typename std::iterator_traits<It>::value_type point_type;
|
||||
|
||||
std::pair<It, It> ignore_range
|
||||
= std::equal_range(first, last, m_pt,
|
||||
geometry::less<point_type>());
|
||||
|
||||
if ( find_odd_count(first, ignore_range.first) )
|
||||
return true;
|
||||
|
||||
return find_odd_count(ignore_range.second, last);
|
||||
}
|
||||
|
||||
Point const& m_pt;
|
||||
};
|
||||
std::pair<It, It> rng = std::equal_range(first, last, point, relate::less());
|
||||
return (std::size_t)std::distance(rng.first, rng.second);
|
||||
}
|
||||
|
||||
template <typename It>
|
||||
static inline bool find_odd_count(It first, It last)
|
||||
{
|
||||
if ( first == last )
|
||||
interrupting_visitor visitor;
|
||||
for_each_boundary_point(first, last, visitor);
|
||||
return visitor.found;
|
||||
}
|
||||
|
||||
struct interrupting_visitor
|
||||
{
|
||||
bool found;
|
||||
interrupting_visitor() : found(false) {}
|
||||
template <typename Point>
|
||||
bool apply(Point const&)
|
||||
{
|
||||
found = true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename It, typename Visitor>
|
||||
static void for_each_boundary_point(It first, It last, Visitor& visitor)
|
||||
{
|
||||
if ( first == last )
|
||||
return;
|
||||
|
||||
std::size_t count = 1;
|
||||
It prev = first;
|
||||
@ -203,8 +260,14 @@ struct topology_check<MultiLinestring, multi_linestring_tag>
|
||||
// the end of the equal points subrange
|
||||
if ( ! equals::equals_point_point(*first, *prev) )
|
||||
{
|
||||
// odd count -> boundary
|
||||
if ( count % 2 != 0 )
|
||||
return true;
|
||||
{
|
||||
if (! visitor.apply(*prev))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
count = 1;
|
||||
}
|
||||
@ -214,8 +277,22 @@ struct topology_check<MultiLinestring, multi_linestring_tag>
|
||||
}
|
||||
}
|
||||
|
||||
return count % 2 != 0;
|
||||
// odd count -> boundary
|
||||
if ( count % 2 != 0 )
|
||||
{
|
||||
visitor.apply(*prev);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
MultiLinestring const& m_mls;
|
||||
mutable bool m_is_initialized;
|
||||
|
||||
mutable bool m_has_interior;
|
||||
mutable bool m_has_boundary;
|
||||
|
||||
typedef typename geometry::point_type<MultiLinestring>::type point_type;
|
||||
mutable std::vector<point_type> m_endpoints;
|
||||
};
|
||||
|
||||
template <typename Ring>
|
||||
@ -223,12 +300,11 @@ struct topology_check<Ring, ring_tag>
|
||||
{
|
||||
static const char interior = '2';
|
||||
static const char boundary = '1';
|
||||
static const bool has_interior = true;
|
||||
static const bool has_boundary = true;
|
||||
|
||||
topology_check(Ring const&) {}
|
||||
template <typename P>
|
||||
topology_check(Ring const&, P const&) {}
|
||||
|
||||
static bool has_interior() { return true; }
|
||||
static bool has_boundary() { return true; }
|
||||
};
|
||||
|
||||
template <typename Polygon>
|
||||
@ -236,12 +312,11 @@ struct topology_check<Polygon, polygon_tag>
|
||||
{
|
||||
static const char interior = '2';
|
||||
static const char boundary = '1';
|
||||
static const bool has_interior = true;
|
||||
static const bool has_boundary = true;
|
||||
|
||||
|
||||
topology_check(Polygon const&) {}
|
||||
template <typename P>
|
||||
topology_check(Polygon const&, P const&) {}
|
||||
|
||||
static bool has_interior() { return true; }
|
||||
static bool has_boundary() { return true; }
|
||||
};
|
||||
|
||||
template <typename MultiPolygon>
|
||||
@ -249,12 +324,13 @@ struct topology_check<MultiPolygon, multi_polygon_tag>
|
||||
{
|
||||
static const char interior = '2';
|
||||
static const char boundary = '1';
|
||||
static const bool has_interior = true;
|
||||
static const bool has_boundary = true;
|
||||
|
||||
|
||||
topology_check(MultiPolygon const&) {}
|
||||
template <typename P>
|
||||
topology_check(MultiPolygon const&, P const&) {}
|
||||
|
||||
static bool has_interior() { return true; }
|
||||
static bool has_boundary() { return true; }
|
||||
template <typename Point>
|
||||
static bool check_boundary_point(Point const& ) { return true; }
|
||||
};
|
||||
|
||||
}} // namespace detail::relate
|
||||
|
@ -0,0 +1,459 @@
|
||||
// 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) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2013, 2014, 2015, 2017.
|
||||
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_TOUCHES_IMPLEMENTATION_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_TOUCHES_IMPLEMENTATION_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/algorithms/detail/for_each_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
|
||||
#include <boost/geometry/algorithms/detail/sub_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
|
||||
#include <boost/geometry/algorithms/detail/touches/interface.hpp>
|
||||
#include <boost/geometry/algorithms/disjoint.hpp>
|
||||
#include <boost/geometry/algorithms/intersects.hpp>
|
||||
#include <boost/geometry/algorithms/num_geometries.hpp>
|
||||
#include <boost/geometry/algorithms/relate.hpp>
|
||||
|
||||
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace touches
|
||||
{
|
||||
|
||||
// Box/Box
|
||||
|
||||
template
|
||||
<
|
||||
std::size_t Dimension,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct box_box_loop
|
||||
{
|
||||
template <typename Box1, typename Box2>
|
||||
static inline bool apply(Box1 const& b1, Box2 const& b2, bool & touch)
|
||||
{
|
||||
typedef typename coordinate_type<Box1>::type coordinate_type1;
|
||||
typedef typename coordinate_type<Box2>::type coordinate_type2;
|
||||
|
||||
coordinate_type1 const& min1 = get<min_corner, Dimension>(b1);
|
||||
coordinate_type1 const& max1 = get<max_corner, Dimension>(b1);
|
||||
coordinate_type2 const& min2 = get<min_corner, Dimension>(b2);
|
||||
coordinate_type2 const& max2 = get<max_corner, Dimension>(b2);
|
||||
|
||||
// TODO assert or exception?
|
||||
//BOOST_GEOMETRY_ASSERT(min1 <= max1 && min2 <= max2);
|
||||
|
||||
if (max1 < min2 || max2 < min1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (max1 == min2 || max2 == min1)
|
||||
{
|
||||
touch = true;
|
||||
}
|
||||
|
||||
return box_box_loop
|
||||
<
|
||||
Dimension + 1,
|
||||
DimensionCount
|
||||
>::apply(b1, b2, touch);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct box_box_loop<DimensionCount, DimensionCount>
|
||||
{
|
||||
template <typename Box1, typename Box2>
|
||||
static inline bool apply(Box1 const& , Box2 const&, bool &)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct box_box
|
||||
{
|
||||
template <typename Box1, typename Box2, typename Strategy>
|
||||
static inline bool apply(Box1 const& b1, Box2 const& b2, Strategy const& /*strategy*/)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_same
|
||||
<
|
||||
typename geometry::coordinate_system<Box1>::type,
|
||||
typename geometry::coordinate_system<Box2>::type
|
||||
>::value
|
||||
));
|
||||
assert_dimension_equal<Box1, Box2>();
|
||||
|
||||
bool touches = false;
|
||||
bool ok = box_box_loop
|
||||
<
|
||||
0,
|
||||
dimension<Box1>::type::value
|
||||
>::apply(b1, b2, touches);
|
||||
|
||||
return ok && touches;
|
||||
}
|
||||
};
|
||||
|
||||
// Areal/Areal
|
||||
|
||||
struct areal_interrupt_policy
|
||||
{
|
||||
static bool const enabled = true;
|
||||
bool found_touch;
|
||||
bool found_not_touch;
|
||||
|
||||
// dummy variable required by self_get_turn_points::get_turns
|
||||
static bool const has_intersections = false;
|
||||
|
||||
inline bool result()
|
||||
{
|
||||
return found_touch && !found_not_touch;
|
||||
}
|
||||
|
||||
inline areal_interrupt_policy()
|
||||
: found_touch(false), found_not_touch(false)
|
||||
{}
|
||||
|
||||
template <typename Range>
|
||||
inline bool apply(Range const& range)
|
||||
{
|
||||
// if already rejected (temp workaround?)
|
||||
if ( found_not_touch )
|
||||
return true;
|
||||
|
||||
typedef typename boost::range_iterator<Range const>::type iterator;
|
||||
for ( iterator it = boost::begin(range) ; it != boost::end(range) ; ++it )
|
||||
{
|
||||
if ( it->has(overlay::operation_intersection) )
|
||||
{
|
||||
found_not_touch = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch(it->method)
|
||||
{
|
||||
case overlay::method_crosses:
|
||||
found_not_touch = true;
|
||||
return true;
|
||||
case overlay::method_equal:
|
||||
// Segment spatially equal means: at the right side
|
||||
// the polygon internally overlaps. So return false.
|
||||
found_not_touch = true;
|
||||
return true;
|
||||
case overlay::method_touch:
|
||||
case overlay::method_touch_interior:
|
||||
case overlay::method_collinear:
|
||||
if ( ok_for_touch(*it) )
|
||||
{
|
||||
found_touch = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
found_not_touch = true;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case overlay::method_none :
|
||||
case overlay::method_disjoint :
|
||||
case overlay::method_error :
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Turn>
|
||||
inline bool ok_for_touch(Turn const& turn)
|
||||
{
|
||||
return turn.both(overlay::operation_union)
|
||||
|| turn.both(overlay::operation_blocked)
|
||||
|| turn.combination(overlay::operation_union, overlay::operation_blocked)
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Geometry, typename PointInRingStrategy>
|
||||
struct check_each_ring_for_within
|
||||
{
|
||||
bool has_within;
|
||||
Geometry const& m_geometry;
|
||||
PointInRingStrategy const& m_strategy;
|
||||
|
||||
inline check_each_ring_for_within(Geometry const& g, PointInRingStrategy const& strategy)
|
||||
: has_within(false)
|
||||
, m_geometry(g)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Range>
|
||||
inline void apply(Range const& range)
|
||||
{
|
||||
typename geometry::point_type<Range>::type p;
|
||||
geometry::point_on_border(p, range);
|
||||
if ( !has_within && geometry::within(p, m_geometry, m_strategy) )
|
||||
{
|
||||
has_within = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename FirstGeometry, typename SecondGeometry, typename IntersectionStrategy>
|
||||
inline bool rings_containing(FirstGeometry const& geometry1,
|
||||
SecondGeometry const& geometry2,
|
||||
IntersectionStrategy const& strategy)
|
||||
{
|
||||
// NOTE: This strategy could be defined inside IntersectionStrategy
|
||||
typedef typename IntersectionStrategy::template point_in_geometry_strategy
|
||||
<
|
||||
FirstGeometry, SecondGeometry
|
||||
>::type point_in_ring_strategy_type;
|
||||
|
||||
point_in_ring_strategy_type point_in_ring_strategy
|
||||
= strategy.template get_point_in_geometry_strategy<FirstGeometry, SecondGeometry>();
|
||||
|
||||
check_each_ring_for_within
|
||||
<
|
||||
FirstGeometry, point_in_ring_strategy_type
|
||||
> checker(geometry1, point_in_ring_strategy);
|
||||
geometry::detail::for_each_range(geometry2, checker);
|
||||
return checker.has_within;
|
||||
}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct areal_areal
|
||||
{
|
||||
template <typename IntersectionStrategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
IntersectionStrategy const& strategy)
|
||||
{
|
||||
typedef detail::no_rescale_policy rescale_policy_type;
|
||||
typedef typename geometry::point_type<Geometry1>::type point_type;
|
||||
typedef detail::overlay::turn_info
|
||||
<
|
||||
point_type,
|
||||
typename segment_ratio_type<point_type, rescale_policy_type>::type
|
||||
> turn_info;
|
||||
|
||||
std::deque<turn_info> turns;
|
||||
detail::touches::areal_interrupt_policy policy;
|
||||
rescale_policy_type robust_policy;
|
||||
boost::geometry::get_turns
|
||||
<
|
||||
detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
|
||||
detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
|
||||
detail::overlay::assign_null_policy
|
||||
>(geometry1, geometry2, strategy, robust_policy, turns, policy);
|
||||
|
||||
return policy.result()
|
||||
&& ! geometry::detail::touches::rings_containing(geometry1, geometry2, strategy)
|
||||
&& ! geometry::detail::touches::rings_containing(geometry2, geometry1, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
// P/*
|
||||
|
||||
struct use_point_in_geometry
|
||||
{
|
||||
template <typename Point, typename Geometry, typename Strategy>
|
||||
static inline bool apply(Point const& point, Geometry const& geometry, Strategy const& strategy)
|
||||
{
|
||||
return detail::within::point_in_geometry(point, geometry, strategy) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}}
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch {
|
||||
|
||||
// P/P
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Tag2>
|
||||
struct touches<Geometry1, Geometry2, point_tag, Tag2, pointlike_tag, pointlike_tag, false>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const& , Geometry2 const& , Strategy const&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Tag2>
|
||||
struct touches<Geometry1, Geometry2, multi_point_tag, Tag2, pointlike_tag, pointlike_tag, false>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const&, Geometry2 const&, Strategy const&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// P/*
|
||||
|
||||
template <typename Point, typename Geometry, typename Tag2, typename CastedTag2>
|
||||
struct touches<Point, Geometry, point_tag, Tag2, pointlike_tag, CastedTag2, false>
|
||||
: detail::touches::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename MultiGeometry, typename Tag2, typename CastedTag2>
|
||||
struct touches<MultiPoint, MultiGeometry, multi_point_tag, Tag2, pointlike_tag, CastedTag2, false>
|
||||
: detail::relate::relate_impl
|
||||
<
|
||||
detail::de9im::static_mask_touches_type,
|
||||
MultiPoint,
|
||||
MultiGeometry
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename Geometry, typename MultiPoint, typename Tag1, typename CastedTag1>
|
||||
struct touches<Geometry, MultiPoint, Tag1, multi_point_tag, CastedTag1, pointlike_tag, false>
|
||||
: detail::relate::relate_impl
|
||||
<
|
||||
detail::de9im::static_mask_touches_type,
|
||||
Geometry,
|
||||
MultiPoint
|
||||
>
|
||||
{};
|
||||
|
||||
// Box/Box
|
||||
|
||||
template <typename Box1, typename Box2, typename CastedTag1, typename CastedTag2>
|
||||
struct touches<Box1, Box2, box_tag, box_tag, CastedTag1, CastedTag2, false>
|
||||
: detail::touches::box_box
|
||||
{};
|
||||
|
||||
template <typename Box1, typename Box2>
|
||||
struct touches<Box1, Box2, box_tag, box_tag, areal_tag, areal_tag, false>
|
||||
: detail::touches::box_box
|
||||
{};
|
||||
|
||||
// L/L
|
||||
|
||||
template <typename Linear1, typename Linear2, typename Tag1, typename Tag2>
|
||||
struct touches<Linear1, Linear2, Tag1, Tag2, linear_tag, linear_tag, false>
|
||||
: detail::relate::relate_impl
|
||||
<
|
||||
detail::de9im::static_mask_touches_type,
|
||||
Linear1,
|
||||
Linear2
|
||||
>
|
||||
{};
|
||||
|
||||
// L/A
|
||||
|
||||
template <typename Linear, typename Areal, typename Tag1, typename Tag2>
|
||||
struct touches<Linear, Areal, Tag1, Tag2, linear_tag, areal_tag, false>
|
||||
: detail::relate::relate_impl
|
||||
<
|
||||
detail::de9im::static_mask_touches_type,
|
||||
Linear,
|
||||
Areal
|
||||
>
|
||||
{};
|
||||
|
||||
// A/L
|
||||
template <typename Linear, typename Areal, typename Tag1, typename Tag2>
|
||||
struct touches<Areal, Linear, Tag1, Tag2, areal_tag, linear_tag, false>
|
||||
: detail::relate::relate_impl
|
||||
<
|
||||
detail::de9im::static_mask_touches_type,
|
||||
Areal,
|
||||
Linear
|
||||
>
|
||||
{};
|
||||
|
||||
// A/A
|
||||
|
||||
template <typename Areal1, typename Areal2, typename Tag1, typename Tag2>
|
||||
struct touches<Areal1, Areal2, Tag1, Tag2, areal_tag, areal_tag, false>
|
||||
: detail::relate::relate_impl
|
||||
<
|
||||
detail::de9im::static_mask_touches_type,
|
||||
Areal1,
|
||||
Areal2
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename Areal1, typename Areal2>
|
||||
struct touches<Areal1, Areal2, ring_tag, ring_tag, areal_tag, areal_tag, false>
|
||||
: detail::touches::areal_areal<Areal1, Areal2>
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
namespace resolve_variant {
|
||||
|
||||
template <typename Geometry>
|
||||
struct self_touches
|
||||
{
|
||||
static bool apply(Geometry const& geometry)
|
||||
{
|
||||
concepts::check<Geometry const>();
|
||||
|
||||
typedef typename strategy::relate::services::default_strategy
|
||||
<
|
||||
Geometry, Geometry
|
||||
>::type strategy_type;
|
||||
typedef detail::no_rescale_policy rescale_policy_type;
|
||||
typedef typename geometry::point_type<Geometry>::type point_type;
|
||||
typedef detail::overlay::turn_info
|
||||
<
|
||||
point_type,
|
||||
typename segment_ratio_type<point_type, rescale_policy_type>::type
|
||||
> turn_info;
|
||||
|
||||
typedef detail::overlay::get_turn_info
|
||||
<
|
||||
detail::overlay::assign_null_policy
|
||||
> policy_type;
|
||||
|
||||
std::deque<turn_info> turns;
|
||||
detail::touches::areal_interrupt_policy policy;
|
||||
strategy_type strategy;
|
||||
rescale_policy_type robust_policy;
|
||||
detail::self_get_turn_points::get_turns
|
||||
<
|
||||
policy_type
|
||||
>::apply(geometry, strategy, robust_policy, turns, policy, 0);
|
||||
|
||||
return policy.result();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_TOUCHES_IMPLEMENTATION_HPP
|
321
include/boost/geometry/algorithms/detail/touches/interface.hpp
Normal file
321
include/boost/geometry/algorithms/detail/touches/interface.hpp
Normal file
@ -0,0 +1,321 @@
|
||||
// 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) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2013, 2014, 2015, 2017.
|
||||
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_TOUCHES_INTERFACE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_TOUCHES_INTERFACE_HPP
|
||||
|
||||
|
||||
#include <deque>
|
||||
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
|
||||
#include <boost/geometry/core/reverse_dispatch.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tag_cast.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/relate.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch {
|
||||
|
||||
// TODO: Since CastedTags are used is Reverse needed?
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Tag1 = typename tag<Geometry1>::type,
|
||||
typename Tag2 = typename tag<Geometry2>::type,
|
||||
typename CastedTag1 = typename tag_cast<Tag1, pointlike_tag, linear_tag, areal_tag>::type,
|
||||
typename CastedTag2 = typename tag_cast<Tag2, pointlike_tag, linear_tag, areal_tag>::type,
|
||||
bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
|
||||
>
|
||||
struct touches
|
||||
: not_implemented<Tag1, Tag2>
|
||||
{};
|
||||
|
||||
// If reversal is needed, perform it
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Tag1, typename Tag2,
|
||||
typename CastedTag1, typename CastedTag2
|
||||
>
|
||||
struct touches<Geometry1, Geometry2, Tag1, Tag2, CastedTag1, CastedTag2, true>
|
||||
: touches<Geometry2, Geometry1, Tag2, Tag1, CastedTag2, CastedTag1, false>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
|
||||
{
|
||||
return touches<Geometry2, Geometry1>::apply(g2, g1, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
namespace resolve_strategy
|
||||
{
|
||||
|
||||
struct touches
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return dispatch::touches
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
default_strategy)
|
||||
{
|
||||
typedef typename strategy::relate::services::default_strategy
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
return dispatch::touches
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_strategy
|
||||
|
||||
|
||||
namespace resolve_variant {
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct touches
|
||||
{
|
||||
template <typename Strategy>
|
||||
static bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
|
||||
{
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
|
||||
return resolve_strategy::touches::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
|
||||
struct touches<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: boost::static_visitor<bool>
|
||||
{
|
||||
Geometry2 const& m_geometry2;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry2 const& geometry2, Strategy const& strategy)
|
||||
: m_geometry2(geometry2)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry1>
|
||||
bool operator()(Geometry1 const& geometry1) const
|
||||
{
|
||||
return touches<Geometry1, Geometry2>::apply(geometry1, m_geometry2, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct touches<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: boost::static_visitor<bool>
|
||||
{
|
||||
Geometry1 const& m_geometry1;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry1 const& geometry1, Strategy const& strategy)
|
||||
: m_geometry1(geometry1)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry2>
|
||||
bool operator()(Geometry2 const& geometry2) const
|
||||
{
|
||||
return touches<Geometry1, Geometry2>::apply(m_geometry1, geometry2, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T1),
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T2)>
|
||||
struct touches<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: boost::static_visitor<bool>
|
||||
{
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
bool operator()(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2) const
|
||||
{
|
||||
return touches<Geometry1, Geometry2>::apply(geometry1, geometry2, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct self_touches;
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct self_touches<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
{
|
||||
struct visitor: boost::static_visitor<bool>
|
||||
{
|
||||
template <typename Geometry>
|
||||
bool operator()(Geometry const& geometry) const
|
||||
{
|
||||
return self_touches<Geometry>::apply(geometry);
|
||||
}
|
||||
};
|
||||
|
||||
static inline bool
|
||||
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
|
||||
{
|
||||
return boost::apply_visitor(visitor(), geometry);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_variant
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check{has at least one touching point (self-tangency)}
|
||||
\note This function can be called for one geometry (self-tangency) and
|
||||
also for two geometries (touch)
|
||||
\ingroup touches
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry
|
||||
\return \return_check{is self-touching}
|
||||
|
||||
\qbk{distinguish,one geometry}
|
||||
\qbk{[def __one_parameter__]}
|
||||
\qbk{[include reference/algorithms/touches.qbk]}
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline bool touches(Geometry const& geometry)
|
||||
{
|
||||
return resolve_variant::self_touches<Geometry>::apply(geometry);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check2{have at least one touching point (tangent - non overlapping)}
|
||||
\ingroup touches
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\return \return_check2{touch each other}
|
||||
|
||||
\qbk{distinguish,two geometries}
|
||||
\qbk{[include reference/algorithms/touches.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline bool touches(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
return resolve_variant::touches
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, default_strategy());
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief \brief_check2{have at least one touching point (tangent - non overlapping)}
|
||||
\ingroup touches
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam Strategy \tparam_strategy{Touches}
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param strategy \param_strategy{touches}
|
||||
\return \return_check2{touch each other}
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{[include reference/algorithms/touches.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
inline bool touches(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return resolve_variant::touches
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_TOUCHES_INTERFACE_HPP
|
@ -0,0 +1,306 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2013, 2014, 2017.
|
||||
// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_IMPLEMENTATION_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_IMPLEMENTATION_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/within/interface.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/point_order.hpp>
|
||||
#include <boost/geometry/core/ring_type.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
#include <boost/geometry/util/order_as_direction.hpp>
|
||||
#include <boost/geometry/views/closeable_view.hpp>
|
||||
#include <boost/geometry/views/reversible_view.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/within/multi_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/relate.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/do_reverse.hpp>
|
||||
#include <deque>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace within {
|
||||
|
||||
struct use_point_in_geometry
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
|
||||
{
|
||||
return detail::within::point_in_geometry(geometry1, geometry2, strategy) == 1;
|
||||
}
|
||||
};
|
||||
|
||||
struct use_relate
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
|
||||
{
|
||||
typedef typename detail::de9im::static_mask_within_type
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::type within_mask;
|
||||
return geometry::relate(geometry1, geometry2, within_mask(), strategy);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::within
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template <typename Point, typename Box>
|
||||
struct within<Point, Box, point_tag, box_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
|
||||
{
|
||||
boost::ignore_unused_variable_warning(strategy);
|
||||
return strategy.apply(point, box);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box1, typename Box2>
|
||||
struct within<Box1, Box2, box_tag, box_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
|
||||
{
|
||||
assert_dimension_equal<Box1, Box2>();
|
||||
boost::ignore_unused_variable_warning(strategy);
|
||||
return strategy.apply(box1, box2);
|
||||
}
|
||||
};
|
||||
|
||||
// P/P
|
||||
|
||||
template <typename Point1, typename Point2>
|
||||
struct within<Point1, Point2, point_tag, point_tag>
|
||||
: public detail::within::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename Point, typename MultiPoint>
|
||||
struct within<Point, MultiPoint, point_tag, multi_point_tag>
|
||||
: public detail::within::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename Point>
|
||||
struct within<MultiPoint, Point, multi_point_tag, point_tag>
|
||||
: public detail::within::multi_point_point
|
||||
{};
|
||||
|
||||
template <typename MultiPoint1, typename MultiPoint2>
|
||||
struct within<MultiPoint1, MultiPoint2, multi_point_tag, multi_point_tag>
|
||||
: public detail::within::multi_point_multi_point
|
||||
{};
|
||||
|
||||
// P/L
|
||||
|
||||
template <typename Point, typename Segment>
|
||||
struct within<Point, Segment, point_tag, segment_tag>
|
||||
: public detail::within::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename Point, typename Linestring>
|
||||
struct within<Point, Linestring, point_tag, linestring_tag>
|
||||
: public detail::within::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename Point, typename MultiLinestring>
|
||||
struct within<Point, MultiLinestring, point_tag, multi_linestring_tag>
|
||||
: public detail::within::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename Segment>
|
||||
struct within<MultiPoint, Segment, multi_point_tag, segment_tag>
|
||||
: public detail::within::multi_point_single_geometry<true>
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename Linestring>
|
||||
struct within<MultiPoint, Linestring, multi_point_tag, linestring_tag>
|
||||
: public detail::within::multi_point_single_geometry<true>
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename MultiLinestring>
|
||||
struct within<MultiPoint, MultiLinestring, multi_point_tag, multi_linestring_tag>
|
||||
: public detail::within::multi_point_multi_geometry<true>
|
||||
{};
|
||||
|
||||
// P/A
|
||||
|
||||
template <typename Point, typename Ring>
|
||||
struct within<Point, Ring, point_tag, ring_tag>
|
||||
: public detail::within::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename Point, typename Polygon>
|
||||
struct within<Point, Polygon, point_tag, polygon_tag>
|
||||
: public detail::within::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename Point, typename MultiPolygon>
|
||||
struct within<Point, MultiPolygon, point_tag, multi_polygon_tag>
|
||||
: public detail::within::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename Ring>
|
||||
struct within<MultiPoint, Ring, multi_point_tag, ring_tag>
|
||||
: public detail::within::multi_point_single_geometry<true>
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename Polygon>
|
||||
struct within<MultiPoint, Polygon, multi_point_tag, polygon_tag>
|
||||
: public detail::within::multi_point_single_geometry<true>
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename MultiPolygon>
|
||||
struct within<MultiPoint, MultiPolygon, multi_point_tag, multi_polygon_tag>
|
||||
: public detail::within::multi_point_multi_geometry<true>
|
||||
{};
|
||||
|
||||
// L/L
|
||||
|
||||
template <typename Linestring1, typename Linestring2>
|
||||
struct within<Linestring1, Linestring2, linestring_tag, linestring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename Linestring, typename MultiLinestring>
|
||||
struct within<Linestring, MultiLinestring, linestring_tag, multi_linestring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring, typename Linestring>
|
||||
struct within<MultiLinestring, Linestring, multi_linestring_tag, linestring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring1, typename MultiLinestring2>
|
||||
struct within<MultiLinestring1, MultiLinestring2, multi_linestring_tag, multi_linestring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
// L/A
|
||||
|
||||
template <typename Linestring, typename Ring>
|
||||
struct within<Linestring, Ring, linestring_tag, ring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring, typename Ring>
|
||||
struct within<MultiLinestring, Ring, multi_linestring_tag, ring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename Linestring, typename Polygon>
|
||||
struct within<Linestring, Polygon, linestring_tag, polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring, typename Polygon>
|
||||
struct within<MultiLinestring, Polygon, multi_linestring_tag, polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename Linestring, typename MultiPolygon>
|
||||
struct within<Linestring, MultiPolygon, linestring_tag, multi_polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring, typename MultiPolygon>
|
||||
struct within<MultiLinestring, MultiPolygon, multi_linestring_tag, multi_polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
// A/A
|
||||
|
||||
template <typename Ring1, typename Ring2>
|
||||
struct within<Ring1, Ring2, ring_tag, ring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename Ring, typename Polygon>
|
||||
struct within<Ring, Polygon, ring_tag, polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename Polygon, typename Ring>
|
||||
struct within<Polygon, Ring, polygon_tag, ring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename Polygon1, typename Polygon2>
|
||||
struct within<Polygon1, Polygon2, polygon_tag, polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename Ring, typename MultiPolygon>
|
||||
struct within<Ring, MultiPolygon, ring_tag, multi_polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiPolygon, typename Ring>
|
||||
struct within<MultiPolygon, Ring, multi_polygon_tag, ring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename Polygon, typename MultiPolygon>
|
||||
struct within<Polygon, MultiPolygon, polygon_tag, multi_polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiPolygon, typename Polygon>
|
||||
struct within<MultiPolygon, Polygon, multi_polygon_tag, polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiPolygon1, typename MultiPolygon2>
|
||||
struct within<MultiPolygon1, MultiPolygon2, multi_polygon_tag, multi_polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#include <boost/geometry/index/rtree.hpp>
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_IMPLEMENTATION_HPP
|
304
include/boost/geometry/algorithms/detail/within/interface.hpp
Normal file
304
include/boost/geometry/algorithms/detail/within/interface.hpp
Normal file
@ -0,0 +1,304 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2013, 2014, 2017.
|
||||
// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_INTERFACE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_INTERFACE_HPP
|
||||
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tag_cast.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/strategies/concepts/within_concept.hpp>
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/within.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Tag1 = typename tag<Geometry1>::type,
|
||||
typename Tag2 = typename tag<Geometry2>::type
|
||||
>
|
||||
struct within
|
||||
: not_implemented<Tag1, Tag2>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
namespace resolve_strategy
|
||||
{
|
||||
|
||||
struct within
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concepts::within::check
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
|
||||
Strategy
|
||||
>();
|
||||
|
||||
return dispatch::within<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
default_strategy)
|
||||
{
|
||||
typedef typename strategy::within::services::default_strategy
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
return apply(geometry1, geometry2, strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_strategy
|
||||
|
||||
|
||||
namespace resolve_variant
|
||||
{
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct within
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
assert_dimension_equal<Geometry1, Geometry2>();
|
||||
|
||||
return resolve_strategy::within::apply(geometry1,
|
||||
geometry2,
|
||||
strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
|
||||
struct within<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: boost::static_visitor<bool>
|
||||
{
|
||||
Geometry2 const& m_geometry2;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry2 const& geometry2, Strategy const& strategy)
|
||||
: m_geometry2(geometry2)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry1>
|
||||
bool operator()(Geometry1 const& geometry1) const
|
||||
{
|
||||
return within<Geometry1, Geometry2>::apply(geometry1,
|
||||
m_geometry2,
|
||||
m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool
|
||||
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(geometry2, strategy),
|
||||
geometry1);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct within<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: boost::static_visitor<bool>
|
||||
{
|
||||
Geometry1 const& m_geometry1;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry1 const& geometry1, Strategy const& strategy)
|
||||
: m_geometry1(geometry1)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry2>
|
||||
bool operator()(Geometry2 const& geometry2) const
|
||||
{
|
||||
return within<Geometry1, Geometry2>::apply(m_geometry1,
|
||||
geometry2,
|
||||
m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool
|
||||
apply(Geometry1 const& geometry1,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(geometry1, strategy),
|
||||
geometry2
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T1),
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T2)
|
||||
>
|
||||
struct within<
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
|
||||
>
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: boost::static_visitor<bool>
|
||||
{
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Strategy const& strategy): m_strategy(strategy) {}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
bool operator()(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2) const
|
||||
{
|
||||
return within<Geometry1, Geometry2>::apply(geometry1,
|
||||
geometry2,
|
||||
m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool
|
||||
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(strategy),
|
||||
geometry1,
|
||||
geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check12{is completely inside}
|
||||
\ingroup within
|
||||
\details \details_check12{within, is completely inside}.
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry which might be within the second geometry
|
||||
\param geometry2 \param_geometry which might contain the first geometry
|
||||
\return true if geometry1 is completely contained within geometry2,
|
||||
else false
|
||||
\note The default strategy is used for within detection
|
||||
|
||||
|
||||
\qbk{[include reference/algorithms/within.qbk]}
|
||||
|
||||
\qbk{
|
||||
[heading Example]
|
||||
[within]
|
||||
[within_output]
|
||||
}
|
||||
*/
|
||||
template<typename Geometry1, typename Geometry2>
|
||||
inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
return resolve_variant::within
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply(geometry1, geometry2, default_strategy());
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief \brief_check12{is completely inside} \brief_strategy
|
||||
\ingroup within
|
||||
\details \details_check12{within, is completely inside}, \brief_strategy. \details_strategy_reasons
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry which might be within the second geometry
|
||||
\param geometry2 \param_geometry which might contain the first geometry
|
||||
\param strategy strategy to be used
|
||||
\return true if geometry1 is completely contained within geometry2,
|
||||
else false
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{[include reference/algorithms/within.qbk]}
|
||||
\qbk{
|
||||
[heading Available Strategies]
|
||||
\* [link geometry.reference.strategies.strategy_within_winding Winding (coordinate system agnostic)]
|
||||
\* [link geometry.reference.strategies.strategy_within_franklin Franklin (cartesian)]
|
||||
\* [link geometry.reference.strategies.strategy_within_crossings_multiply Crossings Multiply (cartesian)]
|
||||
|
||||
[heading Example]
|
||||
[within_strategy]
|
||||
[within_strategy_output]
|
||||
|
||||
}
|
||||
*/
|
||||
template<typename Geometry1, typename Geometry2, typename Strategy>
|
||||
inline bool within(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return resolve_variant::within
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_INTERFACE_HPP
|
@ -16,8 +16,25 @@
|
||||
#include <vector>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/disjoint/box_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/point_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/expand_by_epsilon.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/less.hpp>
|
||||
#include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/envelope.hpp>
|
||||
#include <boost/geometry/algorithms/detail/partition.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tag_cast.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/box.hpp>
|
||||
|
||||
#include <boost/geometry/index/rtree.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/covered_by.hpp>
|
||||
#include <boost/geometry/strategies/disjoint.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry {
|
||||
@ -27,9 +44,10 @@ namespace detail { namespace within {
|
||||
|
||||
struct multi_point_point
|
||||
{
|
||||
template <typename MultiPoint, typename Point, typename Strategy> static inline
|
||||
bool apply(MultiPoint const& multi_point, Point const& point,
|
||||
Strategy const& strategy)
|
||||
template <typename MultiPoint, typename Point, typename Strategy>
|
||||
static inline bool apply(MultiPoint const& multi_point,
|
||||
Point const& point,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename boost::range_const_iterator<MultiPoint>::type iterator;
|
||||
for ( iterator it = boost::begin(multi_point) ; it != boost::end(multi_point) ; ++it )
|
||||
@ -48,9 +66,10 @@ struct multi_point_point
|
||||
// NOTE: currently the strategy is ignored, math::equals() is used inside relate::less
|
||||
struct multi_point_multi_point
|
||||
{
|
||||
template <typename MultiPoint1, typename MultiPoint2, typename Strategy> static inline
|
||||
bool apply(MultiPoint1 const& multi_point1, MultiPoint2 const& multi_point2,
|
||||
Strategy const& /*strategy*/)
|
||||
template <typename MultiPoint1, typename MultiPoint2, typename Strategy>
|
||||
static inline bool apply(MultiPoint1 const& multi_point1,
|
||||
MultiPoint2 const& multi_point2,
|
||||
Strategy const& /*strategy*/)
|
||||
{
|
||||
typedef typename boost::range_value<MultiPoint2>::type point2_type;
|
||||
|
||||
@ -59,6 +78,8 @@ struct multi_point_multi_point
|
||||
std::vector<point2_type> points2(boost::begin(multi_point2), boost::end(multi_point2));
|
||||
std::sort(points2.begin(), points2.end(), less);
|
||||
|
||||
bool result = false;
|
||||
|
||||
typedef typename boost::range_const_iterator<MultiPoint1>::type iterator;
|
||||
for ( iterator it = boost::begin(multi_point1) ; it != boost::end(multi_point1) ; ++it )
|
||||
{
|
||||
@ -66,17 +87,182 @@ struct multi_point_multi_point
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
// all points of MultiPoint1 inside MultiPoint2
|
||||
return true;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// TODO: the complexity could be lesser
|
||||
// the second geometry could be "prepared"/sorted
|
||||
// For Linear geometries partition could be used
|
||||
// For Areal geometries point_in_geometry() would have to call the winding
|
||||
// strategy differently, currently it linearly calls the strategy for each
|
||||
// segment. So the segments would have to be sorted in a way consistent with
|
||||
// the strategy and then the strategy called only for the segments in range.
|
||||
template <bool Within>
|
||||
struct multi_point_single_geometry
|
||||
{
|
||||
template <typename MultiPoint, typename LinearOrAreal, typename Strategy>
|
||||
static inline bool apply(MultiPoint const& multi_point,
|
||||
LinearOrAreal const& linear_or_areal,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename boost::range_value<MultiPoint>::type point1_type;
|
||||
typedef typename point_type<LinearOrAreal>::type point2_type;
|
||||
typedef model::box<point2_type> box2_type;
|
||||
|
||||
// Create envelope of geometry
|
||||
box2_type box;
|
||||
geometry::envelope(linear_or_areal, box, strategy.get_envelope_strategy());
|
||||
geometry::detail::expand_by_epsilon(box);
|
||||
|
||||
typedef typename strategy::covered_by::services::default_strategy
|
||||
<
|
||||
point1_type, box2_type
|
||||
>::type point_in_box_type;
|
||||
|
||||
// Test each Point with envelope and then geometry if needed
|
||||
// If in the exterior, break
|
||||
bool result = false;
|
||||
|
||||
typedef typename boost::range_const_iterator<MultiPoint>::type iterator;
|
||||
for ( iterator it = boost::begin(multi_point) ; it != boost::end(multi_point) ; ++it )
|
||||
{
|
||||
int in_val = 0;
|
||||
|
||||
// exterior of box and of geometry
|
||||
if (! point_in_box_type::apply(*it, box)
|
||||
|| (in_val = point_in_geometry(*it, linear_or_areal, strategy)) < 0)
|
||||
{
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// interior : interior/boundary
|
||||
if (Within ? in_val > 0 : in_val >= 0)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// TODO: same here, probably the complexity could be lesser
|
||||
template <bool Within>
|
||||
struct multi_point_multi_geometry
|
||||
{
|
||||
template <typename MultiPoint, typename LinearOrAreal, typename Strategy>
|
||||
static inline bool apply(MultiPoint const& multi_point,
|
||||
LinearOrAreal const& linear_or_areal,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename point_type<LinearOrAreal>::type point2_type;
|
||||
typedef model::box<point2_type> box2_type;
|
||||
static const bool is_linear = is_same
|
||||
<
|
||||
typename tag_cast
|
||||
<
|
||||
typename tag<LinearOrAreal>::type,
|
||||
linear_tag
|
||||
>::type,
|
||||
linear_tag
|
||||
>::value;
|
||||
|
||||
typename Strategy::envelope_strategy_type const
|
||||
envelope_strategy = strategy.get_envelope_strategy();
|
||||
|
||||
// TODO: box pairs could be constructed on the fly, inside the rtree
|
||||
|
||||
// Prepare range of envelopes and ids
|
||||
std::size_t count2 = boost::size(linear_or_areal);
|
||||
typedef std::pair<box2_type, std::size_t> box_pair_type;
|
||||
typedef std::vector<box_pair_type> box_pair_vector;
|
||||
box_pair_vector boxes(count2);
|
||||
for (std::size_t i = 0 ; i < count2 ; ++i)
|
||||
{
|
||||
geometry::envelope(linear_or_areal, boxes[i].first, envelope_strategy);
|
||||
geometry::detail::expand_by_epsilon(boxes[i].first);
|
||||
boxes[i].second = i;
|
||||
}
|
||||
|
||||
// Create R-tree
|
||||
index::rtree<box_pair_type, index::rstar<4> > rtree(boxes.begin(), boxes.end());
|
||||
|
||||
// For each point find overlapping envelopes and test corresponding single geometries
|
||||
// If a point is in the exterior break
|
||||
bool result = false;
|
||||
|
||||
typedef typename boost::range_const_iterator<MultiPoint>::type iterator;
|
||||
for ( iterator it = boost::begin(multi_point) ; it != boost::end(multi_point) ; ++it )
|
||||
{
|
||||
// TODO: investigate the possibility of using satisfies
|
||||
// TODO: investigate the possibility of using iterative queries (optimization below)
|
||||
box_pair_vector inters_boxes;
|
||||
rtree.query(index::intersects(*it), std::back_inserter(inters_boxes));
|
||||
|
||||
bool found_interior = false;
|
||||
bool found_boundary = false;
|
||||
int boundaries = 0;
|
||||
|
||||
typedef typename box_pair_vector::const_iterator iterator;
|
||||
for ( iterator box_it = inters_boxes.begin() ; box_it != inters_boxes.end() ; ++box_it )
|
||||
{
|
||||
int in_val = point_in_geometry(*it, range::at(linear_or_areal, box_it->second), strategy);
|
||||
|
||||
if (in_val > 0)
|
||||
found_interior = true;
|
||||
else if (in_val == 0)
|
||||
++boundaries;
|
||||
|
||||
// If the result was set previously (interior or
|
||||
// interior/boundary found) the only thing that needs to be
|
||||
// done for other points is to make sure they're not
|
||||
// overlapping the exterior no need to analyse boundaries.
|
||||
if (result && in_val >= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( boundaries > 0)
|
||||
{
|
||||
if (is_linear && boundaries % 2 == 0)
|
||||
found_interior = true;
|
||||
else
|
||||
found_boundary = true;
|
||||
}
|
||||
|
||||
// exterior
|
||||
if (! found_interior && ! found_boundary)
|
||||
{
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// interior : interior/boundary
|
||||
if (Within ? found_interior : (found_interior || found_boundary))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::within
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_MULTI_POINT_HPP
|
||||
|
@ -22,644 +22,8 @@
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_EQUALS_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/type_traits/is_base_of.hpp>
|
||||
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/geometry_id.hpp>
|
||||
#include <boost/geometry/core/reverse_dispatch.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
// For trivial checks
|
||||
#include <boost/geometry/algorithms/area.hpp>
|
||||
#include <boost/geometry/algorithms/length.hpp>
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
#include <boost/geometry/util/select_coordinate_type.hpp>
|
||||
#include <boost/geometry/util/select_most_precise.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/equals/collect_vectors.hpp>
|
||||
#include <boost/geometry/algorithms/relate.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
|
||||
|
||||
#include <boost/geometry/views/detail/indexed_point_view.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace equals
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
std::size_t Dimension,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct point_point
|
||||
{
|
||||
template <typename Point1, typename Point2, typename Strategy>
|
||||
static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& strategy)
|
||||
{
|
||||
return ! detail::disjoint::point_point
|
||||
<
|
||||
Point1, Point2,
|
||||
Dimension, DimensionCount
|
||||
>::apply(point1, point2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
std::size_t Dimension,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct box_box
|
||||
{
|
||||
template <typename Box1, typename Box2, typename Strategy>
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
|
||||
{
|
||||
if (!geometry::math::equals(get<min_corner, Dimension>(box1), get<min_corner, Dimension>(box2))
|
||||
|| !geometry::math::equals(get<max_corner, Dimension>(box1), get<max_corner, Dimension>(box2)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return box_box<Dimension + 1, DimensionCount>::apply(box1, box2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t DimensionCount>
|
||||
struct box_box<DimensionCount, DimensionCount>
|
||||
{
|
||||
template <typename Box1, typename Box2, typename Strategy>
|
||||
static inline bool apply(Box1 const& , Box2 const& , Strategy const& )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct segment_segment
|
||||
{
|
||||
template <typename Segment1, typename Segment2, typename Strategy>
|
||||
static inline bool apply(Segment1 const& segment1, Segment2 const& segment2, Strategy const& )
|
||||
{
|
||||
return equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 0>(segment1),
|
||||
indexed_point_view<Segment2 const, 0>(segment2) )
|
||||
? equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 1>(segment1),
|
||||
indexed_point_view<Segment2 const, 1>(segment2) )
|
||||
: ( equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 0>(segment1),
|
||||
indexed_point_view<Segment2 const, 1>(segment2) )
|
||||
&& equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 1>(segment1),
|
||||
indexed_point_view<Segment2 const, 0>(segment2) )
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct area_check
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return geometry::math::equals(
|
||||
geometry::area(geometry1,
|
||||
strategy.template get_area_strategy<Geometry1>()),
|
||||
geometry::area(geometry2,
|
||||
strategy.template get_area_strategy<Geometry2>()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct length_check
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return geometry::math::equals(
|
||||
geometry::length(geometry1,
|
||||
strategy.template get_distance_strategy<Geometry1>()),
|
||||
geometry::length(geometry2,
|
||||
strategy.template get_distance_strategy<Geometry2>()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename IntersectionStrategy>
|
||||
struct collected_vector
|
||||
{
|
||||
typedef typename geometry::select_most_precise
|
||||
<
|
||||
typename select_coordinate_type
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::type,
|
||||
double
|
||||
>::type calculation_type;
|
||||
|
||||
typedef geometry::collected_vector
|
||||
<
|
||||
calculation_type,
|
||||
Geometry1,
|
||||
typename IntersectionStrategy::side_strategy_type
|
||||
> type;
|
||||
};
|
||||
|
||||
template <typename TrivialCheck>
|
||||
struct equals_by_collection
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
if (! TrivialCheck::apply(geometry1, geometry2, strategy))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef typename collected_vector
|
||||
<
|
||||
Geometry1, Geometry2, Strategy
|
||||
>::type collected_vector_type;
|
||||
|
||||
std::vector<collected_vector_type> c1, c2;
|
||||
|
||||
geometry::collect_vectors(c1, geometry1);
|
||||
geometry::collect_vectors(c2, geometry2);
|
||||
|
||||
if (boost::size(c1) != boost::size(c2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::sort(c1.begin(), c1.end());
|
||||
std::sort(c2.begin(), c2.end());
|
||||
|
||||
// Just check if these vectors are equal.
|
||||
return std::equal(c1.begin(), c1.end(), c2.begin());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Geometry1, typename Geometry2>
|
||||
struct equals_by_relate
|
||||
: detail::relate::relate_impl
|
||||
<
|
||||
detail::de9im::static_mask_equals_type,
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>
|
||||
{};
|
||||
|
||||
// If collect_vectors which is a SideStrategy-dispatched optimization
|
||||
// is implemented in a way consistent with the Intersection/Side Strategy
|
||||
// then collect_vectors is used, otherwise relate is used.
|
||||
// NOTE: the result could be coneptually different for invalid
|
||||
// geometries in different coordinate systems because collect_vectors
|
||||
// and relate treat invalid geometries differently.
|
||||
template<typename TrivialCheck>
|
||||
struct equals_by_collection_or_relate
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename boost::is_base_of
|
||||
<
|
||||
nyi::not_implemented_tag,
|
||||
typename collected_vector
|
||||
<
|
||||
Geometry1, Geometry2, Strategy
|
||||
>::type
|
||||
>::type enable_relate_type;
|
||||
|
||||
return apply(geometry1, geometry2, strategy, enable_relate_type());
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy,
|
||||
boost::false_type /*enable_relate*/)
|
||||
{
|
||||
return equals_by_collection<TrivialCheck>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy,
|
||||
boost::true_type /*enable_relate*/)
|
||||
{
|
||||
return equals_by_relate<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::equals
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Tag1 = typename tag<Geometry1>::type,
|
||||
typename Tag2 = typename tag<Geometry2>::type,
|
||||
std::size_t DimensionCount = dimension<Geometry1>::type::value,
|
||||
bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
|
||||
>
|
||||
struct equals: not_implemented<Tag1, Tag2>
|
||||
{};
|
||||
|
||||
|
||||
// If reversal is needed, perform it
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Tag1, typename Tag2,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct equals<Geometry1, Geometry2, Tag1, Tag2, DimensionCount, true>
|
||||
: equals<Geometry2, Geometry1, Tag2, Tag1, DimensionCount, false>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
|
||||
{
|
||||
return equals
|
||||
<
|
||||
Geometry2, Geometry1,
|
||||
Tag2, Tag1,
|
||||
DimensionCount,
|
||||
false
|
||||
>::apply(g2, g1, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename P1, typename P2, std::size_t DimensionCount, bool Reverse>
|
||||
struct equals<P1, P2, point_tag, point_tag, DimensionCount, Reverse>
|
||||
: detail::equals::point_point<0, DimensionCount>
|
||||
{};
|
||||
|
||||
template <typename MultiPoint1, typename MultiPoint2, std::size_t DimensionCount, bool Reverse>
|
||||
struct equals<MultiPoint1, MultiPoint2, multi_point_tag, multi_point_tag, DimensionCount, Reverse>
|
||||
: detail::equals::equals_by_relate<MultiPoint1, MultiPoint2>
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename Point, std::size_t DimensionCount, bool Reverse>
|
||||
struct equals<Point, MultiPoint, point_tag, multi_point_tag, DimensionCount, Reverse>
|
||||
: detail::equals::equals_by_relate<Point, MultiPoint>
|
||||
{};
|
||||
|
||||
template <typename Box1, typename Box2, std::size_t DimensionCount, bool Reverse>
|
||||
struct equals<Box1, Box2, box_tag, box_tag, DimensionCount, Reverse>
|
||||
: detail::equals::box_box<0, DimensionCount>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Ring1, typename Ring2, bool Reverse>
|
||||
struct equals<Ring1, Ring2, ring_tag, ring_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon1, typename Polygon2, bool Reverse>
|
||||
struct equals<Polygon1, Polygon2, polygon_tag, polygon_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename Ring, bool Reverse>
|
||||
struct equals<Polygon, Ring, polygon_tag, ring_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Ring, typename Box, bool Reverse>
|
||||
struct equals<Ring, Box, ring_tag, box_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename Box, bool Reverse>
|
||||
struct equals<Polygon, Box, polygon_tag, box_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
template <typename Segment1, typename Segment2, std::size_t DimensionCount, bool Reverse>
|
||||
struct equals<Segment1, Segment2, segment_tag, segment_tag, DimensionCount, Reverse>
|
||||
: detail::equals::segment_segment
|
||||
{};
|
||||
|
||||
template <typename LineString1, typename LineString2, bool Reverse>
|
||||
struct equals<LineString1, LineString2, linestring_tag, linestring_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_relate<LineString1, LineString2>
|
||||
{};
|
||||
|
||||
template <typename LineString, typename MultiLineString, bool Reverse>
|
||||
struct equals<LineString, MultiLineString, linestring_tag, multi_linestring_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_relate<LineString, MultiLineString>
|
||||
{};
|
||||
|
||||
template <typename MultiLineString1, typename MultiLineString2, bool Reverse>
|
||||
struct equals<MultiLineString1, MultiLineString2, multi_linestring_tag, multi_linestring_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_relate<MultiLineString1, MultiLineString2>
|
||||
{};
|
||||
|
||||
|
||||
template <typename MultiPolygon1, typename MultiPolygon2, bool Reverse>
|
||||
struct equals
|
||||
<
|
||||
MultiPolygon1, MultiPolygon2,
|
||||
multi_polygon_tag, multi_polygon_tag,
|
||||
2,
|
||||
Reverse
|
||||
>
|
||||
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename MultiPolygon, bool Reverse>
|
||||
struct equals
|
||||
<
|
||||
Polygon, MultiPolygon,
|
||||
polygon_tag, multi_polygon_tag,
|
||||
2,
|
||||
Reverse
|
||||
>
|
||||
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
template <typename MultiPolygon, typename Ring, bool Reverse>
|
||||
struct equals
|
||||
<
|
||||
MultiPolygon, Ring,
|
||||
multi_polygon_tag, ring_tag,
|
||||
2,
|
||||
Reverse
|
||||
>
|
||||
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
namespace resolve_strategy
|
||||
{
|
||||
|
||||
struct equals
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return dispatch::equals
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
default_strategy)
|
||||
{
|
||||
typedef typename strategy::relate::services::default_strategy
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
return dispatch::equals
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_strategy
|
||||
|
||||
|
||||
namespace resolve_variant {
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct equals
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concepts::check_concepts_and_equal_dimensions
|
||||
<
|
||||
Geometry1 const,
|
||||
Geometry2 const
|
||||
>();
|
||||
|
||||
return resolve_strategy::equals
|
||||
::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
|
||||
struct equals<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: static_visitor<bool>
|
||||
{
|
||||
Geometry2 const& m_geometry2;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry2 const& geometry2, Strategy const& strategy)
|
||||
: m_geometry2(geometry2)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry1>
|
||||
inline bool operator()(Geometry1 const& geometry1) const
|
||||
{
|
||||
return equals<Geometry1, Geometry2>
|
||||
::apply(geometry1, m_geometry2, m_strategy);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool apply(
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy
|
||||
)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct equals<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: static_visitor<bool>
|
||||
{
|
||||
Geometry1 const& m_geometry1;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry1 const& geometry1, Strategy const& strategy)
|
||||
: m_geometry1(geometry1)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry2>
|
||||
inline bool operator()(Geometry2 const& geometry2) const
|
||||
{
|
||||
return equals<Geometry1, Geometry2>
|
||||
::apply(m_geometry1, geometry2, m_strategy);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool apply(
|
||||
Geometry1 const& geometry1,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
|
||||
Strategy const& strategy
|
||||
)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
template <
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T1),
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T2)
|
||||
>
|
||||
struct equals<
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
|
||||
>
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: static_visitor<bool>
|
||||
{
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline bool operator()(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2) const
|
||||
{
|
||||
return equals<Geometry1, Geometry2>
|
||||
::apply(geometry1, geometry2, m_strategy);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool apply(
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
|
||||
Strategy const& strategy
|
||||
)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_variant
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check{are spatially equal}
|
||||
\details \details_check12{equals, is spatially equal}. Spatially equal means
|
||||
that the same point set is included. A box can therefore be spatially equal
|
||||
to a ring or a polygon, or a linestring can be spatially equal to a
|
||||
multi-linestring or a segment. This only works theoretically, not all
|
||||
combinations are implemented yet.
|
||||
\ingroup equals
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam Strategy \tparam_strategy{Equals}
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param strategy \param_strategy{equals}
|
||||
\return \return_check2{are spatially equal}
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{[include reference/algorithms/equals.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
inline bool equals(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return resolve_variant::equals
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check{are spatially equal}
|
||||
\details \details_check12{equals, is spatially equal}. Spatially equal means
|
||||
that the same point set is included. A box can therefore be spatially equal
|
||||
to a ring or a polygon, or a linestring can be spatially equal to a
|
||||
multi-linestring or a segment. This only works theoretically, not all
|
||||
combinations are implemented yet.
|
||||
\ingroup equals
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\return \return_check2{are spatially equal}
|
||||
|
||||
\qbk{[include reference/algorithms/equals.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline bool equals(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
return resolve_variant::equals<Geometry1, Geometry2>
|
||||
::apply(geometry1, geometry2, default_strategy());
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
#include <boost/geometry/algorithms/detail/equals/interface.hpp>
|
||||
#include <boost/geometry/algorithms/detail/equals/implementation.hpp>
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_EQUALS_HPP
|
||||
|
@ -21,120 +21,8 @@
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_INTERSECTS_HPP
|
||||
|
||||
|
||||
#include <deque>
|
||||
#include <boost/geometry/algorithms/detail/intersects/interface.hpp>
|
||||
#include <boost/geometry/algorithms/detail/intersects/implementation.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
|
||||
#include <boost/geometry/algorithms/disjoint.hpp>
|
||||
|
||||
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
|
||||
#include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/relate.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
/*!
|
||||
\brief \brief_check{has at least one intersection (crossing or self-tangency)}
|
||||
\note This function can be called for one geometry (self-intersection) and
|
||||
also for two geometries (intersection)
|
||||
\ingroup intersects
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry
|
||||
\return \return_check{is self-intersecting}
|
||||
|
||||
\qbk{distinguish,one geometry}
|
||||
\qbk{[def __one_parameter__]}
|
||||
\qbk{[include reference/algorithms/intersects.qbk]}
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline bool intersects(Geometry const& geometry)
|
||||
{
|
||||
concepts::check<Geometry const>();
|
||||
|
||||
typedef typename geometry::point_type<Geometry>::type point_type;
|
||||
typedef typename strategy::relate::services::default_strategy
|
||||
<
|
||||
Geometry, Geometry
|
||||
>::type strategy_type;
|
||||
typedef detail::no_rescale_policy rescale_policy_type;
|
||||
|
||||
typedef detail::overlay::turn_info
|
||||
<
|
||||
point_type,
|
||||
typename segment_ratio_type<point_type, rescale_policy_type>::type
|
||||
> turn_info;
|
||||
|
||||
std::deque<turn_info> turns;
|
||||
|
||||
typedef detail::overlay::get_turn_info
|
||||
<
|
||||
detail::overlay::assign_null_policy
|
||||
> turn_policy;
|
||||
|
||||
strategy_type strategy;
|
||||
rescale_policy_type robust_policy;
|
||||
|
||||
detail::disjoint::disjoint_interrupt_policy policy;
|
||||
detail::self_get_turn_points::get_turns
|
||||
<
|
||||
turn_policy
|
||||
>::apply(geometry, strategy, robust_policy, turns, policy, 0);
|
||||
return policy.has_intersections;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check2{have at least one intersection}
|
||||
\ingroup intersects
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam Strategy \tparam_strategy{Intersects}
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param strategy \param_strategy{intersects}
|
||||
\return \return_check2{intersect each other}
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{[include reference/algorithms/intersects.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
inline bool intersects(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
|
||||
return ! geometry::disjoint(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check2{have at least one intersection}
|
||||
\ingroup intersects
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\return \return_check2{intersect each other}
|
||||
|
||||
\qbk{distinguish,two geometries}
|
||||
\qbk{[include reference/algorithms/intersects.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline bool intersects(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
|
||||
return ! geometry::disjoint(geometry1, geometry2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_INTERSECTS_HPP
|
||||
|
@ -20,214 +20,8 @@
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_OVERLAPS_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/geometry/algorithms/detail/overlaps/interface.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlaps/implementation.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/relate.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlaps
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
std::size_t Dimension,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct box_box_loop
|
||||
{
|
||||
template <typename Box1, typename Box2>
|
||||
static inline void apply(Box1 const& b1, Box2 const& b2,
|
||||
bool& overlaps, bool& one_in_two, bool& two_in_one)
|
||||
{
|
||||
assert_dimension_equal<Box1, Box2>();
|
||||
|
||||
typedef typename coordinate_type<Box1>::type coordinate_type1;
|
||||
typedef typename coordinate_type<Box2>::type coordinate_type2;
|
||||
|
||||
coordinate_type1 const& min1 = get<min_corner, Dimension>(b1);
|
||||
coordinate_type1 const& max1 = get<max_corner, Dimension>(b1);
|
||||
coordinate_type2 const& min2 = get<min_corner, Dimension>(b2);
|
||||
coordinate_type2 const& max2 = get<max_corner, Dimension>(b2);
|
||||
|
||||
// We might use the (not yet accepted) Boost.Interval
|
||||
// submission in the future
|
||||
|
||||
// If:
|
||||
// B1: |-------|
|
||||
// B2: |------|
|
||||
// in any dimension -> no overlap
|
||||
if (max1 <= min2 || min1 >= max2)
|
||||
{
|
||||
overlaps = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// If:
|
||||
// B1: |--------------------|
|
||||
// B2: |-------------|
|
||||
// in all dimensions -> within, then no overlap
|
||||
// B1: |--------------------|
|
||||
// B2: |-------------|
|
||||
// this is "within-touch" -> then no overlap. So use < and >
|
||||
if (min1 < min2 || max1 > max2)
|
||||
{
|
||||
one_in_two = false;
|
||||
}
|
||||
|
||||
// Same other way round
|
||||
if (min2 < min1 || max2 > max1)
|
||||
{
|
||||
two_in_one = false;
|
||||
}
|
||||
|
||||
box_box_loop
|
||||
<
|
||||
Dimension + 1,
|
||||
DimensionCount
|
||||
>::apply(b1, b2, overlaps, one_in_two, two_in_one);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct box_box_loop<DimensionCount, DimensionCount>
|
||||
{
|
||||
template <typename Box1, typename Box2>
|
||||
static inline void apply(Box1 const& , Box2 const&, bool&, bool&, bool&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct box_box
|
||||
{
|
||||
template <typename Box1, typename Box2, typename Strategy>
|
||||
static inline bool apply(Box1 const& b1, Box2 const& b2, Strategy const& /*strategy*/)
|
||||
{
|
||||
bool overlaps = true;
|
||||
bool within1 = true;
|
||||
bool within2 = true;
|
||||
box_box_loop
|
||||
<
|
||||
0,
|
||||
dimension<Box1>::type::value
|
||||
>::apply(b1, b2, overlaps, within1, within2);
|
||||
|
||||
/*
|
||||
\see http://docs.codehaus.org/display/GEOTDOC/02+Geometry+Relationships#02GeometryRelationships-Overlaps
|
||||
where is stated that "inside" is not an "overlap",
|
||||
this is true and is implemented as such.
|
||||
*/
|
||||
return overlaps && ! within1 && ! within2;
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::overlaps
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Tag1 = typename tag<Geometry1>::type,
|
||||
typename Tag2 = typename tag<Geometry2>::type
|
||||
>
|
||||
struct overlaps
|
||||
: detail::relate::relate_impl
|
||||
<
|
||||
detail::de9im::static_mask_overlaps_type,
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Box1, typename Box2>
|
||||
struct overlaps<Box1, Box2, box_tag, box_tag>
|
||||
: detail::overlaps::box_box
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check2{overlap}
|
||||
\ingroup overlaps
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam Strategy \tparam_strategy{Overlaps}
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param strategy \param_strategy{overlaps}
|
||||
\return \return_check2{overlap}
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{[include reference/algorithms/overlaps.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
inline bool overlaps(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
|
||||
return dispatch::overlaps
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief \brief_check2{overlap}
|
||||
\ingroup overlaps
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\return \return_check2{overlap}
|
||||
|
||||
\qbk{[include reference/algorithms/overlaps.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline bool overlaps(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
|
||||
typedef typename strategy::relate::services::default_strategy
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
return dispatch::overlaps
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply(geometry1, geometry2, strategy_type());
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_OVERLAPS_HPP
|
||||
|
@ -21,687 +21,8 @@
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_TOUCHES_HPP
|
||||
|
||||
|
||||
#include <deque>
|
||||
#include <boost/geometry/algorithms/detail/touches/interface.hpp>
|
||||
#include <boost/geometry/algorithms/detail/touches/implementation.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/detail/for_each_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
|
||||
#include <boost/geometry/algorithms/disjoint.hpp>
|
||||
#include <boost/geometry/algorithms/intersects.hpp>
|
||||
#include <boost/geometry/algorithms/num_geometries.hpp>
|
||||
#include <boost/geometry/algorithms/detail/sub_range.hpp>
|
||||
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/relate.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace touches
|
||||
{
|
||||
|
||||
// Box/Box
|
||||
|
||||
template
|
||||
<
|
||||
std::size_t Dimension,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct box_box_loop
|
||||
{
|
||||
template <typename Box1, typename Box2>
|
||||
static inline bool apply(Box1 const& b1, Box2 const& b2, bool & touch)
|
||||
{
|
||||
typedef typename coordinate_type<Box1>::type coordinate_type1;
|
||||
typedef typename coordinate_type<Box2>::type coordinate_type2;
|
||||
|
||||
coordinate_type1 const& min1 = get<min_corner, Dimension>(b1);
|
||||
coordinate_type1 const& max1 = get<max_corner, Dimension>(b1);
|
||||
coordinate_type2 const& min2 = get<min_corner, Dimension>(b2);
|
||||
coordinate_type2 const& max2 = get<max_corner, Dimension>(b2);
|
||||
|
||||
// TODO assert or exception?
|
||||
//BOOST_GEOMETRY_ASSERT(min1 <= max1 && min2 <= max2);
|
||||
|
||||
if (max1 < min2 || max2 < min1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (max1 == min2 || max2 == min1)
|
||||
{
|
||||
touch = true;
|
||||
}
|
||||
|
||||
return box_box_loop
|
||||
<
|
||||
Dimension + 1,
|
||||
DimensionCount
|
||||
>::apply(b1, b2, touch);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct box_box_loop<DimensionCount, DimensionCount>
|
||||
{
|
||||
template <typename Box1, typename Box2>
|
||||
static inline bool apply(Box1 const& , Box2 const&, bool &)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct box_box
|
||||
{
|
||||
template <typename Box1, typename Box2, typename Strategy>
|
||||
static inline bool apply(Box1 const& b1, Box2 const& b2, Strategy const& /*strategy*/)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_same
|
||||
<
|
||||
typename geometry::coordinate_system<Box1>::type,
|
||||
typename geometry::coordinate_system<Box2>::type
|
||||
>::value
|
||||
));
|
||||
assert_dimension_equal<Box1, Box2>();
|
||||
|
||||
bool touches = false;
|
||||
bool ok = box_box_loop
|
||||
<
|
||||
0,
|
||||
dimension<Box1>::type::value
|
||||
>::apply(b1, b2, touches);
|
||||
|
||||
return ok && touches;
|
||||
}
|
||||
};
|
||||
|
||||
// Areal/Areal
|
||||
|
||||
struct areal_interrupt_policy
|
||||
{
|
||||
static bool const enabled = true;
|
||||
bool found_touch;
|
||||
bool found_not_touch;
|
||||
|
||||
// dummy variable required by self_get_turn_points::get_turns
|
||||
static bool const has_intersections = false;
|
||||
|
||||
inline bool result()
|
||||
{
|
||||
return found_touch && !found_not_touch;
|
||||
}
|
||||
|
||||
inline areal_interrupt_policy()
|
||||
: found_touch(false), found_not_touch(false)
|
||||
{}
|
||||
|
||||
template <typename Range>
|
||||
inline bool apply(Range const& range)
|
||||
{
|
||||
// if already rejected (temp workaround?)
|
||||
if ( found_not_touch )
|
||||
return true;
|
||||
|
||||
typedef typename boost::range_iterator<Range const>::type iterator;
|
||||
for ( iterator it = boost::begin(range) ; it != boost::end(range) ; ++it )
|
||||
{
|
||||
if ( it->has(overlay::operation_intersection) )
|
||||
{
|
||||
found_not_touch = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch(it->method)
|
||||
{
|
||||
case overlay::method_crosses:
|
||||
found_not_touch = true;
|
||||
return true;
|
||||
case overlay::method_equal:
|
||||
// Segment spatially equal means: at the right side
|
||||
// the polygon internally overlaps. So return false.
|
||||
found_not_touch = true;
|
||||
return true;
|
||||
case overlay::method_touch:
|
||||
case overlay::method_touch_interior:
|
||||
case overlay::method_collinear:
|
||||
if ( ok_for_touch(*it) )
|
||||
{
|
||||
found_touch = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
found_not_touch = true;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case overlay::method_none :
|
||||
case overlay::method_disjoint :
|
||||
case overlay::method_error :
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Turn>
|
||||
inline bool ok_for_touch(Turn const& turn)
|
||||
{
|
||||
return turn.both(overlay::operation_union)
|
||||
|| turn.both(overlay::operation_blocked)
|
||||
|| turn.combination(overlay::operation_union, overlay::operation_blocked)
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Geometry, typename PointInRingStrategy>
|
||||
struct check_each_ring_for_within
|
||||
{
|
||||
bool has_within;
|
||||
Geometry const& m_geometry;
|
||||
PointInRingStrategy const& m_strategy;
|
||||
|
||||
inline check_each_ring_for_within(Geometry const& g, PointInRingStrategy const& strategy)
|
||||
: has_within(false)
|
||||
, m_geometry(g)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Range>
|
||||
inline void apply(Range const& range)
|
||||
{
|
||||
typename geometry::point_type<Range>::type p;
|
||||
geometry::point_on_border(p, range);
|
||||
if ( !has_within && geometry::within(p, m_geometry, m_strategy) )
|
||||
{
|
||||
has_within = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename FirstGeometry, typename SecondGeometry, typename IntersectionStrategy>
|
||||
inline bool rings_containing(FirstGeometry const& geometry1,
|
||||
SecondGeometry const& geometry2,
|
||||
IntersectionStrategy const& strategy)
|
||||
{
|
||||
// NOTE: This strategy could be defined inside IntersectionStrategy
|
||||
typedef typename IntersectionStrategy::template point_in_geometry_strategy
|
||||
<
|
||||
FirstGeometry, SecondGeometry
|
||||
>::type point_in_ring_strategy_type;
|
||||
|
||||
point_in_ring_strategy_type point_in_ring_strategy
|
||||
= strategy.template get_point_in_geometry_strategy<FirstGeometry, SecondGeometry>();
|
||||
|
||||
check_each_ring_for_within
|
||||
<
|
||||
FirstGeometry, point_in_ring_strategy_type
|
||||
> checker(geometry1, point_in_ring_strategy);
|
||||
geometry::detail::for_each_range(geometry2, checker);
|
||||
return checker.has_within;
|
||||
}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct areal_areal
|
||||
{
|
||||
template <typename IntersectionStrategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
IntersectionStrategy const& strategy)
|
||||
{
|
||||
typedef detail::no_rescale_policy rescale_policy_type;
|
||||
typedef typename geometry::point_type<Geometry1>::type point_type;
|
||||
typedef detail::overlay::turn_info
|
||||
<
|
||||
point_type,
|
||||
typename segment_ratio_type<point_type, rescale_policy_type>::type
|
||||
> turn_info;
|
||||
|
||||
std::deque<turn_info> turns;
|
||||
detail::touches::areal_interrupt_policy policy;
|
||||
rescale_policy_type robust_policy;
|
||||
boost::geometry::get_turns
|
||||
<
|
||||
detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
|
||||
detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
|
||||
detail::overlay::assign_null_policy
|
||||
>(geometry1, geometry2, strategy, robust_policy, turns, policy);
|
||||
|
||||
return policy.result()
|
||||
&& ! geometry::detail::touches::rings_containing(geometry1, geometry2, strategy)
|
||||
&& ! geometry::detail::touches::rings_containing(geometry2, geometry1, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
// P/*
|
||||
|
||||
struct use_point_in_geometry
|
||||
{
|
||||
template <typename Point, typename Geometry, typename Strategy>
|
||||
static inline bool apply(Point const& point, Geometry const& geometry, Strategy const& strategy)
|
||||
{
|
||||
return detail::within::point_in_geometry(point, geometry, strategy) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch {
|
||||
|
||||
// TODO: Since CastedTags are used is Reverse needed?
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Tag1 = typename tag<Geometry1>::type,
|
||||
typename Tag2 = typename tag<Geometry2>::type,
|
||||
typename CastedTag1 = typename tag_cast<Tag1, pointlike_tag, linear_tag, areal_tag>::type,
|
||||
typename CastedTag2 = typename tag_cast<Tag2, pointlike_tag, linear_tag, areal_tag>::type,
|
||||
bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
|
||||
>
|
||||
struct touches
|
||||
: not_implemented<Tag1, Tag2>
|
||||
{};
|
||||
|
||||
// If reversal is needed, perform it
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Tag1, typename Tag2,
|
||||
typename CastedTag1, typename CastedTag2
|
||||
>
|
||||
struct touches<Geometry1, Geometry2, Tag1, Tag2, CastedTag1, CastedTag2, true>
|
||||
: touches<Geometry2, Geometry1, Tag2, Tag1, CastedTag2, CastedTag1, false>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
|
||||
{
|
||||
return touches<Geometry2, Geometry1>::apply(g2, g1, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
// P/P
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Tag2>
|
||||
struct touches<Geometry1, Geometry2, point_tag, Tag2, pointlike_tag, pointlike_tag, false>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const& , Geometry2 const& , Strategy const&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Tag2>
|
||||
struct touches<Geometry1, Geometry2, multi_point_tag, Tag2, pointlike_tag, pointlike_tag, false>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const&, Geometry2 const&, Strategy const&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// P/*
|
||||
|
||||
template <typename Point, typename Geometry, typename Tag2, typename CastedTag2>
|
||||
struct touches<Point, Geometry, point_tag, Tag2, pointlike_tag, CastedTag2, false>
|
||||
: detail::touches::use_point_in_geometry
|
||||
{};
|
||||
|
||||
// TODO: support touches(MPt, Linear/Areal)
|
||||
|
||||
// Box/Box
|
||||
|
||||
template <typename Box1, typename Box2, typename CastedTag1, typename CastedTag2>
|
||||
struct touches<Box1, Box2, box_tag, box_tag, CastedTag1, CastedTag2, false>
|
||||
: detail::touches::box_box
|
||||
{};
|
||||
|
||||
template <typename Box1, typename Box2>
|
||||
struct touches<Box1, Box2, box_tag, box_tag, areal_tag, areal_tag, false>
|
||||
: detail::touches::box_box
|
||||
{};
|
||||
|
||||
// L/L
|
||||
|
||||
template <typename Linear1, typename Linear2, typename Tag1, typename Tag2>
|
||||
struct touches<Linear1, Linear2, Tag1, Tag2, linear_tag, linear_tag, false>
|
||||
: detail::relate::relate_impl
|
||||
<
|
||||
detail::de9im::static_mask_touches_type,
|
||||
Linear1,
|
||||
Linear2
|
||||
>
|
||||
{};
|
||||
|
||||
// L/A
|
||||
|
||||
template <typename Linear, typename Areal, typename Tag1, typename Tag2>
|
||||
struct touches<Linear, Areal, Tag1, Tag2, linear_tag, areal_tag, false>
|
||||
: detail::relate::relate_impl
|
||||
<
|
||||
detail::de9im::static_mask_touches_type,
|
||||
Linear,
|
||||
Areal
|
||||
>
|
||||
{};
|
||||
|
||||
// A/L
|
||||
template <typename Linear, typename Areal, typename Tag1, typename Tag2>
|
||||
struct touches<Areal, Linear, Tag1, Tag2, areal_tag, linear_tag, false>
|
||||
: detail::relate::relate_impl
|
||||
<
|
||||
detail::de9im::static_mask_touches_type,
|
||||
Areal,
|
||||
Linear
|
||||
>
|
||||
{};
|
||||
|
||||
// A/A
|
||||
|
||||
template <typename Areal1, typename Areal2, typename Tag1, typename Tag2>
|
||||
struct touches<Areal1, Areal2, Tag1, Tag2, areal_tag, areal_tag, false>
|
||||
: detail::relate::relate_impl
|
||||
<
|
||||
detail::de9im::static_mask_touches_type,
|
||||
Areal1,
|
||||
Areal2
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename Areal1, typename Areal2>
|
||||
struct touches<Areal1, Areal2, ring_tag, ring_tag, areal_tag, areal_tag, false>
|
||||
: detail::touches::areal_areal<Areal1, Areal2>
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
namespace resolve_strategy
|
||||
{
|
||||
|
||||
struct touches
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return dispatch::touches
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
default_strategy)
|
||||
{
|
||||
typedef typename strategy::relate::services::default_strategy
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
return dispatch::touches
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_strategy
|
||||
|
||||
|
||||
namespace resolve_variant {
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct touches
|
||||
{
|
||||
template <typename Strategy>
|
||||
static bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
|
||||
{
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
|
||||
return resolve_strategy::touches::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
|
||||
struct touches<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: boost::static_visitor<bool>
|
||||
{
|
||||
Geometry2 const& m_geometry2;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry2 const& geometry2, Strategy const& strategy)
|
||||
: m_geometry2(geometry2)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry1>
|
||||
bool operator()(Geometry1 const& geometry1) const
|
||||
{
|
||||
return touches<Geometry1, Geometry2>::apply(geometry1, m_geometry2, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct touches<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: boost::static_visitor<bool>
|
||||
{
|
||||
Geometry1 const& m_geometry1;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry1 const& geometry1, Strategy const& strategy)
|
||||
: m_geometry1(geometry1)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry2>
|
||||
bool operator()(Geometry2 const& geometry2) const
|
||||
{
|
||||
return touches<Geometry1, Geometry2>::apply(m_geometry1, geometry2, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T1),
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T2)>
|
||||
struct touches<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: boost::static_visitor<bool>
|
||||
{
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
bool operator()(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2) const
|
||||
{
|
||||
return touches<Geometry1, Geometry2>::apply(geometry1, geometry2, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct self_touches
|
||||
{
|
||||
static bool apply(Geometry const& geometry)
|
||||
{
|
||||
concepts::check<Geometry const>();
|
||||
|
||||
typedef typename strategy::relate::services::default_strategy
|
||||
<
|
||||
Geometry, Geometry
|
||||
>::type strategy_type;
|
||||
typedef detail::no_rescale_policy rescale_policy_type;
|
||||
typedef typename geometry::point_type<Geometry>::type point_type;
|
||||
typedef detail::overlay::turn_info
|
||||
<
|
||||
point_type,
|
||||
typename segment_ratio_type<point_type, rescale_policy_type>::type
|
||||
> turn_info;
|
||||
|
||||
typedef detail::overlay::get_turn_info
|
||||
<
|
||||
detail::overlay::assign_null_policy
|
||||
> policy_type;
|
||||
|
||||
std::deque<turn_info> turns;
|
||||
detail::touches::areal_interrupt_policy policy;
|
||||
strategy_type strategy;
|
||||
rescale_policy_type robust_policy;
|
||||
detail::self_get_turn_points::get_turns
|
||||
<
|
||||
policy_type
|
||||
>::apply(geometry, strategy, robust_policy, turns, policy, 0);
|
||||
|
||||
return policy.result();
|
||||
}
|
||||
};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct self_touches<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
{
|
||||
struct visitor: boost::static_visitor<bool>
|
||||
{
|
||||
template <typename Geometry>
|
||||
bool operator()(Geometry const& geometry) const
|
||||
{
|
||||
return self_touches<Geometry>::apply(geometry);
|
||||
}
|
||||
};
|
||||
|
||||
static inline bool
|
||||
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
|
||||
{
|
||||
return boost::apply_visitor(visitor(), geometry);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_variant
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check{has at least one touching point (self-tangency)}
|
||||
\note This function can be called for one geometry (self-tangency) and
|
||||
also for two geometries (touch)
|
||||
\ingroup touches
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry
|
||||
\return \return_check{is self-touching}
|
||||
|
||||
\qbk{distinguish,one geometry}
|
||||
\qbk{[def __one_parameter__]}
|
||||
\qbk{[include reference/algorithms/touches.qbk]}
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline bool touches(Geometry const& geometry)
|
||||
{
|
||||
return resolve_variant::self_touches<Geometry>::apply(geometry);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check2{have at least one touching point (tangent - non overlapping)}
|
||||
\ingroup touches
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\return \return_check2{touch each other}
|
||||
|
||||
\qbk{distinguish,two geometries}
|
||||
\qbk{[include reference/algorithms/touches.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline bool touches(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
return resolve_variant::touches
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, default_strategy());
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief \brief_check2{have at least one touching point (tangent - non overlapping)}
|
||||
\ingroup touches
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam Strategy \tparam_strategy{Touches}
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param strategy \param_strategy{touches}
|
||||
\return \return_check2{touch each other}
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{[include reference/algorithms/touches.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
inline bool touches(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return resolve_variant::touches
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_TOUCHES_HPP
|
||||
|
@ -20,515 +20,8 @@
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_WITHIN_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/geometry/algorithms/detail/within/interface.hpp>
|
||||
#include <boost/geometry/algorithms/detail/within/implementation.hpp>
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/make.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/point_order.hpp>
|
||||
#include <boost/geometry/core/ring_type.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/strategies/concepts/within_concept.hpp>
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/within.hpp>
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
#include <boost/geometry/util/order_as_direction.hpp>
|
||||
#include <boost/geometry/views/closeable_view.hpp>
|
||||
#include <boost/geometry/views/reversible_view.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/within/multi_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/relate.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/do_reverse.hpp>
|
||||
#include <deque>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace within {
|
||||
|
||||
struct use_point_in_geometry
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
|
||||
{
|
||||
return detail::within::point_in_geometry(geometry1, geometry2, strategy) == 1;
|
||||
}
|
||||
};
|
||||
|
||||
struct use_relate
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
|
||||
{
|
||||
typedef typename detail::de9im::static_mask_within_type
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::type within_mask;
|
||||
return geometry::relate(geometry1, geometry2, within_mask(), strategy);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::within
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Tag1 = typename tag<Geometry1>::type,
|
||||
typename Tag2 = typename tag<Geometry2>::type
|
||||
>
|
||||
struct within
|
||||
: not_implemented<Tag1, Tag2>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Point, typename Box>
|
||||
struct within<Point, Box, point_tag, box_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
|
||||
{
|
||||
boost::ignore_unused_variable_warning(strategy);
|
||||
return strategy.apply(point, box);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box1, typename Box2>
|
||||
struct within<Box1, Box2, box_tag, box_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
|
||||
{
|
||||
assert_dimension_equal<Box1, Box2>();
|
||||
boost::ignore_unused_variable_warning(strategy);
|
||||
return strategy.apply(box1, box2);
|
||||
}
|
||||
};
|
||||
|
||||
// P/P
|
||||
|
||||
template <typename Point1, typename Point2>
|
||||
struct within<Point1, Point2, point_tag, point_tag>
|
||||
: public detail::within::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename Point, typename MultiPoint>
|
||||
struct within<Point, MultiPoint, point_tag, multi_point_tag>
|
||||
: public detail::within::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename Point>
|
||||
struct within<MultiPoint, Point, multi_point_tag, point_tag>
|
||||
: public detail::within::multi_point_point
|
||||
{};
|
||||
|
||||
template <typename MultiPoint1, typename MultiPoint2>
|
||||
struct within<MultiPoint1, MultiPoint2, multi_point_tag, multi_point_tag>
|
||||
: public detail::within::multi_point_multi_point
|
||||
{};
|
||||
|
||||
// P/L
|
||||
|
||||
template <typename Point, typename Segment>
|
||||
struct within<Point, Segment, point_tag, segment_tag>
|
||||
: public detail::within::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename Point, typename Linestring>
|
||||
struct within<Point, Linestring, point_tag, linestring_tag>
|
||||
: public detail::within::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename Point, typename MultiLinestring>
|
||||
struct within<Point, MultiLinestring, point_tag, multi_linestring_tag>
|
||||
: public detail::within::use_point_in_geometry
|
||||
{};
|
||||
|
||||
// P/A
|
||||
|
||||
template <typename Point, typename Ring>
|
||||
struct within<Point, Ring, point_tag, ring_tag>
|
||||
: public detail::within::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename Point, typename Polygon>
|
||||
struct within<Point, Polygon, point_tag, polygon_tag>
|
||||
: public detail::within::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename Point, typename MultiPolygon>
|
||||
struct within<Point, MultiPolygon, point_tag, multi_polygon_tag>
|
||||
: public detail::within::use_point_in_geometry
|
||||
{};
|
||||
|
||||
// L/L
|
||||
|
||||
template <typename Linestring1, typename Linestring2>
|
||||
struct within<Linestring1, Linestring2, linestring_tag, linestring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename Linestring, typename MultiLinestring>
|
||||
struct within<Linestring, MultiLinestring, linestring_tag, multi_linestring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring, typename Linestring>
|
||||
struct within<MultiLinestring, Linestring, multi_linestring_tag, linestring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring1, typename MultiLinestring2>
|
||||
struct within<MultiLinestring1, MultiLinestring2, multi_linestring_tag, multi_linestring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
// L/A
|
||||
|
||||
template <typename Linestring, typename Ring>
|
||||
struct within<Linestring, Ring, linestring_tag, ring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring, typename Ring>
|
||||
struct within<MultiLinestring, Ring, multi_linestring_tag, ring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename Linestring, typename Polygon>
|
||||
struct within<Linestring, Polygon, linestring_tag, polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring, typename Polygon>
|
||||
struct within<MultiLinestring, Polygon, multi_linestring_tag, polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename Linestring, typename MultiPolygon>
|
||||
struct within<Linestring, MultiPolygon, linestring_tag, multi_polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring, typename MultiPolygon>
|
||||
struct within<MultiLinestring, MultiPolygon, multi_linestring_tag, multi_polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
// A/A
|
||||
|
||||
template <typename Ring1, typename Ring2>
|
||||
struct within<Ring1, Ring2, ring_tag, ring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename Ring, typename Polygon>
|
||||
struct within<Ring, Polygon, ring_tag, polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename Polygon, typename Ring>
|
||||
struct within<Polygon, Ring, polygon_tag, ring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename Polygon1, typename Polygon2>
|
||||
struct within<Polygon1, Polygon2, polygon_tag, polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename Ring, typename MultiPolygon>
|
||||
struct within<Ring, MultiPolygon, ring_tag, multi_polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiPolygon, typename Ring>
|
||||
struct within<MultiPolygon, Ring, multi_polygon_tag, ring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename Polygon, typename MultiPolygon>
|
||||
struct within<Polygon, MultiPolygon, polygon_tag, multi_polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiPolygon, typename Polygon>
|
||||
struct within<MultiPolygon, Polygon, multi_polygon_tag, polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiPolygon1, typename MultiPolygon2>
|
||||
struct within<MultiPolygon1, MultiPolygon2, multi_polygon_tag, multi_polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
namespace resolve_strategy
|
||||
{
|
||||
|
||||
struct within
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concepts::within::check
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
|
||||
Strategy
|
||||
>();
|
||||
|
||||
return dispatch::within<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
default_strategy)
|
||||
{
|
||||
typedef typename strategy::within::services::default_strategy
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
return apply(geometry1, geometry2, strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_strategy
|
||||
|
||||
|
||||
namespace resolve_variant
|
||||
{
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct within
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
assert_dimension_equal<Geometry1, Geometry2>();
|
||||
|
||||
return resolve_strategy::within::apply(geometry1,
|
||||
geometry2,
|
||||
strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
|
||||
struct within<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: boost::static_visitor<bool>
|
||||
{
|
||||
Geometry2 const& m_geometry2;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry2 const& geometry2, Strategy const& strategy)
|
||||
: m_geometry2(geometry2)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry1>
|
||||
bool operator()(Geometry1 const& geometry1) const
|
||||
{
|
||||
return within<Geometry1, Geometry2>::apply(geometry1,
|
||||
m_geometry2,
|
||||
m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool
|
||||
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(geometry2, strategy),
|
||||
geometry1);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct within<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: boost::static_visitor<bool>
|
||||
{
|
||||
Geometry1 const& m_geometry1;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry1 const& geometry1, Strategy const& strategy)
|
||||
: m_geometry1(geometry1)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry2>
|
||||
bool operator()(Geometry2 const& geometry2) const
|
||||
{
|
||||
return within<Geometry1, Geometry2>::apply(m_geometry1,
|
||||
geometry2,
|
||||
m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool
|
||||
apply(Geometry1 const& geometry1,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(geometry1, strategy),
|
||||
geometry2
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T1),
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T2)
|
||||
>
|
||||
struct within<
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
|
||||
>
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: boost::static_visitor<bool>
|
||||
{
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Strategy const& strategy): m_strategy(strategy) {}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
bool operator()(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2) const
|
||||
{
|
||||
return within<Geometry1, Geometry2>::apply(geometry1,
|
||||
geometry2,
|
||||
m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool
|
||||
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(strategy),
|
||||
geometry1,
|
||||
geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check12{is completely inside}
|
||||
\ingroup within
|
||||
\details \details_check12{within, is completely inside}.
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry which might be within the second geometry
|
||||
\param geometry2 \param_geometry which might contain the first geometry
|
||||
\return true if geometry1 is completely contained within geometry2,
|
||||
else false
|
||||
\note The default strategy is used for within detection
|
||||
|
||||
|
||||
\qbk{[include reference/algorithms/within.qbk]}
|
||||
|
||||
\qbk{
|
||||
[heading Example]
|
||||
[within]
|
||||
[within_output]
|
||||
}
|
||||
*/
|
||||
template<typename Geometry1, typename Geometry2>
|
||||
inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
return resolve_variant::within
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply(geometry1, geometry2, default_strategy());
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief \brief_check12{is completely inside} \brief_strategy
|
||||
\ingroup within
|
||||
\details \details_check12{within, is completely inside}, \brief_strategy. \details_strategy_reasons
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry which might be within the second geometry
|
||||
\param geometry2 \param_geometry which might contain the first geometry
|
||||
\param strategy strategy to be used
|
||||
\return true if geometry1 is completely contained within geometry2,
|
||||
else false
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{[include reference/algorithms/within.qbk]}
|
||||
\qbk{
|
||||
[heading Available Strategies]
|
||||
\* [link geometry.reference.strategies.strategy_within_winding Winding (coordinate system agnostic)]
|
||||
\* [link geometry.reference.strategies.strategy_within_franklin Franklin (cartesian)]
|
||||
\* [link geometry.reference.strategies.strategy_within_crossings_multiply Crossings Multiply (cartesian)]
|
||||
|
||||
[heading Example]
|
||||
[within_strategy]
|
||||
[within_strategy_output]
|
||||
|
||||
}
|
||||
*/
|
||||
template<typename Geometry1, typename Geometry2, typename Strategy>
|
||||
inline bool within(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return resolve_variant::within
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_WITHIN_HPP
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// boxes union/intersection area/volume
|
||||
//
|
||||
// Copyright (c) 2011-2016 Adam Wulkiewicz, Lodz, Poland.
|
||||
// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
|
||||
//
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -11,8 +11,9 @@
|
||||
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_INTERSECTION_CONTENT_HPP
|
||||
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_INTERSECTION_CONTENT_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/intersection.hpp>
|
||||
#include <boost/geometry/strategies/intersection_strategies.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/box_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/intersection_box_box.hpp>
|
||||
|
||||
#include <boost/geometry/index/detail/algorithms/content.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index { namespace detail {
|
||||
@ -23,11 +24,19 @@ namespace boost { namespace geometry { namespace index { namespace detail {
|
||||
template <typename Box>
|
||||
inline typename default_content_result<Box>::type intersection_content(Box const& box1, Box const& box2)
|
||||
{
|
||||
if ( geometry::intersects(box1, box2) )
|
||||
bool const intersects = ! geometry::detail::disjoint::box_box<Box, Box>::apply(box1, box2);
|
||||
|
||||
if ( intersects )
|
||||
{
|
||||
Box box_intersection;
|
||||
if ( geometry::intersection(box1, box2, box_intersection) )
|
||||
return detail::content(box_intersection);
|
||||
bool const ok = geometry::detail::intersection::intersection_box_box
|
||||
<
|
||||
0, geometry::dimension<Box>::value
|
||||
>::apply(box1, box2, 0, box_intersection, 0);
|
||||
if ( ok )
|
||||
{
|
||||
return index::detail::content(box_intersection);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// n-dimensional box-linestring intersection
|
||||
//
|
||||
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
|
||||
// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
|
||||
//
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -11,8 +11,12 @@
|
||||
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_PATH_INTERSECTION_HPP
|
||||
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_PATH_INTERSECTION_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/index/detail/algorithms/segment_intersection.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/default_length_result.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry { namespace index { namespace detail {
|
||||
|
||||
namespace dispatch {
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// R-tree removing visitor implementation
|
||||
//
|
||||
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
|
||||
//
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
#include <boost/geometry/index/detail/rtree/visitors/is_leaf.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/covered_by.hpp>
|
||||
#include <boost/geometry/algorithms/detail/covered_by/interface.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
#ifndef BOOST_GEOMETRY_INDEX_EQUAL_TO_HPP
|
||||
#define BOOST_GEOMETRY_INDEX_EQUAL_TO_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/equals.hpp>
|
||||
#include <boost/geometry/algorithms/detail/equals/interface.hpp>
|
||||
#include <boost/geometry/index/indexable.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index { namespace detail {
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Boost.Geometry Index
|
||||
//
|
||||
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
|
||||
//
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -10,6 +10,7 @@
|
||||
#define BOOST_GEOMETRY_INDEX_INDEXABLE_HPP
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
#include <boost/geometry/index/detail/is_indexable.hpp>
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
// R-tree implementation
|
||||
//
|
||||
// Copyright (c) 2008 Federico J. Fernandez.
|
||||
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
|
||||
//
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -21,20 +21,18 @@
|
||||
|
||||
// Boost.Geometry
|
||||
#include <boost/geometry/algorithms/detail/comparable_distance/interface.hpp>
|
||||
#include <boost/geometry/algorithms/detail/covered_by/interface.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/interface.hpp>
|
||||
#include <boost/geometry/algorithms/detail/equals/interface.hpp>
|
||||
#include <boost/geometry/algorithms/detail/intersects/interface.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlaps/interface.hpp>
|
||||
#include <boost/geometry/algorithms/detail/touches/interface.hpp>
|
||||
#include <boost/geometry/algorithms/detail/within/interface.hpp>
|
||||
#include <boost/geometry/algorithms/centroid.hpp>
|
||||
#include <boost/geometry/algorithms/covered_by.hpp>
|
||||
#include <boost/geometry/algorithms/disjoint.hpp>
|
||||
#include <boost/geometry/algorithms/equals.hpp>
|
||||
#include <boost/geometry/algorithms/intersects.hpp>
|
||||
#include <boost/geometry/algorithms/overlaps.hpp>
|
||||
#include <boost/geometry/algorithms/touches.hpp>
|
||||
#include <boost/geometry/algorithms/within.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/point.hpp>
|
||||
#include <boost/geometry/geometries/box.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/strategies.hpp>
|
||||
|
||||
// Boost.Geometry.Index
|
||||
#include <boost/geometry/index/detail/config_begin.hpp>
|
||||
|
||||
@ -145,7 +143,8 @@ compared left-to-right.
|
||||
\tparam Allocator The allocator used to allocate/deallocate memory,
|
||||
construct/destroy nodes and Values.
|
||||
*/
|
||||
template <
|
||||
template
|
||||
<
|
||||
typename Value,
|
||||
typename Parameters,
|
||||
typename IndexableGetter = index::indexable<Value>,
|
||||
@ -2222,9 +2221,6 @@ struct range_mutable_iterator
|
||||
|
||||
} // namespace boost
|
||||
|
||||
// TODO: don't include the implementation at the end of the file
|
||||
#include <boost/geometry/algorithms/detail/comparable_distance/implementation.hpp>
|
||||
|
||||
#include <boost/geometry/index/detail/config_end.hpp>
|
||||
|
||||
#endif // BOOST_GEOMETRY_INDEX_RTREE_HPP
|
||||
|
@ -473,28 +473,44 @@ private:
|
||||
namespace services
|
||||
{
|
||||
|
||||
template <typename Point, typename Geometry, typename AnyTag>
|
||||
struct default_strategy<Point, Geometry, point_tag, AnyTag, pointlike_tag, polygonal_tag, cartesian_tag, cartesian_tag>
|
||||
template <typename PointLike, typename Geometry, typename AnyTag1, typename AnyTag2>
|
||||
struct default_strategy<PointLike, Geometry, AnyTag1, AnyTag2, pointlike_tag, polygonal_tag, cartesian_tag, cartesian_tag>
|
||||
{
|
||||
typedef winding<Point, typename geometry::point_type<Geometry>::type> type;
|
||||
typedef winding
|
||||
<
|
||||
typename geometry::point_type<PointLike>::type,
|
||||
typename geometry::point_type<Geometry>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
template <typename Point, typename Geometry, typename AnyTag>
|
||||
struct default_strategy<Point, Geometry, point_tag, AnyTag, pointlike_tag, polygonal_tag, spherical_tag, spherical_tag>
|
||||
template <typename PointLike, typename Geometry, typename AnyTag1, typename AnyTag2>
|
||||
struct default_strategy<PointLike, Geometry, AnyTag1, AnyTag2, pointlike_tag, polygonal_tag, spherical_tag, spherical_tag>
|
||||
{
|
||||
typedef winding<Point, typename geometry::point_type<Geometry>::type> type;
|
||||
typedef winding
|
||||
<
|
||||
typename geometry::point_type<PointLike>::type,
|
||||
typename geometry::point_type<Geometry>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
template <typename Point, typename Geometry, typename AnyTag>
|
||||
struct default_strategy<Point, Geometry, point_tag, AnyTag, pointlike_tag, linear_tag, cartesian_tag, cartesian_tag>
|
||||
template <typename PointLike, typename Geometry, typename AnyTag1, typename AnyTag2>
|
||||
struct default_strategy<PointLike, Geometry, AnyTag1, AnyTag2, pointlike_tag, linear_tag, cartesian_tag, cartesian_tag>
|
||||
{
|
||||
typedef winding<Point, typename geometry::point_type<Geometry>::type> type;
|
||||
typedef winding
|
||||
<
|
||||
typename geometry::point_type<PointLike>::type,
|
||||
typename geometry::point_type<Geometry>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
template <typename Point, typename Geometry, typename AnyTag>
|
||||
struct default_strategy<Point, Geometry, point_tag, AnyTag, pointlike_tag, linear_tag, spherical_tag, spherical_tag>
|
||||
template <typename PointLike, typename Geometry, typename AnyTag1, typename AnyTag2>
|
||||
struct default_strategy<PointLike, Geometry, AnyTag1, AnyTag2, pointlike_tag, linear_tag, spherical_tag, spherical_tag>
|
||||
{
|
||||
typedef winding<Point, typename geometry::point_type<Geometry>::type> type;
|
||||
typedef winding
|
||||
<
|
||||
typename geometry::point_type<PointLike>::type,
|
||||
typename geometry::point_type<Geometry>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
} // namespace services
|
||||
@ -509,28 +525,44 @@ struct default_strategy<Point, Geometry, point_tag, AnyTag, pointlike_tag, linea
|
||||
namespace strategy { namespace covered_by { namespace services
|
||||
{
|
||||
|
||||
template <typename Point, typename Geometry, typename AnyTag>
|
||||
struct default_strategy<Point, Geometry, point_tag, AnyTag, pointlike_tag, polygonal_tag, cartesian_tag, cartesian_tag>
|
||||
template <typename PointLike, typename Geometry, typename AnyTag1, typename AnyTag2>
|
||||
struct default_strategy<PointLike, Geometry, AnyTag1, AnyTag2, pointlike_tag, polygonal_tag, cartesian_tag, cartesian_tag>
|
||||
{
|
||||
typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
|
||||
typedef within::winding
|
||||
<
|
||||
typename geometry::point_type<PointLike>::type,
|
||||
typename geometry::point_type<Geometry>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
template <typename Point, typename Geometry, typename AnyTag>
|
||||
struct default_strategy<Point, Geometry, point_tag, AnyTag, pointlike_tag, polygonal_tag, spherical_tag, spherical_tag>
|
||||
template <typename PointLike, typename Geometry, typename AnyTag1, typename AnyTag2>
|
||||
struct default_strategy<PointLike, Geometry, AnyTag1, AnyTag2, pointlike_tag, polygonal_tag, spherical_tag, spherical_tag>
|
||||
{
|
||||
typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
|
||||
typedef within::winding
|
||||
<
|
||||
typename geometry::point_type<PointLike>::type,
|
||||
typename geometry::point_type<Geometry>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
template <typename Point, typename Geometry, typename AnyTag>
|
||||
struct default_strategy<Point, Geometry, point_tag, AnyTag, pointlike_tag, linear_tag, cartesian_tag, cartesian_tag>
|
||||
template <typename PointLike, typename Geometry, typename AnyTag1, typename AnyTag2>
|
||||
struct default_strategy<PointLike, Geometry, AnyTag1, AnyTag2, pointlike_tag, linear_tag, cartesian_tag, cartesian_tag>
|
||||
{
|
||||
typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
|
||||
typedef within::winding
|
||||
<
|
||||
typename geometry::point_type<PointLike>::type,
|
||||
typename geometry::point_type<Geometry>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
template <typename Point, typename Geometry, typename AnyTag>
|
||||
struct default_strategy<Point, Geometry, point_tag, AnyTag, pointlike_tag, linear_tag, spherical_tag, spherical_tag>
|
||||
template <typename PointLike, typename Geometry, typename AnyTag1, typename AnyTag2>
|
||||
struct default_strategy<PointLike, Geometry, AnyTag1, AnyTag2, pointlike_tag, linear_tag, spherical_tag, spherical_tag>
|
||||
{
|
||||
typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
|
||||
typedef within::winding
|
||||
<
|
||||
typename geometry::point_type<PointLike>::type,
|
||||
typename geometry::point_type<Geometry>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
}}} // namespace strategy::covered_by::services
|
||||
|
@ -6,10 +6,11 @@
|
||||
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2014.
|
||||
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2014, 2017.
|
||||
// Modifications 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
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
@ -27,6 +28,7 @@
|
||||
#include <geometry_test_common.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/comparable_distance.hpp>
|
||||
#include <boost/geometry/algorithms/make.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/geometries.hpp>
|
||||
#include <boost/geometry/geometries/point_xy.hpp>
|
||||
|
@ -1,9 +1,10 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
|
||||
// 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
|
||||
@ -37,6 +38,8 @@
|
||||
#include <boost/geometry/algorithms/distance.hpp>
|
||||
#include <boost/geometry/algorithms/comparable_distance.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/strategies.hpp>
|
||||
|
||||
#include <from_wkt.hpp>
|
||||
#include <string_from_type.hpp>
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
|
||||
// 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
|
||||
@ -36,6 +37,8 @@
|
||||
#include <boost/geometry/algorithms/distance.hpp>
|
||||
#include <boost/geometry/algorithms/comparable_distance.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/strategies.hpp>
|
||||
|
||||
#include <from_wkt.hpp>
|
||||
#include <string_from_type.hpp>
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/intersection.hpp>
|
||||
#include <boost/geometry/algorithms/make.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
|
||||
|
@ -3,6 +3,10 @@
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2017.
|
||||
// Modifications copyright (c) 2017, Oracle and/or its affiliates.
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
@ -19,6 +23,7 @@
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_relative_order.hpp>
|
||||
#include <boost/geometry/algorithms/make.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/point_xy.hpp>
|
||||
|
||||
|
@ -68,6 +68,37 @@ void test_all()
|
||||
test_geometry<P, mls>("POINT(0 0)", "MULTILINESTRING((0 0,1 1,2 2),(0 0,0 1))", true);
|
||||
test_geometry<P, mls>("POINT(0 0)", "MULTILINESTRING((0 0,1 1,2 2),(0 0,0 1),(0 0,1 0))", true);
|
||||
|
||||
// multi_point/segment
|
||||
typedef bg::model::multi_point<P> mpt;
|
||||
test_geometry<mpt, seg>("MULTIPOINT(0 0, 1 1)", "LINESTRING(0 0, 2 2)", true);
|
||||
|
||||
// multi_point/linestring
|
||||
test_geometry<mpt, ls>("MULTIPOINT(0 0, 2 2)", "LINESTRING(0 0, 2 2)", true);
|
||||
test_geometry<mpt, ls>("MULTIPOINT(1 1, 3 3)", "LINESTRING(0 0, 2 2)", false);
|
||||
|
||||
// multi_point/multi_linestring
|
||||
test_geometry<mpt, mls>("MULTIPOINT(0 0, 1 1)", "MULTILINESTRING((0 0, 2 2),(2 2, 3 3))", true);
|
||||
test_geometry<mpt, mls>("MULTIPOINT(0 0, 2 2)", "MULTILINESTRING((0 0, 2 2),(2 2, 3 3))", true);
|
||||
test_geometry<mpt, mls>("MULTIPOINT(0 0, 3 3)", "MULTILINESTRING((0 0, 2 2),(2 2, 3 3))", true);
|
||||
test_geometry<mpt, mls>("MULTIPOINT(1 1, 4 4)", "MULTILINESTRING((0 0, 2 2),(2 2, 3 3))", false);
|
||||
|
||||
// point/A
|
||||
typedef bg::model::ring<P> ring;
|
||||
typedef bg::model::polygon<P> poly;
|
||||
typedef bg::model::multi_polygon<poly> mpoly;
|
||||
test_geometry<P, ring>("POINT(1 1)", "POLYGON((0 0,0 2,2 2,2 0,0 0))", true);
|
||||
test_geometry<P, poly>("POINT(1 1)", "POLYGON((0 0,0 2,2 2,2 0,0 0))", true);
|
||||
test_geometry<P, mpoly>("POINT(1 1)", "MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0)),((2 2,2 3,3 3,3 2,2 2)))", true);
|
||||
|
||||
// multi_point/A
|
||||
test_geometry<mpt, ring>("MULTIPOINT(0 0, 1 1)", "POLYGON((0 0,0 2,2 2,2 0,0 0))", true);
|
||||
test_geometry<mpt, poly>("MULTIPOINT(0 0, 2 2)", "POLYGON((0 0,0 2,2 2,2 0,0 0))", true);
|
||||
test_geometry<mpt, poly>("MULTIPOINT(1 1, 3 3)", "POLYGON((0 0,0 2,2 2,2 0,0 0))", false);
|
||||
test_geometry<mpt, mpoly>("MULTIPOINT(0 0, 1 1)", "MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0)),((2 2,2 3,3 3,3 2,2 2)))", true);
|
||||
test_geometry<mpt, mpoly>("MULTIPOINT(0 0, 2 2)", "MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0)),((2 2,2 3,3 3,3 2,2 2)))", true);
|
||||
test_geometry<mpt, mpoly>("MULTIPOINT(0 0, 3 3)", "MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0)),((2 2,2 3,3 3,3 2,2 2)))", true);
|
||||
test_geometry<mpt, mpoly>("MULTIPOINT(1 1, 4 4)", "MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0)),((2 2,2 3,3 3,3 2,2 2)))", false);
|
||||
|
||||
typedef bg::model::box<P> box_type;
|
||||
|
||||
test_geometry<P, box_type>("POINT(1 1)", "BOX(0 0,2 2)", true);
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2014.
|
||||
// Modifications copyright (c) 2014 Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2014, 2017.
|
||||
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -16,24 +16,31 @@
|
||||
template <typename P>
|
||||
void test_pl()
|
||||
{
|
||||
/*typedef bg::model::multi_point<P> mpt;
|
||||
typedef bg::model::multi_point<P> mpt;
|
||||
typedef bg::model::linestring<P> ls;
|
||||
typedef bg::model::multi_linestring<ls> mls;
|
||||
|
||||
// not implemented yet
|
||||
test_geometry<mpt, ls>("MULTIPOINT(0 0,1 1)", "LINESTRING(0 0,1 0,3 3)", true);
|
||||
test_geometry<mpt, ls>("MULTIPOINT(0 0,1 1)", "LINESTRING(0 0,1 1,3 3)", false);*/
|
||||
test_geometry<mpt, ls>("MULTIPOINT(1 0,1 1)", "LINESTRING(0 0,1 0,3 3)", true);
|
||||
test_geometry<mpt, ls>("MULTIPOINT(0 0,1 1)", "LINESTRING(0 0,1 0,3 3)", false);
|
||||
test_geometry<mpt, ls>("MULTIPOINT(0 0,1 1)", "LINESTRING(0 0,1 1,3 3)", false);
|
||||
|
||||
test_geometry<mpt, mls>("MULTIPOINT(0 0,3 0)", "MULTILINESTRING((0 0,0 1,1 1),(1 1,1 0,0 0))", true);
|
||||
test_geometry<mpt, mls>("MULTIPOINT(0 0,1 1)", "MULTILINESTRING((0 0,0 1,1 1),(1 1,1 0,0 0))", false);
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
void test_pa()
|
||||
{
|
||||
/*typedef bg::model::multi_point<P> mpt;
|
||||
typedef bg::model::multi_point<P> mpt;
|
||||
typedef bg::model::polygon<P> poly;
|
||||
typedef bg::model::multi_polygon<poly> mpoly;
|
||||
|
||||
// not implemented yet
|
||||
test_geometry<mpt, poly>("MULTIPOINT(0 0,6 6)", "POLYGON((0 0,0 5,5 5,5 0,0 0))", true);
|
||||
test_geometry<mpt, poly>("MULTIPOINT(0 0,1 1)", "POLYGON((0 0,0 5,5 5,5 0,0 0))", false);*/
|
||||
test_geometry<mpt, poly>("MULTIPOINT(1 1,6 6)", "POLYGON((0 0,0 5,5 5,5 0,0 0))", true);
|
||||
test_geometry<mpt, poly>("MULTIPOINT(0 0,6 6)", "POLYGON((0 0,0 5,5 5,5 0,0 0))", false);
|
||||
test_geometry<mpt, poly>("MULTIPOINT(0 0,1 1)", "POLYGON((0 0,0 5,5 5,5 0,0 0))", false);
|
||||
|
||||
test_geometry<mpt, mpoly>("MULTIPOINT(0 0,1 1)", "MULTIPOLYGON(((0 0,0 5,5 5,5 0,0 0)),((5 5,5 9,9 9,9 5,5 5)))", false);
|
||||
test_geometry<mpt, mpoly>("MULTIPOINT(1 1,1 6)", "MULTIPOLYGON(((0 0,0 5,5 5,5 0,0 0)),((5 5,5 9,9 9,9 5,5 5)))", true);
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
|
@ -1,12 +1,13 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
|
||||
// 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
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
#ifndef BOOST_TEST_MODULE
|
||||
#define BOOST_TEST_MODULE test_disjoint_coverage
|
||||
@ -211,22 +212,22 @@ inline void test_multipoint_polygon()
|
||||
|
||||
tester::apply("mp-pg-01",
|
||||
from_wkt<MP>("MULTIPOINT(0 0,1 0)"),
|
||||
from_wkt<PL>("POLYGON(((0 0,1 0,0 1)))"),
|
||||
from_wkt<PL>("POLYGON((0 0,1 0,0 1))"),
|
||||
false);
|
||||
|
||||
tester::apply("mp-pg-02",
|
||||
from_wkt<MP>("MULTIPOINT(0 0,2 0)"),
|
||||
from_wkt<PL>("POLYGON(((0 0,1 0,0 1)))"),
|
||||
from_wkt<PL>("POLYGON((0 0,1 0,0 1))"),
|
||||
false);
|
||||
|
||||
tester::apply("mp-pg-03",
|
||||
from_wkt<MP>("MULTIPOINT(1 1,2 0)"),
|
||||
from_wkt<PL>("POLYGON(((0 0,1 0,0 1)))"),
|
||||
from_wkt<PL>("POLYGON((0 0,1 0,0 1))"),
|
||||
true);
|
||||
|
||||
tester::apply("mp-pg-04",
|
||||
from_wkt<MP>("MULTIPOINT(1 1,2 3)"),
|
||||
from_wkt<PL>("POLYGON(((0 0,1 0,0 1)))"),
|
||||
from_wkt<PL>("POLYGON((0 0,1 0,0 1))"),
|
||||
true);
|
||||
}
|
||||
|
||||
@ -241,22 +242,22 @@ inline void test_multipoint_multipolygon()
|
||||
|
||||
tester::apply("mp-mp-01",
|
||||
from_wkt<MP>("MULTIPOINT(0 0,2 0)"),
|
||||
from_wkt<MPL>("MULTIPOLYGON((0 0,1 0,0 1)),(2 0,3 0,2 1))"),
|
||||
from_wkt<MPL>("MULTIPOLYGON(((0 0,1 0,0 1)),((2 0,3 0,2 1)))"),
|
||||
false);
|
||||
|
||||
tester::apply("mp-mp-02",
|
||||
from_wkt<MP>("MULTIPOINT(0 0,1 0)"),
|
||||
from_wkt<MPL>("MULTIPOLYGON((0 0,1 0,0 1)),(2 0,3 0,2 1))"),
|
||||
from_wkt<MPL>("MULTIPOLYGON(((0 0,1 0,0 1)),((2 0,3 0,2 1)))"),
|
||||
false);
|
||||
|
||||
tester::apply("mp-mp-03",
|
||||
from_wkt<MP>("MULTIPOINT(1 1,2 0)"),
|
||||
from_wkt<MPL>("MULTIPOLYGON((0 0,1 0,0 1)),(2 0,3 0,2 1))"),
|
||||
from_wkt<MPL>("MULTIPOLYGON(((0 0,1 0,0 1)),((2 0,3 0,2 1)))"),
|
||||
false);
|
||||
|
||||
tester::apply("mp-mp-04",
|
||||
from_wkt<MP>("MULTIPOINT(1 1,2 3)"),
|
||||
from_wkt<MPL>("MULTIPOLYGON((0 0,1 0,0 1)),(2 0,3 0,2 1))"),
|
||||
from_wkt<MPL>("MULTIPOLYGON(((0 0,1 0,0 1)),((2 0,3 0,2 1)))"),
|
||||
true);
|
||||
}
|
||||
|
||||
@ -272,10 +273,10 @@ inline void test_pointlike_areal()
|
||||
test_point_ring<point_type>();
|
||||
test_point_box<point_type>();
|
||||
|
||||
// not implemented yet
|
||||
// test_multipoint_polygon<point_type>();
|
||||
// test_multipoint_multipolygon<point_type>();
|
||||
// test_multipoint_ring<point_type>();
|
||||
test_multipoint_polygon<point_type>();
|
||||
test_multipoint_multipolygon<point_type>();
|
||||
test_multipoint_ring<point_type>();
|
||||
|
||||
test_multipoint_box<point_type>();
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2013, 2014, 2015.
|
||||
// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013, 2014, 2015, 2017.
|
||||
// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -65,6 +65,9 @@ void test_point_linestring()
|
||||
{
|
||||
typedef bg::model::linestring<P> ls;
|
||||
|
||||
// degenerated
|
||||
//test_geometry<P, ls>("POINT(0 0)", "LINESTRING(0 0)", "0FFFFFFF2");
|
||||
|
||||
test_geometry<P, ls>("POINT(0 0)", "LINESTRING(0 0, 2 2, 3 2)", "F0FFFF102");
|
||||
test_geometry<P, ls>("POINT(1 1)", "LINESTRING(0 0, 2 2, 3 2)", "0FFFFF102");
|
||||
test_geometry<P, ls>("POINT(3 2)", "LINESTRING(0 0, 2 2, 3 2)", "F0FFFF102");
|
||||
@ -112,14 +115,127 @@ void test_point_multilinestring()
|
||||
}
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
void test_multipoint_linestring()
|
||||
{
|
||||
typedef bg::model::multi_point<P> mpt;
|
||||
typedef bg::model::linestring<P> ls;
|
||||
|
||||
// degenerated
|
||||
//test_geometry<mpt, ls>("MULTIPOINT(0 0)", "LINESTRING(0 0)", "0FFFFFFF2");
|
||||
|
||||
test_geometry<mpt, ls>("MULTIPOINT(0 0)", "LINESTRING(0 0, 2 2, 3 2)", "F0FFFF102");
|
||||
test_geometry<mpt, ls>("MULTIPOINT(0 0, 1 1)", "LINESTRING(0 0, 2 2, 3 2)", "00FFFF102");
|
||||
test_geometry<mpt, ls>("MULTIPOINT(0 0, 1 1, 3 3)", "LINESTRING(0 0, 2 2, 3 2)", "000FFF102");
|
||||
test_geometry<mpt, ls>("MULTIPOINT(0 0, 3 3)", "LINESTRING(0 0, 2 2, 3 2)", "F00FFF102");
|
||||
test_geometry<mpt, ls>("MULTIPOINT(1 1, 3 3)", "LINESTRING(0 0, 2 2, 3 2)", "0F0FFF102");
|
||||
|
||||
test_geometry<mpt, ls>("MULTIPOINT(0 0, 1 1)", "LINESTRING(0 0, 2 2, 3 2, 0 0)", "0FFFFF1F2");
|
||||
test_geometry<mpt, ls>("MULTIPOINT(0 0, 3 3)", "LINESTRING(0 0, 2 2, 3 2, 0 0)", "0F0FFF1F2");
|
||||
|
||||
test_geometry<mpt, ls>("MULTIPOINT(0 0)", "LINESTRING(0 0, 2 2)", "F0FFFF102");
|
||||
test_geometry<mpt, ls>("MULTIPOINT(2 2)", "LINESTRING(0 0, 2 2)", "F0FFFF102");
|
||||
test_geometry<mpt, ls>("MULTIPOINT(0 0, 2 2)", "LINESTRING(0 0, 2 2)", "F0FFFF1F2");
|
||||
test_geometry<mpt, ls>("MULTIPOINT(0 0, 1 1, 0 1, 2 2)", "LINESTRING(0 0, 2 2)", "000FFF1F2");
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
void test_multipoint_multilinestring()
|
||||
{
|
||||
typedef bg::model::multi_point<P> mpt;
|
||||
typedef bg::model::linestring<P> ls;
|
||||
typedef bg::model::multi_linestring<ls> mls;
|
||||
|
||||
test_geometry<mpt, mls>("MULTIPOINT(0 0)", "MULTILINESTRING((0 0, 2 2),(2 2, 3 2))", "F0FFFF102");
|
||||
test_geometry<mpt, mls>("MULTIPOINT(0 0, 1 1)", "MULTILINESTRING((0 0, 2 2),(2 2, 3 2))", "00FFFF102");
|
||||
test_geometry<mpt, mls>("MULTIPOINT(0 0, 1 1, 3 3)", "MULTILINESTRING((0 0, 2 2),(2 2, 3 2))", "000FFF102");
|
||||
test_geometry<mpt, mls>("MULTIPOINT(0 0, 3 3)", "MULTILINESTRING((0 0, 2 2),(2 2, 3 2))", "F00FFF102");
|
||||
test_geometry<mpt, mls>("MULTIPOINT(1 1, 3 3)", "MULTILINESTRING((0 0, 2 2),(2 2, 3 2))", "0F0FFF102");
|
||||
|
||||
test_geometry<mpt, mls>("MULTIPOINT(0 0, 1 1)", "MULTILINESTRING((0 0, 2 2),(2 2, 3 2, 0 0))", "0FFFFF1F2");
|
||||
test_geometry<mpt, mls>("MULTIPOINT(0 0, 3 3)", "MULTILINESTRING((0 0, 2 2),(2 2, 3 2, 0 0))", "0F0FFF1F2");
|
||||
|
||||
test_geometry<mpt, mls>("MULTIPOINT(0 0,1 1)", "MULTILINESTRING((0 0,0 1,1 1),(1 1,1 0,0 0))", "0FFFFF1F2");
|
||||
|
||||
test_geometry<mpt, mls>("MULTIPOINT(0 0)", "MULTILINESTRING((0 0,1 1),(1 1,2 2))", "F0FFFF102");
|
||||
test_geometry<mpt, mls>("MULTIPOINT(0 0, 1 1)", "MULTILINESTRING((0 0,1 1),(1 1,2 2))", "00FFFF102");
|
||||
test_geometry<mpt, mls>("MULTIPOINT(0 0, 1 1, 2 2)", "MULTILINESTRING((0 0,1 1),(1 1,2 2))", "00FFFF1F2");
|
||||
test_geometry<mpt, mls>("MULTIPOINT(0 0, 2 2)", "MULTILINESTRING((0 0,1 1),(1 1,2 2))", "F0FFFF1F2");
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
void test_point_ring_polygon()
|
||||
{
|
||||
typedef bg::model::ring<P> ring;
|
||||
typedef bg::model::polygon<P> poly;
|
||||
|
||||
test_geometry<P, ring>("POINT(0 0)", "POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))", "F0FFFF212");
|
||||
|
||||
test_geometry<P, poly>("POINT(1 1)", "POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))", "0FFFFF212");
|
||||
test_geometry<P, poly>("POINT(1 3)", "POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))", "FF0FFF212");
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
void test_point_multipolygon()
|
||||
{
|
||||
typedef bg::model::polygon<P> poly;
|
||||
typedef bg::model::multi_polygon<poly> mpoly;
|
||||
|
||||
test_geometry<P, mpoly>("POINT(0 0)", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0)),((5 5, 5 9, 9 9, 9 5, 5 5)))", "F0FFFF212");
|
||||
test_geometry<P, mpoly>("POINT(1 1)", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0)),((5 5, 5 9, 9 9, 9 5, 5 5)))", "0FFFFF212");
|
||||
test_geometry<P, mpoly>("POINT(5 5)", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0)),((5 5, 5 9, 9 9, 9 5, 5 5)))", "F0FFFF212");
|
||||
test_geometry<P, mpoly>("POINT(6 6)", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0)),((5 5, 5 9, 9 9, 9 5, 5 5)))", "0FFFFF212");
|
||||
test_geometry<P, mpoly>("POINT(1 6)", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0)),((5 5, 5 9, 9 9, 9 5, 5 5)))", "FF0FFF212");
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
void test_multipoint_ring_polygon()
|
||||
{
|
||||
typedef bg::model::multi_point<P> mpt;
|
||||
typedef bg::model::ring<P> ring;
|
||||
typedef bg::model::polygon<P> poly;
|
||||
|
||||
test_geometry<mpt, ring>("MULTIPOINT(0 0)", "POLYGON((0 0, 0 3, 3 3, 3 0, 0 0))", "F0FFFF212");
|
||||
test_geometry<mpt, ring>("MULTIPOINT(0 0, 1 1)", "POLYGON((0 0, 0 3, 3 3, 3 0, 0 0))", "00FFFF212");
|
||||
test_geometry<mpt, ring>("MULTIPOINT(0 0, 1 1, 4 4)", "POLYGON((0 0, 0 3, 3 3, 3 0, 0 0))", "000FFF212");
|
||||
test_geometry<mpt, ring>("MULTIPOINT(1 1, 4 4)", "POLYGON((0 0, 0 3, 3 3, 3 0, 0 0))", "0F0FFF212");
|
||||
|
||||
test_geometry<mpt, poly>("MULTIPOINT(2 2)", "POLYGON((0 0, 0 4, 4 4, 4 0, 0 0),(1 1, 3 1, 3 3, 1 3, 1 1))", "FF0FFF212");
|
||||
test_geometry<mpt, poly>("MULTIPOINT(0 0, 1 1)", "POLYGON((0 0, 0 4, 4 4, 4 0, 0 0),(1 1, 3 1, 3 3, 1 3, 1 1))", "F0FFFF212");
|
||||
test_geometry<mpt, poly>("MULTIPOINT(0 0, 1 1, 2 2)", "POLYGON((0 0, 0 4, 4 4, 4 0, 0 0),(1 1, 3 1, 3 3, 1 3, 1 1))", "F00FFF212");
|
||||
test_geometry<mpt, poly>("MULTIPOINT(2 2, 4 4)", "POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(1 1, 3 1, 3 3, 1 3, 1 1))", "0F0FFF212");
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
void test_multipoint_multipolygon()
|
||||
{
|
||||
typedef bg::model::multi_point<P> mpt;
|
||||
typedef bg::model::polygon<P> poly;
|
||||
typedef bg::model::multi_polygon<poly> mpoly;
|
||||
|
||||
test_geometry<mpt, mpoly>("MULTIPOINT(0 0)", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0)),((5 5, 5 9, 9 9, 9 5, 5 5)))", "F0FFFF212");
|
||||
test_geometry<mpt, mpoly>("MULTIPOINT(0 0, 1 1)", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0)),((5 5, 5 9, 9 9, 9 5, 5 5)))", "00FFFF212");
|
||||
test_geometry<mpt, mpoly>("MULTIPOINT(1 1, 5 5)", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0)),((5 5, 5 9, 9 9, 9 5, 5 5)))", "00FFFF212");
|
||||
test_geometry<mpt, mpoly>("MULTIPOINT(1 6, 6 6)", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0)),((5 5, 5 9, 9 9, 9 5, 5 5)))", "0F0FFF212");
|
||||
test_geometry<mpt, mpoly>("MULTIPOINT(0 0, 1 6)", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0)),((5 5, 5 9, 9 9, 9 5, 5 5)))", "F00FFF212");
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
void test_all()
|
||||
{
|
||||
test_point_point<P>();
|
||||
test_point_multipoint<P>();
|
||||
test_multipoint_multipoint<P>();
|
||||
|
||||
test_point_linestring<P>();
|
||||
test_point_multilinestring<P>();
|
||||
test_multipoint_linestring<P>();
|
||||
test_multipoint_multilinestring<P>();
|
||||
|
||||
test_point_ring_polygon<P>();
|
||||
test_point_multipolygon<P>();
|
||||
test_multipoint_ring_polygon<P>();
|
||||
test_multipoint_multipolygon<P>();
|
||||
}
|
||||
|
||||
int test_main( int , char* [] )
|
||||
|
@ -16,6 +16,7 @@
|
||||
template <typename P>
|
||||
void test_all()
|
||||
{
|
||||
typedef bg::model::multi_point<P> mpoint;
|
||||
typedef bg::model::ring<P> ring;
|
||||
typedef bg::model::polygon<P> polygon;
|
||||
typedef bg::model::linestring<P> linestring;
|
||||
@ -152,6 +153,10 @@ void test_all()
|
||||
test_touches<P, mlinestring>("POINT(0 0)", "MULTILINESTRING((0 0, 2 2, 10 2),(5 5, 6 6))", true);
|
||||
test_touches<P, mlinestring>("POINT(0 0)", "MULTILINESTRING((0 0, 2 2, 10 2),(0 0, 6 6))", false);
|
||||
|
||||
// MultiPoint-Polygon
|
||||
test_touches<mpoint, ring>("MULTIPOINT(40 50, 30 50)", "POLYGON((40 40,40 60,60 60,60 40,40 40))", true);
|
||||
test_touches<mpoint, polygon>("MULTIPOINT(40 50, 50 50)", "POLYGON((40 40,40 60,60 60,60 40,40 40))", false);
|
||||
|
||||
// Linestring-Linestring
|
||||
test_touches<linestring, linestring>("LINESTRING(0 0,2 0)", "LINESTRING(0 0,0 2)", true);
|
||||
test_touches<linestring, linestring>("LINESTRING(0 0,2 0)", "LINESTRING(2 0,2 2)", true);
|
||||
|
@ -45,6 +45,7 @@ void test_p_p()
|
||||
template <typename P>
|
||||
void test_p_l()
|
||||
{
|
||||
typedef bg::model::multi_point<P> mpt;
|
||||
typedef bg::model::segment<P> seg;
|
||||
typedef bg::model::linestring<P> ls;
|
||||
typedef bg::model::multi_linestring<ls> mls;
|
||||
@ -65,11 +66,23 @@ void test_p_l()
|
||||
|
||||
test_geometry<P, mls>("POINT(1 1)", "MULTILINESTRING((0 0, 1 1),(1 1, 2 2))", true);
|
||||
test_geometry<P, mls>("POINT(1 1)", "MULTILINESTRING((0 0, 1 1),(2 2, 3 3))", false);
|
||||
|
||||
test_geometry<mpt, seg>("MULTIPOINT(0 0, 1 1)", "LINESTRING(0 0, 2 2)", true);
|
||||
|
||||
test_geometry<mpt, ls>("MULTIPOINT(0 0, 2 2)", "LINESTRING(0 0, 2 2)", false);
|
||||
test_geometry<mpt, ls>("MULTIPOINT(1 1, 3 3)", "LINESTRING(0 0, 2 2)", false);
|
||||
|
||||
test_geometry<mpt, mls>("MULTIPOINT(0 0, 1 1)", "MULTILINESTRING((0 0, 2 2),(2 2, 3 3))", true);
|
||||
test_geometry<mpt, mls>("MULTIPOINT(0 0, 2 2)", "MULTILINESTRING((0 0, 2 2),(2 2, 3 3))", true);
|
||||
test_geometry<mpt, mls>("MULTIPOINT(0 0, 3 3)", "MULTILINESTRING((0 0, 2 2),(2 2, 3 3))", false);
|
||||
test_geometry<mpt, mls>("MULTIPOINT(1 1, 4 4)", "MULTILINESTRING((0 0, 2 2),(2 2, 3 3))", false);
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
void test_p_a()
|
||||
{
|
||||
typedef bg::model::multi_point<P> mpt;
|
||||
typedef bg::model::ring<P> ring;
|
||||
typedef bg::model::polygon<P> poly;
|
||||
typedef bg::model::multi_polygon<poly> mpoly;
|
||||
|
||||
@ -116,6 +129,16 @@ void test_p_a()
|
||||
"POLYGON((0 5, 5 0, 6 1, 5 2, 8 4, 5 6, 6 7, 5 8, 6 9, 5 10, 0 5))", true);
|
||||
test_geometry<P, poly>("POINT(4 6)",
|
||||
"POLYGON((5 0, 0 5, 1 6, 2 5, 4 8, 6 5, 7 6, 8 5, 9 6, 10 5, 5 0))", true);
|
||||
|
||||
test_geometry<mpt, ring>("MULTIPOINT(0 0, 1 1)", "POLYGON((0 0,0 2,2 2,2 0,0 0))", true);
|
||||
|
||||
test_geometry<mpt, poly>("MULTIPOINT(0 0, 2 2)", "POLYGON((0 0,0 2,2 2,2 0,0 0))", false);
|
||||
test_geometry<mpt, poly>("MULTIPOINT(1 1, 3 3)", "POLYGON((0 0,0 2,2 2,2 0,0 0))", false);
|
||||
|
||||
test_geometry<mpt, mpoly>("MULTIPOINT(0 0, 1 1)", "MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0)),((2 2,2 3,3 3,3 2,2 2)))", true);
|
||||
test_geometry<mpt, mpoly>("MULTIPOINT(0 0, 2 2)", "MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0)),((2 2,2 3,3 3,3 2,2 2)))", false);
|
||||
test_geometry<mpt, mpoly>("MULTIPOINT(0 0, 3 3)", "MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0)),((2 2,2 3,3 3,3 2,2 2)))", false);
|
||||
test_geometry<mpt, mpoly>("MULTIPOINT(1 1, 4 4)", "MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0)),((2 2,2 3,3 3,3 2,2 2)))", false);
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
|
Loading…
x
Reference in New Issue
Block a user