mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-11 13:34:10 +00:00
Merge pull request #129 from mkaravel/feature/disjoint-1.57
Feature/disjoint 1.57
This commit is contained in:
commit
f0c5554190
@ -26,6 +26,7 @@
|
||||
#include <boost/geometry/algorithms/detail/disjoint/linear_areal.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/linear_linear.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/point_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/point_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/box_box.hpp>
|
||||
|
@ -35,12 +35,15 @@
|
||||
|
||||
#include <boost/geometry/algorithms/covered_by.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
#include <boost/geometry/algorithms/detail/point_on_border.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/point_on_border.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/point_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/segment_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
|
||||
|
||||
@ -61,7 +64,9 @@ struct disjoint_linear_areal
|
||||
{
|
||||
// if there are intersections - return false
|
||||
if ( !disjoint_linear<Geometry1, Geometry2>::apply(g1, g2) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef typename point_type<Geometry1>::type point1_type;
|
||||
point1_type p;
|
||||
@ -88,38 +93,28 @@ template <typename Segment, typename Polygon>
|
||||
class disjoint_segment_areal<Segment, Polygon, polygon_tag>
|
||||
{
|
||||
private:
|
||||
template <typename RingIterator>
|
||||
static inline bool check_interior_rings(RingIterator first,
|
||||
RingIterator beyond,
|
||||
Segment const& segment)
|
||||
{
|
||||
for (RingIterator it = first; it != beyond; ++it)
|
||||
{
|
||||
if ( !disjoint_range_segment_or_box
|
||||
<
|
||||
typename std::iterator_traits
|
||||
<
|
||||
RingIterator
|
||||
>::value_type,
|
||||
closure<Polygon>::value,
|
||||
Segment
|
||||
>::apply(*it, segment) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template <typename InteriorRings>
|
||||
static inline
|
||||
bool check_interior_rings(InteriorRings const& interior_rings,
|
||||
Segment const& segment)
|
||||
{
|
||||
return check_interior_rings(boost::begin(interior_rings),
|
||||
boost::end(interior_rings),
|
||||
segment);
|
||||
typedef typename boost::range_value<InteriorRings>::type ring_type;
|
||||
|
||||
typedef unary_disjoint_geometry_to_query_geometry
|
||||
<
|
||||
Segment,
|
||||
disjoint_range_segment_or_box
|
||||
<
|
||||
ring_type, closure<ring_type>::value, Segment
|
||||
>
|
||||
> unary_predicate_type;
|
||||
|
||||
return check_iterator_range
|
||||
<
|
||||
unary_predicate_type
|
||||
>::apply(boost::begin(interior_rings),
|
||||
boost::end(interior_rings),
|
||||
unary_predicate_type(segment));
|
||||
}
|
||||
|
||||
|
||||
@ -155,7 +150,7 @@ struct disjoint_segment_areal<Segment, MultiPolygon, multi_polygon_tag>
|
||||
static inline
|
||||
bool apply(Segment const& segment, MultiPolygon const& multipolygon)
|
||||
{
|
||||
return disjoint_multirange_segment_or_box
|
||||
return multirange_constant_size_geometry
|
||||
<
|
||||
MultiPolygon, Segment
|
||||
>::apply(multipolygon, segment);
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
#include <boost/geometry/views/closeable_view.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
|
||||
|
||||
|
||||
@ -44,34 +45,6 @@ namespace detail { namespace disjoint
|
||||
{
|
||||
|
||||
|
||||
template <typename MultiRange, typename SegmentOrBox>
|
||||
struct disjoint_multirange_segment_or_box
|
||||
{
|
||||
static inline
|
||||
bool apply(MultiRange const& multirange, SegmentOrBox const& segment_or_box)
|
||||
{
|
||||
typedef typename boost::range_iterator
|
||||
<
|
||||
MultiRange const
|
||||
>::type const_iterator;
|
||||
|
||||
for (const_iterator it = boost::begin(multirange);
|
||||
it != boost::end(multirange); ++it)
|
||||
{
|
||||
if ( !dispatch::disjoint
|
||||
<
|
||||
typename boost::range_value<MultiRange>::type,
|
||||
SegmentOrBox
|
||||
>::apply(*it, segment_or_box) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Range,
|
||||
@ -160,7 +133,7 @@ template <typename MultiLinestring, typename SegmentOrBox>
|
||||
struct disjoint_linear_segment_or_box
|
||||
<
|
||||
MultiLinestring, SegmentOrBox, multi_linestring_tag
|
||||
> : disjoint_multirange_segment_or_box<MultiLinestring, SegmentOrBox>
|
||||
> : multirange_constant_size_geometry<MultiLinestring, SegmentOrBox>
|
||||
{};
|
||||
|
||||
|
||||
|
@ -0,0 +1,162 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_MULTIPOINT_GEOMETRY_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_MULTIPOINT_GEOMETRY_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.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>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace disjoint
|
||||
{
|
||||
|
||||
template<typename MultiPoint1, typename MultiPoint2>
|
||||
class multipoint_multipoint
|
||||
{
|
||||
private:
|
||||
template <typename Iterator>
|
||||
class unary_disjoint_predicate
|
||||
: detail::relate::less
|
||||
{
|
||||
private:
|
||||
typedef detail::relate::less base_type;
|
||||
|
||||
public:
|
||||
unary_disjoint_predicate(Iterator first, Iterator last)
|
||||
: base_type(), m_first(first), m_last(last)
|
||||
{}
|
||||
|
||||
template <typename Point>
|
||||
inline bool apply(Point const& point) const
|
||||
{
|
||||
return !std::binary_search(m_first,
|
||||
m_last,
|
||||
point,
|
||||
static_cast<base_type const&>(*this));
|
||||
}
|
||||
|
||||
private:
|
||||
Iterator m_first, m_last;
|
||||
};
|
||||
|
||||
public:
|
||||
static inline bool apply(MultiPoint1 const& multipoint1,
|
||||
MultiPoint2 const& multipoint2)
|
||||
{
|
||||
BOOST_ASSERT( boost::size(multipoint1) <= boost::size(multipoint2) );
|
||||
|
||||
typedef typename boost::range_value<MultiPoint1>::type point1_type;
|
||||
|
||||
std::vector<point1_type> points1(boost::begin(multipoint1),
|
||||
boost::end(multipoint1));
|
||||
|
||||
std::sort(points1.begin(), points1.end(), detail::relate::less());
|
||||
|
||||
typedef unary_disjoint_predicate
|
||||
<
|
||||
typename std::vector<point1_type>::const_iterator
|
||||
> predicate_type;
|
||||
|
||||
return check_iterator_range
|
||||
<
|
||||
predicate_type
|
||||
>::apply(boost::begin(multipoint2),
|
||||
boost::end(multipoint2),
|
||||
predicate_type(points1.begin(), points1.end()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::disjoint
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template<typename Point, typename MultiPoint, std::size_t DimensionCount>
|
||||
struct disjoint
|
||||
<
|
||||
Point, MultiPoint, DimensionCount, point_tag, multi_point_tag, false
|
||||
> : detail::disjoint::multirange_constant_size_geometry<MultiPoint, Point>
|
||||
{};
|
||||
|
||||
|
||||
template<typename MultiPoint, typename Segment, std::size_t DimensionCount>
|
||||
struct disjoint
|
||||
<
|
||||
MultiPoint, Segment, DimensionCount, multi_point_tag, segment_tag, false
|
||||
> : detail::disjoint::multirange_constant_size_geometry<MultiPoint, Segment>
|
||||
{};
|
||||
|
||||
|
||||
template<typename MultiPoint, typename Box, std::size_t DimensionCount>
|
||||
struct disjoint
|
||||
<
|
||||
MultiPoint, Box, DimensionCount, multi_point_tag, box_tag, false
|
||||
> : detail::disjoint::multirange_constant_size_geometry<MultiPoint, Box>
|
||||
{};
|
||||
|
||||
|
||||
template<typename MultiPoint1, typename MultiPoint2, std::size_t DimensionCount>
|
||||
struct disjoint
|
||||
<
|
||||
MultiPoint1, MultiPoint2, DimensionCount,
|
||||
multi_point_tag, multi_point_tag, false
|
||||
>
|
||||
{
|
||||
static inline bool apply(MultiPoint1 const& multipoint1,
|
||||
MultiPoint2 const& multipoint2)
|
||||
{
|
||||
if ( boost::size(multipoint2) < boost::size(multipoint1) )
|
||||
{
|
||||
return detail::disjoint::multipoint_multipoint
|
||||
<
|
||||
MultiPoint2, MultiPoint1
|
||||
>::apply(multipoint2, multipoint1);
|
||||
}
|
||||
|
||||
return detail::disjoint::multipoint_multipoint
|
||||
<
|
||||
MultiPoint1, MultiPoint2
|
||||
>::apply(multipoint1, multipoint2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_MULTIPOINT_GEOMETRY_HPP
|
@ -0,0 +1,85 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_MULTIRANGE_GEOMETRY_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_MULTIRANGE_GEOMETRY_HPP
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
|
||||
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace disjoint
|
||||
{
|
||||
|
||||
|
||||
template <typename Geometry, typename BinaryPredicate>
|
||||
class unary_disjoint_geometry_to_query_geometry
|
||||
{
|
||||
public:
|
||||
unary_disjoint_geometry_to_query_geometry(Geometry const& geometry)
|
||||
: m_geometry(geometry)
|
||||
{}
|
||||
|
||||
template <typename QueryGeometry>
|
||||
inline bool apply(QueryGeometry const& query_geometry) const
|
||||
{
|
||||
return BinaryPredicate::apply(query_geometry, m_geometry);
|
||||
}
|
||||
|
||||
private:
|
||||
Geometry const& m_geometry;
|
||||
};
|
||||
|
||||
|
||||
template<typename MultiRange, typename ConstantSizeGeometry>
|
||||
struct multirange_constant_size_geometry
|
||||
{
|
||||
static inline bool apply(MultiRange const& multirange,
|
||||
ConstantSizeGeometry const& constant_size_geometry)
|
||||
{
|
||||
typedef unary_disjoint_geometry_to_query_geometry
|
||||
<
|
||||
ConstantSizeGeometry,
|
||||
dispatch::disjoint
|
||||
<
|
||||
typename boost::range_value<MultiRange>::type,
|
||||
ConstantSizeGeometry
|
||||
>
|
||||
> unary_predicate_type;
|
||||
|
||||
return detail::check_iterator_range
|
||||
<
|
||||
unary_predicate_type
|
||||
>::apply(boost::begin(multirange), boost::end(multirange),
|
||||
unary_predicate_type(constant_size_geometry));
|
||||
}
|
||||
|
||||
static inline bool apply(ConstantSizeGeometry const& constant_size_geometry,
|
||||
MultiRange const& multirange)
|
||||
{
|
||||
return apply(multirange, constant_size_geometry);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::disjoint
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_MULTIRANGE_GEOMETRY_HPP
|
@ -151,6 +151,10 @@ inline void test_point_multipoint()
|
||||
tester::apply(from_wkt<P>("POINT(0 0)"),
|
||||
from_wkt<MP>("MULTIPOINT(1 1,2 2)"),
|
||||
true);
|
||||
|
||||
tester::apply(from_wkt<P>("POINT(0 0)"),
|
||||
from_wkt<MP>("MULTIPOINT()"),
|
||||
true);
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
@ -167,6 +171,14 @@ inline void test_multipoint_multipoint()
|
||||
tester::apply(from_wkt<MP>("MULTIPOINT(0 0,1 0)"),
|
||||
from_wkt<MP>("MULTIPOINT(1 1,2 2)"),
|
||||
true);
|
||||
|
||||
tester::apply(from_wkt<MP>("MULTIPOINT()"),
|
||||
from_wkt<MP>("MULTIPOINT(1 1,2 2)"),
|
||||
true);
|
||||
|
||||
tester::apply(from_wkt<MP>("MULTIPOINT(0 0,1 0)"),
|
||||
from_wkt<MP>("MULTIPOINT()"),
|
||||
true);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
@ -258,6 +270,10 @@ inline void test_multipoint_segment()
|
||||
tester::apply(from_wkt<MP>("MULTIPOINT(1 1,2 2)"),
|
||||
from_wkt<S>("SEGMENT(0 0,2 0)"),
|
||||
true);
|
||||
|
||||
tester::apply(from_wkt<MP>("MULTIPOINT()"),
|
||||
from_wkt<S>("SEGMENT(0 0,2 0)"),
|
||||
true);
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
@ -396,6 +412,10 @@ inline void test_multipoint_box()
|
||||
tester::apply(from_wkt<MP>("MULTIPOINT(3 3,4 4)"),
|
||||
from_wkt<B>("BOX(0 0,2 2)"),
|
||||
true);
|
||||
|
||||
tester::apply(from_wkt<MP>("MULTIPOINT()"),
|
||||
from_wkt<B>("BOX(0 0,2 2)"),
|
||||
true);
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
@ -1255,10 +1275,9 @@ inline void test_pointlike_pointlike()
|
||||
typedef bg::model::point<CoordinateType, 2, bg::cs::cartesian> point_type;
|
||||
|
||||
test_point_point<point_type>();
|
||||
// not implemented yet
|
||||
// test_point_multipoint<point_type>();
|
||||
test_point_multipoint<point_type>();
|
||||
|
||||
// test_multipoint_multipoint<point_type>();
|
||||
test_multipoint_multipoint<point_type>();
|
||||
}
|
||||
|
||||
template <typename CoordinateType>
|
||||
@ -1273,7 +1292,7 @@ inline void test_pointlike_linear()
|
||||
// not implemented yet
|
||||
// test_multipoint_linestring<point_type>();
|
||||
// test_multipoint_multilinestring<point_type>();
|
||||
// test_multipoint_segment<point_type>();
|
||||
test_multipoint_segment<point_type>();
|
||||
}
|
||||
|
||||
template <typename CoordinateType>
|
||||
@ -1290,7 +1309,7 @@ inline void test_pointlike_areal()
|
||||
// test_multipoint_polygon<point_type>();
|
||||
// test_multipoint_multipolygon<point_type>();
|
||||
// test_multipoint_ring<point_type>();
|
||||
// test_multipoint_box<point_type>();
|
||||
test_multipoint_box<point_type>();
|
||||
}
|
||||
|
||||
template <typename CoordinateType>
|
||||
|
Loading…
x
Reference in New Issue
Block a user