Merge pull request #129 from mkaravel/feature/disjoint-1.57

Feature/disjoint 1.57
This commit is contained in:
Adam Wulkiewicz 2014-11-04 22:25:35 +01:00
commit f0c5554190
6 changed files with 299 additions and 64 deletions

View File

@ -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>

View File

@ -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);

View File

@ -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>
{};

View File

@ -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

View File

@ -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

View File

@ -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>