1357 lines
34 KiB
C++
1357 lines
34 KiB
C++
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
|
// Unit Test
|
|
|
|
// Copyright (c) 2014, 2018 Oracle and/or its affiliates.
|
|
|
|
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
|
|
// 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_TEST_DISTANCE_BRUTE_FORCE_HPP
|
|
#define BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP
|
|
|
|
#include <iterator>
|
|
|
|
#include <boost/mpl/assert.hpp>
|
|
#include <boost/mpl/or.hpp>
|
|
#include <boost/range.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/iterators/segment_iterator.hpp>
|
|
|
|
#include <boost/geometry/algorithms/distance.hpp>
|
|
#include <boost/geometry/algorithms/intersects.hpp>
|
|
#include <boost/geometry/algorithms/not_implemented.hpp>
|
|
|
|
|
|
namespace boost { namespace geometry
|
|
{
|
|
|
|
namespace unit_test
|
|
{
|
|
|
|
namespace detail { namespace distance_brute_force
|
|
{
|
|
|
|
struct distance_from_bg
|
|
{
|
|
template <typename G>
|
|
struct use_distance_from_bg
|
|
{
|
|
typedef typename boost::mpl::or_
|
|
<
|
|
boost::is_same<typename tag<G>::type, point_tag>,
|
|
typename boost::mpl::or_
|
|
<
|
|
boost::is_same<typename tag<G>::type, segment_tag>,
|
|
boost::is_same<typename tag<G>::type, box_tag>
|
|
>::type
|
|
>::type type;
|
|
};
|
|
|
|
template <typename Geometry1, typename Geometry2, typename Strategy>
|
|
static inline
|
|
typename distance_result<Geometry1, Geometry2, Strategy>::type
|
|
apply(Geometry1 const& geometry1,
|
|
Geometry2 const& geometry2,
|
|
Strategy const& strategy)
|
|
{
|
|
BOOST_MPL_ASSERT((typename use_distance_from_bg<Geometry1>::type));
|
|
BOOST_MPL_ASSERT((typename use_distance_from_bg<Geometry2>::type));
|
|
|
|
return geometry::distance(geometry1, geometry2, strategy);
|
|
}
|
|
};
|
|
|
|
|
|
template <typename Geometry1, typename Geometry2, typename Strategy>
|
|
inline
|
|
typename distance_result<Geometry1, Geometry2, Strategy>::type
|
|
bg_distance(Geometry1 const& geometry1,
|
|
Geometry2 const& geometry2,
|
|
Strategy const& strategy)
|
|
{
|
|
return distance_from_bg::apply(geometry1, geometry2, strategy);
|
|
}
|
|
|
|
|
|
template <typename Policy>
|
|
struct one_to_many
|
|
{
|
|
template <typename Geometry, typename Iterator, typename Strategy>
|
|
static inline typename distance_result
|
|
<
|
|
Geometry,
|
|
typename std::iterator_traits<Iterator>::value_type,
|
|
Strategy
|
|
>::type
|
|
apply(Geometry const& geometry, Iterator begin, Iterator end,
|
|
Strategy const& strategy)
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Geometry,
|
|
typename std::iterator_traits<Iterator>::value_type,
|
|
Strategy
|
|
>::type distance_type;
|
|
|
|
bool first = true;
|
|
distance_type d_min(0);
|
|
for (Iterator it = begin; it != end; ++it, first = false)
|
|
{
|
|
distance_type d = Policy::apply(geometry, *it, strategy);
|
|
|
|
if ( first || d < d_min )
|
|
{
|
|
d_min = d;
|
|
}
|
|
}
|
|
return d_min;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
}} // namespace detail::distance_brute_force
|
|
|
|
|
|
namespace dispatch
|
|
{
|
|
|
|
template
|
|
<
|
|
typename Geometry1,
|
|
typename Geometry2,
|
|
typename Strategy,
|
|
typename Tag1 = typename tag_cast
|
|
<
|
|
typename tag<Geometry1>::type,
|
|
segment_tag,
|
|
linear_tag
|
|
>::type,
|
|
typename Tag2 = typename tag_cast
|
|
<
|
|
typename tag<Geometry2>::type,
|
|
segment_tag,
|
|
linear_tag
|
|
>::type,
|
|
bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
|
|
>
|
|
struct distance_brute_force
|
|
: not_implemented<Geometry1, Geometry2>
|
|
{};
|
|
|
|
template
|
|
<
|
|
typename Geometry1,
|
|
typename Geometry2,
|
|
typename Strategy,
|
|
typename Tag1,
|
|
typename Tag2
|
|
>
|
|
struct distance_brute_force<Geometry1, Geometry2, Strategy, Tag1, Tag2, true>
|
|
{
|
|
static inline typename distance_result<Geometry1, Geometry2, Strategy>::type
|
|
apply(Geometry1 const& geometry1,
|
|
Geometry2 const& geometry2,
|
|
Strategy const& strategy)
|
|
{
|
|
return distance_brute_force
|
|
<
|
|
Geometry2, Geometry1, Strategy
|
|
>::apply(geometry2, geometry1, strategy);
|
|
}
|
|
};
|
|
|
|
//===================================================================
|
|
|
|
template
|
|
<
|
|
typename Point1,
|
|
typename Point2,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Point1, Point2, Strategy,
|
|
point_tag, point_tag, false
|
|
> : detail::distance_brute_force::distance_from_bg
|
|
{};
|
|
|
|
|
|
template
|
|
<
|
|
typename Point,
|
|
typename Segment,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Point, Segment, Strategy,
|
|
point_tag, segment_tag, false
|
|
> : detail::distance_brute_force::distance_from_bg
|
|
{};
|
|
|
|
template
|
|
<
|
|
typename Point,
|
|
typename Linear,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Point, Linear, Strategy,
|
|
point_tag, linear_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Point, Linear, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Point const& point,
|
|
Linear const& linear,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
detail::distance_brute_force::distance_from_bg
|
|
>::apply(point,
|
|
geometry::segments_begin(linear),
|
|
geometry::segments_end(linear),
|
|
strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename Point,
|
|
typename Ring,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Point, Ring, Strategy,
|
|
point_tag, ring_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Point, Ring, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Point const& point,
|
|
Ring const& ring,
|
|
Strategy const& strategy)
|
|
{
|
|
|
|
if (geometry::covered_by(point, ring))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
Point,
|
|
typename std::iterator_traits
|
|
<
|
|
segment_iterator<Ring const>
|
|
>::value_type,
|
|
Strategy
|
|
>
|
|
>::apply(point,
|
|
geometry::segments_begin(ring),
|
|
geometry::segments_end(ring),
|
|
strategy);
|
|
}
|
|
};
|
|
|
|
//TODO do it more brute force (also in all polygon-geometry cases)
|
|
template
|
|
<
|
|
typename Point,
|
|
typename Polygon,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Point, Polygon, Strategy,
|
|
point_tag, polygon_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Point, Polygon, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Point const& point,
|
|
Polygon const& polygon,
|
|
Strategy const& strategy)
|
|
{
|
|
return geometry::distance(point, polygon, strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename Point,
|
|
typename Box,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Point, Box, Strategy,
|
|
point_tag, box_tag, false
|
|
> : detail::distance_brute_force::distance_from_bg
|
|
{};
|
|
|
|
template
|
|
<
|
|
typename Point,
|
|
typename MultiPoint,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Point, MultiPoint, Strategy,
|
|
point_tag, multi_point_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Point, MultiPoint, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Point const& p,
|
|
MultiPoint const& mp,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
detail::distance_brute_force::distance_from_bg
|
|
>::apply(p, boost::begin(mp), boost::end(mp), strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename Point,
|
|
typename MultiPolygon,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Point, MultiPolygon, Strategy,
|
|
point_tag, multi_polygon_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Point, MultiPolygon, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Point const& p,
|
|
MultiPolygon const& mp,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
Point,
|
|
typename boost::range_value<MultiPolygon>::type,
|
|
Strategy
|
|
>
|
|
>::apply(p, boost::begin(mp), boost::end(mp), strategy);
|
|
}
|
|
};
|
|
|
|
//=======================================================================
|
|
|
|
template
|
|
<
|
|
typename Linear,
|
|
typename Segment,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Linear, Segment, Strategy,
|
|
linear_tag, segment_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Linear, Segment, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Linear const& linear,
|
|
Segment const& segment,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
detail::distance_brute_force::distance_from_bg
|
|
>::apply(segment,
|
|
geometry::segments_begin(linear),
|
|
geometry::segments_end(linear),
|
|
strategy);
|
|
}
|
|
};
|
|
|
|
|
|
template
|
|
<
|
|
typename Linear1,
|
|
typename Linear2,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Linear1, Linear2, Strategy,
|
|
linear_tag, linear_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Linear1, Linear2, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Linear1 const& linear1,
|
|
Linear2 const& linear2,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
Linear1,
|
|
typename std::iterator_traits
|
|
<
|
|
segment_iterator<Linear2 const>
|
|
>::value_type,
|
|
Strategy
|
|
>
|
|
>::apply(linear1,
|
|
geometry::segments_begin(linear2),
|
|
geometry::segments_end(linear2),
|
|
strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename Linear,
|
|
typename Ring,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Linear, Ring, Strategy,
|
|
linear_tag, ring_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Linear, Ring, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Linear const& linear,
|
|
Ring const& ring,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
Linear,
|
|
typename std::iterator_traits
|
|
<
|
|
segment_iterator<Ring const>
|
|
>::value_type,
|
|
Strategy
|
|
>
|
|
>::apply(linear,
|
|
geometry::segments_begin(ring),
|
|
geometry::segments_end(ring),
|
|
strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename Linear,
|
|
typename Polygon,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Linear, Polygon, Strategy,
|
|
linear_tag, polygon_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Linear, Polygon, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Linear const& linear,
|
|
Polygon const& polygon,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
Polygon,
|
|
typename std::iterator_traits
|
|
<
|
|
segment_iterator<Linear const>
|
|
>::value_type,
|
|
Strategy
|
|
>
|
|
>::apply(polygon,
|
|
geometry::segments_begin(linear),
|
|
geometry::segments_end(linear),
|
|
strategy);
|
|
}
|
|
};
|
|
|
|
|
|
template
|
|
<
|
|
typename Linear,
|
|
typename Box,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Linear, Box, Strategy,
|
|
linear_tag, box_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Linear, Box, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Linear const& linear,
|
|
Box const& box,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
detail::distance_brute_force::distance_from_bg
|
|
>::apply(box,
|
|
geometry::segments_begin(linear),
|
|
geometry::segments_end(linear),
|
|
strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename Linear,
|
|
typename MultiPoint,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Linear, MultiPoint, Strategy,
|
|
linear_tag, multi_point_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Linear, MultiPoint, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Linear const& linear,
|
|
MultiPoint const& mp,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
Linear,
|
|
typename boost::range_value<MultiPoint>::type,
|
|
Strategy
|
|
>
|
|
>::apply(linear, boost::begin(mp), boost::end(mp), strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename Linear,
|
|
typename MultiPolygon,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Linear, MultiPolygon, Strategy,
|
|
linear_tag, multi_polygon_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Linear, MultiPolygon, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Linear const& linear,
|
|
MultiPolygon const& mp,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
Linear,
|
|
typename boost::range_value<MultiPolygon>::type,
|
|
Strategy
|
|
>
|
|
>::apply(linear, boost::begin(mp), boost::end(mp), strategy);
|
|
}
|
|
};
|
|
|
|
//=================================================================
|
|
|
|
template
|
|
<
|
|
typename Polygon,
|
|
typename Segment,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Polygon, Segment, Strategy,
|
|
polygon_tag, segment_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Polygon, Segment, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Polygon const& polygon,
|
|
Segment const& segment,
|
|
Strategy const& strategy)
|
|
{
|
|
return geometry::distance(segment, polygon, strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename Polygon,
|
|
typename Linear,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Polygon, Linear, Strategy,
|
|
polygon_tag, linear_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Polygon, Linear, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Polygon const& polygon,
|
|
Linear const& linear,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
Polygon,
|
|
typename std::iterator_traits
|
|
<
|
|
segment_iterator<Linear const>
|
|
>::value_type,
|
|
Strategy
|
|
>
|
|
>::apply(polygon,
|
|
geometry::segments_begin(linear),
|
|
geometry::segments_end(linear),
|
|
strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename Polygon1,
|
|
typename Polygon2,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Polygon1, Polygon2, Strategy,
|
|
polygon_tag, polygon_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Polygon1, Polygon2, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Polygon1 const& polygon1,
|
|
Polygon2 const& polygon2,
|
|
Strategy const& strategy)
|
|
{
|
|
return geometry::distance(polygon1, polygon2, strategy);
|
|
}
|
|
};
|
|
|
|
|
|
template
|
|
<
|
|
typename Polygon,
|
|
typename MultiPoint,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Polygon, MultiPoint, Strategy,
|
|
polygon_tag, multi_point_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Polygon, MultiPoint, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Polygon const& polygon,
|
|
MultiPoint const& mp,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
Polygon,
|
|
typename boost::range_value<MultiPoint>::type,
|
|
Strategy
|
|
>
|
|
>::apply(polygon, boost::begin(mp), boost::end(mp), strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename Polygon,
|
|
typename MultiPolygon,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Polygon, MultiPolygon, Strategy,
|
|
polygon_tag, multi_polygon_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Polygon, MultiPolygon, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Polygon const& poly,
|
|
MultiPolygon const& mp,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
Polygon,
|
|
typename boost::range_value<MultiPolygon>::type,
|
|
Strategy
|
|
>
|
|
>::apply(poly, boost::begin(mp), boost::end(mp), strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename Polygon,
|
|
typename Ring,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Polygon, Ring, Strategy,
|
|
polygon_tag, ring_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Polygon, Ring, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Polygon const& polygon,
|
|
Ring const& ring,
|
|
Strategy const& strategy)
|
|
{
|
|
return geometry::distance(ring, polygon, strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename Polygon,
|
|
typename Box,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Polygon, Box, Strategy,
|
|
polygon_tag, box_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Polygon, Box, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Polygon const& polygon,
|
|
Box const& box,
|
|
Strategy const& strategy)
|
|
{
|
|
return geometry::distance(box, polygon, strategy);
|
|
}
|
|
};
|
|
|
|
//========================================================================
|
|
|
|
template
|
|
<
|
|
typename MultiPoint1,
|
|
typename MultiPoint2,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
MultiPoint1, MultiPoint2, Strategy,
|
|
multi_point_tag, multi_point_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
MultiPoint1, MultiPoint2, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(MultiPoint1 const& mp1,
|
|
MultiPoint2 const& mp2,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
MultiPoint1,
|
|
typename boost::range_value<MultiPoint2>::type,
|
|
Strategy
|
|
>
|
|
>::apply(mp1, boost::begin(mp2), boost::end(mp2), strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename MultiPoint,
|
|
typename Linear,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
MultiPoint, Linear, Strategy,
|
|
multi_point_tag, linear_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
MultiPoint, Linear, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(MultiPoint const& mp,
|
|
Linear const& l,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
MultiPoint,
|
|
typename boost::range_value<Linear>::type,
|
|
Strategy
|
|
>
|
|
>::apply(mp, boost::begin(l), boost::end(l), strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename MultiPoint,
|
|
typename MultiPolygon,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
MultiPoint, MultiPolygon, Strategy,
|
|
multi_point_tag, multi_polygon_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
MultiPoint, MultiPolygon, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(MultiPoint const& mp,
|
|
MultiPolygon const& mpl,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
MultiPoint,
|
|
typename boost::range_value<MultiPolygon>::type,
|
|
Strategy
|
|
>
|
|
>::apply(mp, boost::begin(mpl), boost::end(mpl), strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename MultiPoint,
|
|
typename Segment,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
MultiPoint, Segment, Strategy,
|
|
multi_point_tag, segment_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
MultiPoint, Segment, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(MultiPoint const& mp,
|
|
Segment const& segment,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
detail::distance_brute_force::distance_from_bg
|
|
>::apply(segment, boost::begin(mp), boost::end(mp), strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename MultiPoint,
|
|
typename Ring,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
MultiPoint, Ring, Strategy,
|
|
multi_point_tag, ring_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
MultiPoint, Ring, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(MultiPoint const& mp,
|
|
Ring const& ring,
|
|
Strategy const& strategy)
|
|
{
|
|
|
|
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
MultiPoint,
|
|
typename std::iterator_traits
|
|
<
|
|
segment_iterator<Ring const>
|
|
>::value_type,
|
|
Strategy
|
|
>
|
|
>::apply(mp,
|
|
geometry::segments_begin(ring),
|
|
geometry::segments_end(ring),
|
|
strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename MultiPoint,
|
|
typename Box,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
MultiPoint, Box, Strategy,
|
|
multi_point_tag, box_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
MultiPoint, Box, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(MultiPoint const& mp,
|
|
Box const& box,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
Box,
|
|
typename boost::range_value<MultiPoint>::type,
|
|
Strategy
|
|
>
|
|
>::apply(box, boost::begin(mp), boost::end(mp), strategy);
|
|
}
|
|
};
|
|
|
|
//=====================================================================
|
|
|
|
template
|
|
<
|
|
typename MultiPolygon1,
|
|
typename MultiPolygon2,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
MultiPolygon1, MultiPolygon2, Strategy,
|
|
multi_polygon_tag, multi_polygon_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
MultiPolygon1, MultiPolygon2, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(MultiPolygon1 const& mp1,
|
|
MultiPolygon2 const& mp2,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
MultiPolygon1,
|
|
typename boost::range_value<MultiPolygon2>::type,
|
|
Strategy
|
|
>
|
|
>::apply(mp1, boost::begin(mp2), boost::end(mp2), strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename MultiPolygon,
|
|
typename Segment,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
MultiPolygon, Segment, Strategy,
|
|
multi_polygon_tag, segment_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
MultiPolygon, Segment, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(MultiPolygon const& mp,
|
|
Segment const& segment,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
Segment,
|
|
typename boost::range_value<MultiPolygon>::type,
|
|
Strategy
|
|
>
|
|
>::apply(segment, boost::begin(mp), boost::end(mp), strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename MultiPolygon,
|
|
typename Ring,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
MultiPolygon, Ring, Strategy,
|
|
multi_polygon_tag, ring_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
MultiPolygon, Ring, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(MultiPolygon const& mp,
|
|
Ring const& ring,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
Ring,
|
|
typename boost::range_value<MultiPolygon>::type,
|
|
Strategy
|
|
>
|
|
>::apply(ring, boost::begin(mp), boost::end(mp), strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename MultiPolygon,
|
|
typename Box,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
MultiPolygon, Box, Strategy,
|
|
multi_polygon_tag, box_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
MultiPolygon, Box, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(MultiPolygon const& mp,
|
|
Box const& box,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
Box,
|
|
typename boost::range_value<MultiPolygon>::type,
|
|
Strategy
|
|
>
|
|
>::apply(box, boost::begin(mp), boost::end(mp), strategy);
|
|
}
|
|
};
|
|
|
|
|
|
//========================================================================
|
|
|
|
template
|
|
<
|
|
typename Ring,
|
|
typename Box,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Ring, Box, Strategy,
|
|
ring_tag, box_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Ring, Box, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Ring const& ring,
|
|
Box const& box,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
Box,
|
|
typename std::iterator_traits
|
|
<
|
|
segment_iterator<Ring const>
|
|
>::value_type,
|
|
Strategy
|
|
>
|
|
>::apply(box,
|
|
geometry::segments_begin(ring),
|
|
geometry::segments_end(ring),
|
|
strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename Ring1,
|
|
typename Ring2,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Ring1, Ring2, Strategy,
|
|
ring_tag, ring_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Ring1, Ring2, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Ring1 const& ring1,
|
|
Ring2 const& ring2,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
Ring1,
|
|
typename std::iterator_traits
|
|
<
|
|
segment_iterator<Ring2 const>
|
|
>::value_type,
|
|
Strategy
|
|
>
|
|
>::apply(ring1,
|
|
geometry::segments_begin(ring2),
|
|
geometry::segments_end(ring2),
|
|
strategy);
|
|
}
|
|
};
|
|
|
|
//========================================================================
|
|
|
|
template
|
|
<
|
|
typename Segment1,
|
|
typename Segment2,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Segment1, Segment2, Strategy,
|
|
segment_tag, segment_tag, false
|
|
> : detail::distance_brute_force::distance_from_bg
|
|
{};
|
|
|
|
template
|
|
<
|
|
typename Segment,
|
|
typename Ring,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Segment, Ring, Strategy,
|
|
segment_tag, ring_tag, false
|
|
>
|
|
{
|
|
typedef typename distance_result
|
|
<
|
|
Segment, Ring, Strategy
|
|
>::type distance_type;
|
|
|
|
static inline distance_type apply(Segment const& segment,
|
|
Ring const& ring,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::distance_brute_force::one_to_many
|
|
<
|
|
distance_brute_force
|
|
<
|
|
Segment,
|
|
typename std::iterator_traits
|
|
<
|
|
segment_iterator<Ring const>
|
|
>::value_type,
|
|
Strategy
|
|
>
|
|
>::apply(segment,
|
|
geometry::segments_begin(ring),
|
|
geometry::segments_end(ring),
|
|
strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename Segment,
|
|
typename Box,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Segment, Box, Strategy,
|
|
segment_tag, box_tag, false
|
|
> : detail::distance_brute_force::distance_from_bg
|
|
{};
|
|
|
|
//====================================================================
|
|
|
|
template
|
|
<
|
|
typename Box1,
|
|
typename Box2,
|
|
typename Strategy
|
|
>
|
|
struct distance_brute_force
|
|
<
|
|
Box1, Box2, Strategy,
|
|
box_tag, box_tag, false
|
|
> : detail::distance_brute_force::distance_from_bg
|
|
{};
|
|
|
|
} // namespace dispatch
|
|
|
|
|
|
|
|
|
|
|
|
template <typename Geometry1, typename Geometry2, typename Strategy>
|
|
inline typename distance_result<Geometry1, Geometry2, Strategy>::type
|
|
distance_brute_force(Geometry1 const& geometry1,
|
|
Geometry2 const& geometry2,
|
|
Strategy const& strategy)
|
|
{
|
|
return dispatch::distance_brute_force
|
|
<
|
|
Geometry1, Geometry2, Strategy
|
|
>::apply(geometry1, geometry2, strategy);
|
|
}
|
|
|
|
} // namespace unit_test
|
|
|
|
|
|
}} // namespace boost::geometry
|
|
#endif // BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP
|