add boost on mac

This commit is contained in:
Bassem Girgis
2019-08-10 16:38:17 -05:00
parent 861b918727
commit be945cb63b
14105 changed files with 2714968 additions and 0 deletions

View File

@@ -0,0 +1,333 @@
// 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.
// 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.
// 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_DISTANCE_BACKWARD_COMPATIBILITY_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_BACKWARD_COMPATIBILITY_HPP
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/tags.hpp>
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/dispatch/distance.hpp>
#include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
#include <boost/geometry/algorithms/detail/distance/point_to_geometry.hpp>
#include <boost/geometry/algorithms/detail/distance/multipoint_to_geometry.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace distance
{
template<typename Point, typename Segment, typename Strategy>
struct point_to_segment
{
static inline typename strategy::distance::services::return_type
<
Strategy,
Point,
typename point_type<Segment>::type
>::type
apply(Point const& point, Segment const& segment, Strategy const& )
{
typename detail::distance::default_ps_strategy
<
Point,
typename point_type<Segment>::type,
Strategy
>::type segment_strategy;
typename point_type<Segment>::type p[2];
geometry::detail::assign_point_from_index<0>(segment, p[0]);
geometry::detail::assign_point_from_index<1>(segment, p[1]);
return segment_strategy.apply(point, p[0], p[1]);
}
};
}} // namespace detail::distance
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
// Point-segment version 1, with point-point strategy
template <typename Point, typename Segment, typename Strategy>
struct distance
<
Point, Segment, Strategy,
point_tag, segment_tag, strategy_tag_distance_point_point,
false
> : detail::distance::point_to_segment<Point, Segment, Strategy>
{};
// Point-line version 1, where point-point strategy is specified
template <typename Point, typename Linestring, typename Strategy>
struct distance
<
Point, Linestring, Strategy,
point_tag, linestring_tag, strategy_tag_distance_point_point,
false
>
{
static inline typename strategy::distance::services::return_type
<
Strategy, Point, typename point_type<Linestring>::type
>::type
apply(Point const& point,
Linestring const& linestring,
Strategy const&)
{
typedef typename detail::distance::default_ps_strategy
<
Point,
typename point_type<Linestring>::type,
Strategy
>::type ps_strategy_type;
return detail::distance::point_to_range
<
Point, Linestring, closed, ps_strategy_type
>::apply(point, linestring, ps_strategy_type());
}
};
// Point-ring , where point-point strategy is specified
template <typename Point, typename Ring, typename Strategy>
struct distance
<
Point, Ring, Strategy,
point_tag, ring_tag, strategy_tag_distance_point_point,
false
>
{
typedef typename strategy::distance::services::return_type
<
Strategy, Point, typename point_type<Ring>::type
>::type return_type;
static inline return_type apply(Point const& point,
Ring const& ring,
Strategy const&)
{
typedef typename detail::distance::default_ps_strategy
<
Point,
typename point_type<Ring>::type,
Strategy
>::type ps_strategy_type;
return detail::distance::point_to_ring
<
Point, Ring,
geometry::closure<Ring>::value,
ps_strategy_type
>::apply(point, ring, ps_strategy_type());
}
};
// Point-polygon , where point-point strategy is specified
template <typename Point, typename Polygon, typename Strategy>
struct distance
<
Point, Polygon, Strategy,
point_tag, polygon_tag, strategy_tag_distance_point_point,
false
>
{
typedef typename strategy::distance::services::return_type
<
Strategy, Point, typename point_type<Polygon>::type
>::type return_type;
static inline return_type apply(Point const& point,
Polygon const& polygon,
Strategy const&)
{
typedef typename detail::distance::default_ps_strategy
<
Point,
typename point_type<Polygon>::type,
Strategy
>::type ps_strategy_type;
return detail::distance::point_to_polygon
<
Point,
Polygon,
geometry::closure<Polygon>::value,
ps_strategy_type
>::apply(point, polygon, ps_strategy_type());
}
};
template
<
typename Point,
typename MultiGeometry,
typename MultiGeometryTag,
typename Strategy
>
struct distance
<
Point, MultiGeometry, Strategy,
point_tag, MultiGeometryTag,
strategy_tag_distance_point_point, false
>
{
typedef typename strategy::distance::services::return_type
<
Strategy, Point, typename point_type<MultiGeometry>::type
>::type return_type;
static inline return_type apply(Point const& point,
MultiGeometry const& multigeometry,
Strategy const&)
{
typedef typename detail::distance::default_ps_strategy
<
Point,
typename point_type<MultiGeometry>::type,
Strategy
>::type ps_strategy_type;
return distance
<
Point, MultiGeometry, ps_strategy_type,
point_tag, MultiGeometryTag,
strategy_tag_distance_point_segment, false
>::apply(point, multigeometry, ps_strategy_type());
}
};
template
<
typename Geometry,
typename MultiPoint,
typename GeometryTag,
typename Strategy
>
struct distance
<
Geometry, MultiPoint, Strategy,
GeometryTag, multi_point_tag,
strategy_tag_distance_point_point, false
>
{
typedef typename strategy::distance::services::return_type
<
Strategy,
typename point_type<MultiPoint>::type,
typename point_type<Geometry>::type
>::type return_type;
static inline return_type apply(Geometry const& geometry,
MultiPoint const& multipoint,
Strategy const&)
{
typedef typename detail::distance::default_ps_strategy
<
typename point_type<MultiPoint>::type,
typename point_type<Geometry>::type,
Strategy
>::type ps_strategy_type;
return distance
<
Geometry, MultiPoint, ps_strategy_type,
GeometryTag, multi_point_tag,
strategy_tag_distance_point_segment, false
>::apply(geometry, multipoint, ps_strategy_type());
}
};
template
<
typename MultiPoint,
typename MultiGeometry,
typename MultiGeometryTag,
typename Strategy
>
struct distance
<
MultiPoint, MultiGeometry, Strategy,
multi_point_tag, MultiGeometryTag,
strategy_tag_distance_point_point, false
>
{
typedef typename strategy::distance::services::return_type
<
Strategy,
typename point_type<MultiPoint>::type,
typename point_type<MultiGeometry>::type
>::type return_type;
static inline return_type apply(MultiPoint const& multipoint,
MultiGeometry const& multigeometry,
Strategy const&)
{
typedef typename detail::distance::default_ps_strategy
<
typename point_type<MultiPoint>::type,
typename point_type<MultiGeometry>::type,
Strategy
>::type ps_strategy_type;
return distance
<
MultiPoint, MultiGeometry, ps_strategy_type,
multi_point_tag, MultiGeometryTag,
strategy_tag_distance_point_segment, false
>::apply(multipoint, multigeometry, ps_strategy_type());
}
};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_BACKWARD_COMPATIBILITY_HPP

View File

@@ -0,0 +1,60 @@
// 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_DISTANCE_BOX_TO_BOX_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_BOX_TO_BOX_HPP
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/tags.hpp>
#include <boost/geometry/algorithms/dispatch/distance.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
template <typename Box1, typename Box2, typename Strategy>
struct distance
<
Box1, Box2, Strategy, box_tag, box_tag,
strategy_tag_distance_box_box, false
>
{
static inline typename strategy::distance::services::return_type
<
Strategy,
typename point_type<Box1>::type,
typename point_type<Box2>::type
>::type
apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
{
boost::ignore_unused(strategy);
return strategy.apply(box1, box2);
}
};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_BOX_TO_BOX_HPP

View File

@@ -0,0 +1,157 @@
// 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.
// 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.
// 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_DISTANCE_DEFAULT_STRATEGIES_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_DEFAULT_STRATEGIES_HPP
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tag_cast.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/reverse_dispatch.hpp>
#include <boost/geometry/strategies/distance.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace distance
{
// Helper metafunction for default strategy retrieval
template
<
typename Geometry1,
typename Geometry2 = Geometry1,
typename Tag1 = typename tag_cast
<
typename tag<Geometry1>::type, pointlike_tag
>::type,
typename Tag2 = typename tag_cast
<
typename tag<Geometry2>::type, pointlike_tag
>::type,
bool Reverse = geometry::reverse_dispatch<Geometry1, Geometry2>::type::value
>
struct default_strategy
: strategy::distance::services::default_strategy
<
point_tag, segment_tag,
typename point_type<Geometry1>::type,
typename point_type<Geometry2>::type
>
{};
template
<
typename Geometry1,
typename Geometry2,
typename Tag1,
typename Tag2
>
struct default_strategy<Geometry1, Geometry2, Tag1, Tag2, true>
: default_strategy<Geometry2, Geometry1, Tag2, Tag1, false>
{};
template <typename Pointlike1, typename Pointlike2>
struct default_strategy
<
Pointlike1, Pointlike2,
pointlike_tag, pointlike_tag, false
> : strategy::distance::services::default_strategy
<
point_tag, point_tag,
typename point_type<Pointlike1>::type,
typename point_type<Pointlike2>::type
>
{};
template <typename Pointlike, typename Box>
struct default_strategy<Pointlike, Box, pointlike_tag, box_tag, false>
: strategy::distance::services::default_strategy
<
point_tag, box_tag,
typename point_type<Pointlike>::type,
typename point_type<Box>::type
>
{};
template <typename Box1, typename Box2>
struct default_strategy<Box1, Box2, box_tag, box_tag, false>
: strategy::distance::services::default_strategy
<
box_tag, box_tag,
typename point_type<Box1>::type,
typename point_type<Box2>::type
>
{};
template <typename Linear, typename Box>
struct default_strategy<Linear, Box, segment_tag, box_tag, false>
: strategy::distance::services::default_strategy
<
segment_tag, box_tag,
typename point_type<Linear>::type,
typename point_type<Box>::type
>
{};
template <typename Linear, typename Box>
struct default_strategy<Linear, Box, linear_tag, box_tag, false>
: strategy::distance::services::default_strategy
<
segment_tag, box_tag,
typename point_type<Linear>::type,
typename point_type<Box>::type
>
{};
// Helper metafunction for default point-segment strategy retrieval
template <typename Geometry1, typename Geometry2, typename Strategy>
struct default_ps_strategy
: strategy::distance::services::default_strategy
<
point_tag, segment_tag,
typename point_type<Geometry1>::type,
typename point_type<Geometry2>::type,
typename cs_tag<typename point_type<Geometry1>::type>::type,
typename cs_tag<typename point_type<Geometry2>::type>::type,
Strategy
>
{};
}} // namespace detail::distance
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_DEFAULT_STRATEGIES_HPP

View File

@@ -0,0 +1,464 @@
// 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_DISTANCE_GEOMETRY_TO_SEGMENT_OR_BOX_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_GEOMETRY_TO_SEGMENT_OR_BOX_HPP
#include <iterator>
#include <boost/range.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/tags.hpp>
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/intersects.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
#include <boost/geometry/iterators/point_iterator.hpp>
#include <boost/geometry/iterators/segment_iterator.hpp>
#include <boost/geometry/algorithms/dispatch/distance.hpp>
#include <boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp>
#include <boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp>
#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
#include <boost/geometry/util/condition.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace distance
{
// closure of segment or box point range
template
<
typename SegmentOrBox,
typename Tag = typename tag<SegmentOrBox>::type
>
struct segment_or_box_point_range_closure
: not_implemented<SegmentOrBox>
{};
template <typename Segment>
struct segment_or_box_point_range_closure<Segment, segment_tag>
{
static const closure_selector value = closed;
};
template <typename Box>
struct segment_or_box_point_range_closure<Box, box_tag>
{
static const closure_selector value = open;
};
template
<
typename Geometry,
typename SegmentOrBox,
typename Strategy,
typename Tag = typename tag<Geometry>::type
>
class geometry_to_segment_or_box
{
private:
typedef typename point_type<SegmentOrBox>::type segment_or_box_point;
typedef typename strategy::distance::services::comparable_type
<
Strategy
>::type comparable_strategy;
typedef detail::closest_feature::point_to_point_range
<
typename point_type<Geometry>::type,
std::vector<segment_or_box_point>,
segment_or_box_point_range_closure<SegmentOrBox>::value,
comparable_strategy
> point_to_point_range;
typedef detail::closest_feature::geometry_to_range geometry_to_range;
typedef typename strategy::distance::services::return_type
<
comparable_strategy,
typename point_type<Geometry>::type,
segment_or_box_point
>::type comparable_return_type;
// assign the new minimum value for an iterator of the point range
// of a segment or a box
template
<
typename SegOrBox,
typename SegOrBoxTag = typename tag<SegOrBox>::type
>
struct assign_new_min_iterator
: not_implemented<SegOrBox>
{};
template <typename Segment>
struct assign_new_min_iterator<Segment, segment_tag>
{
template <typename Iterator>
static inline void apply(Iterator&, Iterator)
{
}
};
template <typename Box>
struct assign_new_min_iterator<Box, box_tag>
{
template <typename Iterator>
static inline void apply(Iterator& it_min, Iterator it)
{
it_min = it;
}
};
// assign the points of a segment or a box to a range
template
<
typename SegOrBox,
typename PointRange,
typename SegOrBoxTag = typename tag<SegOrBox>::type
>
struct assign_segment_or_box_points
{};
template <typename Segment, typename PointRange>
struct assign_segment_or_box_points<Segment, PointRange, segment_tag>
{
static inline void apply(Segment const& segment, PointRange& range)
{
detail::assign_point_from_index<0>(segment, range[0]);
detail::assign_point_from_index<1>(segment, range[1]);
}
};
template <typename Box, typename PointRange>
struct assign_segment_or_box_points<Box, PointRange, box_tag>
{
static inline void apply(Box const& box, PointRange& range)
{
detail::assign_box_corners_oriented<true>(box, range);
}
};
public:
typedef typename strategy::distance::services::return_type
<
Strategy,
typename point_type<Geometry>::type,
segment_or_box_point
>::type return_type;
static inline return_type apply(Geometry const& geometry,
SegmentOrBox const& segment_or_box,
Strategy const& strategy,
bool check_intersection = true)
{
typedef geometry::point_iterator<Geometry const> point_iterator_type;
typedef geometry::segment_iterator
<
Geometry const
> segment_iterator_type;
typedef typename boost::range_const_iterator
<
std::vector<segment_or_box_point>
>::type seg_or_box_const_iterator;
typedef assign_new_min_iterator<SegmentOrBox> assign_new_value;
if (check_intersection
&& geometry::intersects(geometry, segment_or_box))
{
return 0;
}
comparable_strategy cstrategy =
strategy::distance::services::get_comparable
<
Strategy
>::apply(strategy);
// get all points of the segment or the box
std::vector<segment_or_box_point>
seg_or_box_points(geometry::num_points(segment_or_box));
assign_segment_or_box_points
<
SegmentOrBox,
std::vector<segment_or_box_point>
>::apply(segment_or_box, seg_or_box_points);
// consider all distances of the points in the geometry to the
// segment or box
comparable_return_type cd_min1(0);
point_iterator_type pit_min;
seg_or_box_const_iterator it_min1 = boost::const_begin(seg_or_box_points);
seg_or_box_const_iterator it_min2 = it_min1;
++it_min2;
bool first = true;
for (point_iterator_type pit = points_begin(geometry);
pit != points_end(geometry); ++pit, first = false)
{
comparable_return_type cd;
std::pair
<
seg_or_box_const_iterator, seg_or_box_const_iterator
> it_pair
= point_to_point_range::apply(*pit,
boost::const_begin(seg_or_box_points),
boost::const_end(seg_or_box_points),
cstrategy,
cd);
if (first || cd < cd_min1)
{
cd_min1 = cd;
pit_min = pit;
assign_new_value::apply(it_min1, it_pair.first);
assign_new_value::apply(it_min2, it_pair.second);
}
}
// consider all distances of the points in the segment or box to the
// segments of the geometry
comparable_return_type cd_min2(0);
segment_iterator_type sit_min;
seg_or_box_const_iterator it_min;
first = true;
for (seg_or_box_const_iterator it = boost::const_begin(seg_or_box_points);
it != boost::const_end(seg_or_box_points); ++it, first = false)
{
comparable_return_type cd;
segment_iterator_type sit
= geometry_to_range::apply(*it,
segments_begin(geometry),
segments_end(geometry),
cstrategy,
cd);
if (first || cd < cd_min2)
{
cd_min2 = cd;
it_min = it;
sit_min = sit;
}
}
if (BOOST_GEOMETRY_CONDITION(is_comparable<Strategy>::value))
{
return (std::min)(cd_min1, cd_min2);
}
if (cd_min1 < cd_min2)
{
return strategy.apply(*pit_min, *it_min1, *it_min2);
}
else
{
return dispatch::distance
<
segment_or_box_point,
typename std::iterator_traits
<
segment_iterator_type
>::value_type,
Strategy
>::apply(*it_min, *sit_min, strategy);
}
}
static inline return_type
apply(SegmentOrBox const& segment_or_box, Geometry const& geometry,
Strategy const& strategy, bool check_intersection = true)
{
return apply(geometry, segment_or_box, strategy, check_intersection);
}
};
template <typename MultiPoint, typename SegmentOrBox, typename Strategy>
class geometry_to_segment_or_box
<
MultiPoint, SegmentOrBox, Strategy, multi_point_tag
>
{
private:
typedef detail::closest_feature::geometry_to_range base_type;
typedef typename boost::range_iterator
<
MultiPoint const
>::type iterator_type;
typedef detail::closest_feature::geometry_to_range geometry_to_range;
public:
typedef typename strategy::distance::services::return_type
<
Strategy,
typename point_type<SegmentOrBox>::type,
typename point_type<MultiPoint>::type
>::type return_type;
static inline return_type apply(MultiPoint const& multipoint,
SegmentOrBox const& segment_or_box,
Strategy const& strategy)
{
namespace sds = strategy::distance::services;
typename sds::return_type
<
typename sds::comparable_type<Strategy>::type,
typename point_type<SegmentOrBox>::type,
typename point_type<MultiPoint>::type
>::type cd_min;
iterator_type it_min
= geometry_to_range::apply(segment_or_box,
boost::begin(multipoint),
boost::end(multipoint),
sds::get_comparable
<
Strategy
>::apply(strategy),
cd_min);
return
is_comparable<Strategy>::value
?
cd_min
:
dispatch::distance
<
typename point_type<MultiPoint>::type,
SegmentOrBox,
Strategy
>::apply(*it_min, segment_or_box, strategy);
}
};
}} // namespace detail::distance
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
template <typename Linear, typename Segment, typename Strategy>
struct distance
<
Linear, Segment, Strategy, linear_tag, segment_tag,
strategy_tag_distance_point_segment, false
> : detail::distance::geometry_to_segment_or_box<Linear, Segment, Strategy>
{};
template <typename Areal, typename Segment, typename Strategy>
struct distance
<
Areal, Segment, Strategy, areal_tag, segment_tag,
strategy_tag_distance_point_segment, false
> : detail::distance::geometry_to_segment_or_box<Areal, Segment, Strategy>
{};
template <typename Segment, typename Areal, typename Strategy>
struct distance
<
Segment, Areal, Strategy, segment_tag, areal_tag,
strategy_tag_distance_point_segment, false
> : detail::distance::geometry_to_segment_or_box<Areal, Segment, Strategy>
{};
template <typename Linear, typename Box, typename Strategy>
struct distance
<
Linear, Box, Strategy, linear_tag, box_tag,
strategy_tag_distance_point_segment, false
> : detail::distance::geometry_to_segment_or_box
<
Linear, Box, Strategy
>
{};
template <typename Areal, typename Box, typename Strategy>
struct distance
<
Areal, Box, Strategy, areal_tag, box_tag,
strategy_tag_distance_point_segment, false
> : detail::distance::geometry_to_segment_or_box<Areal, Box, Strategy>
{};
template <typename MultiPoint, typename Segment, typename Strategy>
struct distance
<
MultiPoint, Segment, Strategy,
multi_point_tag, segment_tag,
strategy_tag_distance_point_segment, false
> : detail::distance::geometry_to_segment_or_box
<
MultiPoint, Segment, Strategy
>
{};
template <typename MultiPoint, typename Box, typename Strategy>
struct distance
<
MultiPoint, Box, Strategy,
multi_point_tag, box_tag,
strategy_tag_distance_point_box, false
> : detail::distance::geometry_to_segment_or_box
<
MultiPoint, Box, Strategy
>
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_GEOMETRY_TO_SEGMENT_OR_BOX_HPP

View File

@@ -0,0 +1,37 @@
// 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.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2014, 2018.
// Modifications 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
// 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_DISTANCE_IMPLEMENTATION_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_IMPLEMENTATION_HPP
// the implementation details
#include <boost/geometry/algorithms/detail/distance/point_to_geometry.hpp>
#include <boost/geometry/algorithms/detail/distance/multipoint_to_geometry.hpp>
#include <boost/geometry/algorithms/detail/distance/linear_to_linear.hpp>
#include <boost/geometry/algorithms/detail/distance/linear_or_areal_to_areal.hpp>
#include <boost/geometry/algorithms/detail/distance/linear_to_box.hpp>
#include <boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp>
#include <boost/geometry/algorithms/detail/distance/segment_to_segment.hpp>
#include <boost/geometry/algorithms/detail/distance/segment_to_box.hpp>
#include <boost/geometry/algorithms/detail/distance/box_to_box.hpp>
#include <boost/geometry/algorithms/detail/distance/backward_compatibility.hpp>
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_IMPLEMENTATION_HPP

View File

@@ -0,0 +1,412 @@
// 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.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2014 Samuel Debionne, Grenoble, France.
// This file was modified by Oracle on 2014, 2018.
// Modifications copyright (c) 2014-2018, 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_DISTANCE_INTERFACE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_INTERFACE_HPP
#include <boost/concept_check.hpp>
#include <boost/mpl/always.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/default_distance_result.hpp>
#include <boost/geometry/strategies/distance_result.hpp>
#include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
#include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
#include <boost/geometry/algorithms/dispatch/distance.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
// If reversal is needed, perform it
template
<
typename Geometry1, typename Geometry2, typename Strategy,
typename Tag1, typename Tag2, typename StrategyTag
>
struct distance
<
Geometry1, Geometry2, Strategy,
Tag1, Tag2, StrategyTag,
true
>
: distance<Geometry2, Geometry1, Strategy, Tag2, Tag1, StrategyTag, false>
{
typedef typename strategy::distance::services::return_type
<
Strategy,
typename point_type<Geometry2>::type,
typename point_type<Geometry1>::type
>::type return_type;
static inline return_type apply(
Geometry1 const& g1,
Geometry2 const& g2,
Strategy const& strategy)
{
return distance
<
Geometry2, Geometry1, Strategy,
Tag2, Tag1, StrategyTag,
false
>::apply(g2, g1, strategy);
}
};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
namespace resolve_strategy
{
template <typename Strategy>
struct distance
{
template <typename Geometry1, typename Geometry2>
static inline typename distance_result<Geometry1, Geometry2, Strategy>::type
apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
return dispatch::distance
<
Geometry1, Geometry2, Strategy
>::apply(geometry1, geometry2, strategy);
}
};
template <>
struct distance<default_strategy>
{
template <typename Geometry1, typename Geometry2>
static inline
typename distance_result<Geometry1, Geometry2, default_strategy>::type
apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
default_strategy)
{
typedef typename detail::distance::default_strategy
<
Geometry1, Geometry2
>::type strategy_type;
return dispatch::distance
<
Geometry1, Geometry2, strategy_type
>::apply(geometry1, geometry2, strategy_type());
}
};
} // namespace resolve_strategy
namespace resolve_variant
{
template <typename Geometry1, typename Geometry2>
struct distance
{
template <typename Strategy>
static inline typename distance_result<Geometry1, Geometry2, Strategy>::type
apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
return resolve_strategy::distance
<
Strategy
>::apply(geometry1, geometry2, strategy);
}
};
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
struct distance<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
{
template <typename Strategy>
struct visitor: static_visitor
<
typename distance_result
<
variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
Geometry2,
Strategy
>::type
>
{
Geometry2 const& m_geometry2;
Strategy const& m_strategy;
visitor(Geometry2 const& geometry2,
Strategy const& strategy)
: m_geometry2(geometry2),
m_strategy(strategy)
{}
template <typename Geometry1>
typename distance_result<Geometry1, Geometry2, Strategy>::type
operator()(Geometry1 const& geometry1) const
{
return distance
<
Geometry1,
Geometry2
>::template apply
<
Strategy
>(geometry1, m_geometry2, m_strategy);
}
};
template <typename Strategy>
static inline typename distance_result
<
variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
Geometry2,
Strategy
>::type
apply(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 distance<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
template <typename Strategy>
struct visitor: static_visitor
<
typename distance_result
<
Geometry1,
variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
Strategy
>::type
>
{
Geometry1 const& m_geometry1;
Strategy const& m_strategy;
visitor(Geometry1 const& geometry1,
Strategy const& strategy)
: m_geometry1(geometry1),
m_strategy(strategy)
{}
template <typename Geometry2>
typename distance_result<Geometry1, Geometry2, Strategy>::type
operator()(Geometry2 const& geometry2) const
{
return distance
<
Geometry1,
Geometry2
>::template apply
<
Strategy
>(m_geometry1, geometry2, m_strategy);
}
};
template <typename Strategy>
static inline typename distance_result
<
Geometry1,
variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
Strategy
>::type
apply(
Geometry1 const& geometry1,
const variant<BOOST_VARIANT_ENUM_PARAMS(T)>& 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 distance
<
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
>
{
template <typename Strategy>
struct visitor: static_visitor
<
typename distance_result
<
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>,
Strategy
>::type
>
{
Strategy const& m_strategy;
visitor(Strategy const& strategy)
: m_strategy(strategy)
{}
template <typename Geometry1, typename Geometry2>
typename distance_result<Geometry1, Geometry2, Strategy>::type
operator()(Geometry1 const& geometry1, Geometry2 const& geometry2) const
{
return distance
<
Geometry1,
Geometry2
>::template apply
<
Strategy
>(geometry1, geometry2, m_strategy);
}
};
template <typename Strategy>
static inline typename distance_result
<
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>,
Strategy
>::type
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 Calculate the distance between two geometries \brief_strategy
\ingroup distance
\details
\details The free function distance calculates the distance between two geometries \brief_strategy. \details_strategy_reasons
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry
\tparam Strategy \tparam_strategy{Distance}
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\param strategy \param_strategy{distance}
\return \return_calc{distance}
\note The strategy can be a point-point strategy. In case of distance point-line/point-polygon
it may also be a point-segment strategy.
\qbk{distinguish,with strategy}
\qbk{
[heading Available Strategies]
\* [link geometry.reference.strategies.strategy_distance_pythagoras Pythagoras (cartesian)]
\* [link geometry.reference.strategies.strategy_distance_haversine Haversine (spherical)]
\* [link geometry.reference.strategies.strategy_distance_cross_track Cross track (spherical\, point-to-segment)]
\* [link geometry.reference.strategies.strategy_distance_projected_point Projected point (cartesian\, point-to-segment)]
\* more (currently extensions): Vincenty\, Andoyer (geographic)
}
*/
/*
Note, in case of a Compilation Error:
if you get:
- "Failed to specialize function template ..."
- "error: no matching function for call to ..."
for distance, it is probably so that there is no specialization
for return_type<...> for your strategy.
*/
template <typename Geometry1, typename Geometry2, typename Strategy>
inline typename distance_result<Geometry1, Geometry2, Strategy>::type
distance(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
detail::throw_on_empty_input(geometry1);
detail::throw_on_empty_input(geometry2);
return resolve_variant::distance
<
Geometry1,
Geometry2
>::apply(geometry1, geometry2, strategy);
}
/*!
\brief Calculate the distance between two geometries.
\ingroup distance
\details The free function distance calculates the distance between two geometries. \details_default_strategy
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\return \return_calc{distance}
\qbk{[include reference/algorithms/distance.qbk]}
*/
template <typename Geometry1, typename Geometry2>
inline typename default_distance_result<Geometry1, Geometry2>::type
distance(Geometry1 const& geometry1,
Geometry2 const& geometry2)
{
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
return geometry::distance(geometry1, geometry2, default_strategy());
}
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_INTERFACE_HPP

View File

@@ -0,0 +1,45 @@
// 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_ALGORITHS_DETAIL_DISTANCE_IS_COMPARABLE_HPP
#define BOOST_GEOMETRY_ALGORITHS_DETAIL_DISTANCE_IS_COMPARABLE_HPP
#include <boost/type_traits/is_same.hpp>
#include <boost/geometry/strategies/distance.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace distance
{
// metafunction to determine is a strategy is comparable or not
template <typename Strategy>
struct is_comparable
: boost::is_same
<
Strategy,
typename strategy::distance::services::comparable_type
<
Strategy
>::type
>
{};
}} // namespace detail::distance
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHS_DETAIL_DISTANCE_IS_COMPARABLE_HPP

View File

@@ -0,0 +1,70 @@
// 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_ALGORITHS_DETAIL_DISTANCE_ITERATOR_SELECTOR_HPP
#define BOOST_GEOMETRY_ALGORITHS_DETAIL_DISTANCE_ITERATOR_SELECTOR_HPP
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/iterators/point_iterator.hpp>
#include <boost/geometry/iterators/segment_iterator.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace distance
{
// class to choose between point_iterator and segment_iterator
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
struct iterator_selector
{
typedef geometry::segment_iterator<Geometry> iterator_type;
static inline iterator_type begin(Geometry& geometry)
{
return segments_begin(geometry);
}
static inline iterator_type end(Geometry& geometry)
{
return segments_end(geometry);
}
};
template <typename MultiPoint>
struct iterator_selector<MultiPoint, multi_point_tag>
{
typedef geometry::point_iterator<MultiPoint> iterator_type;
static inline iterator_type begin(MultiPoint& multipoint)
{
return points_begin(multipoint);
}
static inline iterator_type end(MultiPoint& multipoint)
{
return points_end(multipoint);
}
};
}} // namespace detail::distance
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHS_DETAIL_DISTANCE_ITERATOR_SELECTOR_HPP

View File

@@ -0,0 +1,144 @@
// 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_DISTANCE_LINEAR_OR_AREAL_TO_AREAL_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_LINEAR_OR_AREAL_TO_AREAL_HPP
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/algorithms/intersects.hpp>
#include <boost/geometry/algorithms/detail/distance/linear_to_linear.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace distance
{
template <typename Linear, typename Areal, typename Strategy>
struct linear_to_areal
{
typedef typename strategy::distance::services::return_type
<
Strategy,
typename point_type<Linear>::type,
typename point_type<Areal>::type
>::type return_type;
static inline return_type apply(Linear const& linear,
Areal const& areal,
Strategy const& strategy)
{
if ( geometry::intersects(linear, areal) )
{
return 0;
}
return linear_to_linear
<
Linear, Areal, Strategy
>::apply(linear, areal, strategy, false);
}
static inline return_type apply(Areal const& areal,
Linear const& linear,
Strategy const& strategy)
{
return apply(linear, areal, strategy);
}
};
template <typename Areal1, typename Areal2, typename Strategy>
struct areal_to_areal
{
typedef typename strategy::distance::services::return_type
<
Strategy,
typename point_type<Areal1>::type,
typename point_type<Areal2>::type
>::type return_type;
static inline return_type apply(Areal1 const& areal1,
Areal2 const& areal2,
Strategy const& strategy)
{
if ( geometry::intersects(areal1, areal2) )
{
return 0;
}
return linear_to_linear
<
Areal1, Areal2, Strategy
>::apply(areal1, areal2, strategy, false);
}
};
}} // namespace detail::distance
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
template <typename Linear, typename Areal, typename Strategy>
struct distance
<
Linear, Areal, Strategy,
linear_tag, areal_tag,
strategy_tag_distance_point_segment, false
>
: detail::distance::linear_to_areal
<
Linear, Areal, Strategy
>
{};
template <typename Areal, typename Linear, typename Strategy>
struct distance
<
Areal, Linear, Strategy,
areal_tag, linear_tag,
strategy_tag_distance_point_segment, false
>
: detail::distance::linear_to_areal
<
Linear, Areal, Strategy
>
{};
template <typename Areal1, typename Areal2, typename Strategy>
struct distance
<
Areal1, Areal2, Strategy,
areal_tag, areal_tag,
strategy_tag_distance_point_segment, false
>
: detail::distance::areal_to_areal
<
Areal1, Areal2, Strategy
>
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_LINEAR_OR_AREAL_TO_AREAL_HPP

View File

@@ -0,0 +1,123 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, 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_DISTANCE_LINEAR_TO_BOX_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_LINEAR_TO_BOX_HPP
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/algorithms/intersects.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace distance
{
template <typename Linear, typename Box, typename Strategy>
struct linear_to_box
{
typedef typename strategy::distance::services::return_type
<
Strategy,
typename point_type<Linear>::type,
typename point_type<Box>::type
>::type return_type;
template <typename Iterator>
static inline return_type apply(Box const& box,
Iterator begin,
Iterator end,
Strategy const& strategy)
{
bool first = true;
return_type d_min(0);
for (Iterator it = begin; it != end; ++it, first = false)
{
typedef typename std::iterator_traits<Iterator>::value_type
Segment;
return_type d = dispatch::distance<Segment, Box, Strategy>
::apply(*it, box, strategy);
if ( first || d < d_min )
{
d_min = d;
}
}
return d_min;
}
static inline return_type apply(Linear const& linear,
Box const& box,
Strategy const& strategy)
{
if ( geometry::intersects(linear, box) )
{
return 0;
}
return apply(box,
geometry::segments_begin(linear),
geometry::segments_end(linear),
strategy);
}
static inline return_type apply(Box const& box,
Linear const& linear,
Strategy const& strategy)
{
return apply(linear, box, strategy);
}
};
}} // namespace detail::distance
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
template <typename Linear, typename Box, typename Strategy>
struct distance
<
Linear, Box, Strategy,
linear_tag, box_tag,
strategy_tag_distance_segment_box, false
>
: detail::distance::linear_to_box
<
Linear, Box, Strategy
>
{};
template <typename Areal, typename Box, typename Strategy>
struct distance
<
Areal, Box, Strategy,
areal_tag, box_tag,
strategy_tag_distance_segment_box, false
>
: detail::distance::linear_to_box
<
Areal, Box, Strategy
>
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_LINEAR_TO_BOX_HPP

View File

@@ -0,0 +1,123 @@
// 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_DISTANCE_LINEAR_TO_LINEAR_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_LINEAR_TO_LINEAR_HPP
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/iterators/point_iterator.hpp>
#include <boost/geometry/iterators/segment_iterator.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
#include <boost/geometry/algorithms/num_segments.hpp>
#include <boost/geometry/algorithms/dispatch/distance.hpp>
#include <boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace distance
{
template <typename Linear1, typename Linear2, typename Strategy>
struct linear_to_linear
{
typedef typename strategy::distance::services::return_type
<
Strategy,
typename point_type<Linear1>::type,
typename point_type<Linear2>::type
>::type return_type;
static inline return_type apply(Linear1 const& linear1,
Linear2 const& linear2,
Strategy const& strategy,
bool = false)
{
if (geometry::num_points(linear1) == 1)
{
return dispatch::distance
<
typename point_type<Linear1>::type,
Linear2,
Strategy
>::apply(*points_begin(linear1), linear2, strategy);
}
if (geometry::num_points(linear2) == 1)
{
return dispatch::distance
<
typename point_type<Linear2>::type,
Linear1,
Strategy
>::apply(*points_begin(linear2), linear1, strategy);
}
if (geometry::num_segments(linear2) < geometry::num_segments(linear1))
{
return point_or_segment_range_to_geometry_rtree
<
geometry::segment_iterator<Linear2 const>,
Linear1,
Strategy
>::apply(geometry::segments_begin(linear2),
geometry::segments_end(linear2),
linear1,
strategy);
}
return point_or_segment_range_to_geometry_rtree
<
geometry::segment_iterator<Linear1 const>,
Linear2,
Strategy
>::apply(geometry::segments_begin(linear1),
geometry::segments_end(linear1),
linear2,
strategy);
}
};
}} // namespace detail::distance
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
template <typename Linear1, typename Linear2, typename Strategy>
struct distance
<
Linear1, Linear2, Strategy,
linear_tag, linear_tag,
strategy_tag_distance_point_segment, false
> : detail::distance::linear_to_linear
<
Linear1, Linear2, Strategy
>
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_LINEAR_TO_LINEAR_HPP

View File

@@ -0,0 +1,240 @@
// 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_DISTANCE_MULTIPOINT_TO_GEOMETRY_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTIPOINT_TO_GEOMETRY_HPP
#include <boost/range.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/tags.hpp>
#include <boost/geometry/algorithms/covered_by.hpp>
#include <boost/geometry/algorithms/dispatch/distance.hpp>
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
#include <boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace distance
{
template <typename MultiPoint1, typename MultiPoint2, typename Strategy>
struct multipoint_to_multipoint
{
typedef typename strategy::distance::services::return_type
<
Strategy,
typename point_type<MultiPoint1>::type,
typename point_type<MultiPoint2>::type
>::type return_type;
static inline return_type apply(MultiPoint1 const& multipoint1,
MultiPoint2 const& multipoint2,
Strategy const& strategy)
{
if (boost::size(multipoint2) < boost::size(multipoint1))
{
return point_or_segment_range_to_geometry_rtree
<
typename boost::range_iterator<MultiPoint2 const>::type,
MultiPoint1,
Strategy
>::apply(boost::begin(multipoint2),
boost::end(multipoint2),
multipoint1,
strategy);
}
return point_or_segment_range_to_geometry_rtree
<
typename boost::range_iterator<MultiPoint1 const>::type,
MultiPoint2,
Strategy
>::apply(boost::begin(multipoint1),
boost::end(multipoint1),
multipoint2,
strategy);
}
};
template <typename MultiPoint, typename Linear, typename Strategy>
struct multipoint_to_linear
{
typedef typename strategy::distance::services::return_type
<
Strategy,
typename point_type<MultiPoint>::type,
typename point_type<Linear>::type
>::type return_type;
static inline return_type apply(MultiPoint const& multipoint,
Linear const& linear,
Strategy const& strategy)
{
return detail::distance::point_or_segment_range_to_geometry_rtree
<
typename boost::range_iterator<MultiPoint const>::type,
Linear,
Strategy
>::apply(boost::begin(multipoint),
boost::end(multipoint),
linear,
strategy);
}
static inline return_type apply(Linear const& linear,
MultiPoint const& multipoint,
Strategy const& strategy)
{
return apply(multipoint, linear, strategy);
}
};
template <typename MultiPoint, typename Areal, typename Strategy>
class multipoint_to_areal
{
private:
struct not_covered_by_areal
{
not_covered_by_areal(Areal const& areal)
: m_areal(areal)
{}
template <typename Point>
inline bool apply(Point const& point) const
{
return !geometry::covered_by(point, m_areal);
}
Areal const& m_areal;
};
public:
typedef typename strategy::distance::services::return_type
<
Strategy,
typename point_type<MultiPoint>::type,
typename point_type<Areal>::type
>::type return_type;
static inline return_type apply(MultiPoint const& multipoint,
Areal const& areal,
Strategy const& strategy)
{
not_covered_by_areal predicate(areal);
if (check_iterator_range
<
not_covered_by_areal, false
>::apply(boost::begin(multipoint),
boost::end(multipoint),
predicate))
{
return detail::distance::point_or_segment_range_to_geometry_rtree
<
typename boost::range_iterator<MultiPoint const>::type,
Areal,
Strategy
>::apply(boost::begin(multipoint),
boost::end(multipoint),
areal,
strategy);
}
return 0;
}
static inline return_type apply(Areal const& areal,
MultiPoint const& multipoint,
Strategy const& strategy)
{
return apply(multipoint, areal, strategy);
}
};
}} // namespace detail::distance
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
template <typename MultiPoint1, typename MultiPoint2, typename Strategy>
struct distance
<
MultiPoint1, MultiPoint2, Strategy,
multi_point_tag, multi_point_tag,
strategy_tag_distance_point_point, false
> : detail::distance::multipoint_to_multipoint
<
MultiPoint1, MultiPoint2, Strategy
>
{};
template <typename MultiPoint, typename Linear, typename Strategy>
struct distance
<
MultiPoint, Linear, Strategy, multi_point_tag, linear_tag,
strategy_tag_distance_point_segment, false
> : detail::distance::multipoint_to_linear<MultiPoint, Linear, Strategy>
{};
template <typename Linear, typename MultiPoint, typename Strategy>
struct distance
<
Linear, MultiPoint, Strategy, linear_tag, multi_point_tag,
strategy_tag_distance_point_segment, false
> : detail::distance::multipoint_to_linear<MultiPoint, Linear, Strategy>
{};
template <typename MultiPoint, typename Areal, typename Strategy>
struct distance
<
MultiPoint, Areal, Strategy, multi_point_tag, areal_tag,
strategy_tag_distance_point_segment, false
> : detail::distance::multipoint_to_areal<MultiPoint, Areal, Strategy>
{};
template <typename Areal, typename MultiPoint, typename Strategy>
struct distance
<
Areal, MultiPoint, Strategy, areal_tag, multi_point_tag,
strategy_tag_distance_point_segment, false
> : detail::distance::multipoint_to_areal<MultiPoint, Areal, Strategy>
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTIPOINT_TO_GEOMETRY_HPP

View File

@@ -0,0 +1,522 @@
// 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.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2014, 2019.
// Modifications copyright (c) 2014-2019, 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_DISTANCE_POINT_TO_GEOMETRY_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_POINT_TO_GEOMETRY_HPP
#include <iterator>
#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/tags.hpp>
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp>
#include <boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp>
#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
#include <boost/geometry/algorithms/detail/distance/iterator_selector.hpp>
#include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
#include <boost/geometry/algorithms/dispatch/distance.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace distance
{
template <typename P1, typename P2, typename Strategy>
struct point_to_point
{
static inline
typename strategy::distance::services::return_type<Strategy, P1, P2>::type
apply(P1 const& p1, P2 const& p2, Strategy const& strategy)
{
boost::ignore_unused(strategy);
return strategy.apply(p1, p2);
}
};
template
<
typename Point,
typename Range,
closure_selector Closure,
typename Strategy
>
class point_to_range
{
private:
typedef typename strategy::distance::services::comparable_type
<
Strategy
>::type comparable_strategy;
typedef detail::closest_feature::point_to_point_range
<
Point, Range, Closure, comparable_strategy
> point_to_point_range;
public:
typedef typename strategy::distance::services::return_type
<
Strategy,
Point,
typename boost::range_value<Range>::type
>::type return_type;
static inline return_type apply(Point const& point, Range const& range,
Strategy const& strategy)
{
return_type const zero = return_type(0);
if (boost::size(range) == 0)
{
return zero;
}
namespace sds = strategy::distance::services;
typename sds::return_type
<
comparable_strategy,
Point,
typename point_type<Range>::type
>::type cd_min;
std::pair
<
typename boost::range_iterator<Range const>::type,
typename boost::range_iterator<Range const>::type
> it_pair
= point_to_point_range::apply(point,
boost::begin(range),
boost::end(range),
sds::get_comparable
<
Strategy
>::apply(strategy),
cd_min);
return
is_comparable<Strategy>::value
?
cd_min
:
strategy.apply(point, *it_pair.first, *it_pair.second);
}
};
template
<
typename Point,
typename Ring,
closure_selector Closure,
typename Strategy
>
struct point_to_ring
{
typedef typename strategy::distance::services::return_type
<
Strategy, Point, typename point_type<Ring>::type
>::type return_type;
static inline return_type apply(Point const& point,
Ring const& ring,
Strategy const& strategy)
{
// TODO: pass strategy
if (within::within_point_geometry(point, ring))
{
return return_type(0);
}
return point_to_range
<
Point, Ring, closure<Ring>::value, Strategy
>::apply(point, ring, strategy);
}
};
template
<
typename Point,
typename Polygon,
closure_selector Closure,
typename Strategy
>
class point_to_polygon
{
public:
typedef typename strategy::distance::services::return_type
<
Strategy, Point, typename point_type<Polygon>::type
>::type return_type;
private:
typedef point_to_range
<
Point, typename ring_type<Polygon>::type, Closure, Strategy
> per_ring;
struct distance_to_interior_rings
{
template <typename InteriorRingIterator>
static inline return_type apply(Point const& point,
InteriorRingIterator first,
InteriorRingIterator last,
Strategy const& strategy)
{
for (InteriorRingIterator it = first; it != last; ++it)
{
// TODO: pass strategy
if (within::within_point_geometry(point, *it))
{
// the point is inside a polygon hole, so its distance
// to the polygon its distance to the polygon's
// hole boundary
return per_ring::apply(point, *it, strategy);
}
}
return 0;
}
template <typename InteriorRings>
static inline return_type apply(Point const& point,
InteriorRings const& interior_rings,
Strategy const& strategy)
{
return apply(point,
boost::begin(interior_rings),
boost::end(interior_rings),
strategy);
}
};
public:
static inline return_type apply(Point const& point,
Polygon const& polygon,
Strategy const& strategy)
{
// TODO: pass strategy
if (! within::covered_by_point_geometry(point, exterior_ring(polygon)))
{
// the point is outside the exterior ring, so its distance
// to the polygon is its distance to the polygon's exterior ring
return per_ring::apply(point, exterior_ring(polygon), strategy);
}
// Check interior rings
return distance_to_interior_rings::apply(point,
interior_rings(polygon),
strategy);
}
};
template
<
typename Point,
typename MultiGeometry,
typename Strategy,
bool CheckCoveredBy = boost::is_same
<
typename tag<MultiGeometry>::type, multi_polygon_tag
>::value
>
class point_to_multigeometry
{
private:
typedef detail::closest_feature::geometry_to_range geometry_to_range;
public:
typedef typename strategy::distance::services::return_type
<
Strategy,
Point,
typename point_type<MultiGeometry>::type
>::type return_type;
static inline return_type apply(Point const& point,
MultiGeometry const& multigeometry,
Strategy const& strategy)
{
typedef iterator_selector<MultiGeometry const> selector_type;
namespace sds = strategy::distance::services;
typename sds::return_type
<
typename sds::comparable_type<Strategy>::type,
Point,
typename point_type<MultiGeometry>::type
>::type cd;
typename selector_type::iterator_type it_min
= geometry_to_range::apply(point,
selector_type::begin(multigeometry),
selector_type::end(multigeometry),
sds::get_comparable
<
Strategy
>::apply(strategy),
cd);
return
is_comparable<Strategy>::value
?
cd
:
dispatch::distance
<
Point,
typename std::iterator_traits
<
typename selector_type::iterator_type
>::value_type,
Strategy
>::apply(point, *it_min, strategy);
}
};
// this is called only for multipolygons, hence the change in the
// template parameter name MultiGeometry to MultiPolygon
template <typename Point, typename MultiPolygon, typename Strategy>
struct point_to_multigeometry<Point, MultiPolygon, Strategy, true>
{
typedef typename strategy::distance::services::return_type
<
Strategy,
Point,
typename point_type<MultiPolygon>::type
>::type return_type;
static inline return_type apply(Point const& point,
MultiPolygon const& multipolygon,
Strategy const& strategy)
{
// TODO: pass strategy
if (within::covered_by_point_geometry(point, multipolygon))
{
return 0;
}
return point_to_multigeometry
<
Point, MultiPolygon, Strategy, false
>::apply(point, multipolygon, strategy);
}
};
}} // namespace detail::distance
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
// Point-point
template <typename P1, typename P2, typename Strategy>
struct distance
<
P1, P2, Strategy, point_tag, point_tag,
strategy_tag_distance_point_point, false
> : detail::distance::point_to_point<P1, P2, Strategy>
{};
// Point-line version 2, where point-segment strategy is specified
template <typename Point, typename Linestring, typename Strategy>
struct distance
<
Point, Linestring, Strategy, point_tag, linestring_tag,
strategy_tag_distance_point_segment, false
> : detail::distance::point_to_range<Point, Linestring, closed, Strategy>
{};
// Point-ring , where point-segment strategy is specified
template <typename Point, typename Ring, typename Strategy>
struct distance
<
Point, Ring, Strategy, point_tag, ring_tag,
strategy_tag_distance_point_segment, false
> : detail::distance::point_to_ring
<
Point, Ring, closure<Ring>::value, Strategy
>
{};
// Point-polygon , where point-segment strategy is specified
template <typename Point, typename Polygon, typename Strategy>
struct distance
<
Point, Polygon, Strategy, point_tag, polygon_tag,
strategy_tag_distance_point_segment, false
> : detail::distance::point_to_polygon
<
Point, Polygon, closure<Polygon>::value, Strategy
>
{};
// Point-segment version 2, with point-segment strategy
template <typename Point, typename Segment, typename Strategy>
struct distance
<
Point, Segment, Strategy, point_tag, segment_tag,
strategy_tag_distance_point_segment, false
>
{
static inline typename strategy::distance::services::return_type
<
Strategy, Point, typename point_type<Segment>::type
>::type apply(Point const& point,
Segment const& segment,
Strategy const& strategy)
{
typename point_type<Segment>::type p[2];
geometry::detail::assign_point_from_index<0>(segment, p[0]);
geometry::detail::assign_point_from_index<1>(segment, p[1]);
boost::ignore_unused(strategy);
return strategy.apply(point, p[0], p[1]);
}
};
template <typename Point, typename Box, typename Strategy>
struct distance
<
Point, Box, Strategy, point_tag, box_tag,
strategy_tag_distance_point_box, false
>
{
static inline typename strategy::distance::services::return_type
<
Strategy, Point, typename point_type<Box>::type
>::type
apply(Point const& point, Box const& box, Strategy const& strategy)
{
boost::ignore_unused(strategy);
return strategy.apply(point, box);
}
};
template<typename Point, typename MultiPoint, typename Strategy>
struct distance
<
Point, MultiPoint, Strategy, point_tag, multi_point_tag,
strategy_tag_distance_point_point, false
> : detail::distance::point_to_multigeometry
<
Point, MultiPoint, Strategy
>
{};
template<typename Point, typename MultiLinestring, typename Strategy>
struct distance
<
Point, MultiLinestring, Strategy, point_tag, multi_linestring_tag,
strategy_tag_distance_point_segment, false
> : detail::distance::point_to_multigeometry
<
Point, MultiLinestring, Strategy
>
{};
template<typename Point, typename MultiPolygon, typename Strategy>
struct distance
<
Point, MultiPolygon, Strategy, point_tag, multi_polygon_tag,
strategy_tag_distance_point_segment, false
> : detail::distance::point_to_multigeometry
<
Point, MultiPolygon, Strategy
>
{};
template <typename Point, typename Linear, typename Strategy>
struct distance
<
Point, Linear, Strategy, point_tag, linear_tag,
strategy_tag_distance_point_segment, false
> : distance
<
Point, Linear, Strategy,
point_tag, typename tag<Linear>::type,
strategy_tag_distance_point_segment, false
>
{};
template <typename Point, typename Areal, typename Strategy>
struct distance
<
Point, Areal, Strategy, point_tag, areal_tag,
strategy_tag_distance_point_segment, false
> : distance
<
Point, Areal, Strategy,
point_tag, typename tag<Areal>::type,
strategy_tag_distance_point_segment, false
>
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_POINT_TO_GEOMETRY_HPP

View File

@@ -0,0 +1,130 @@
// 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_DISTANCE_RANGE_TO_GEOMETRY_RTREE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_RANGE_TO_GEOMETRY_RTREE_HPP
#include <iterator>
#include <utility>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/iterators/has_one_element.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/algorithms/dispatch/distance.hpp>
#include <boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp>
#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
#include <boost/geometry/algorithms/detail/distance/iterator_selector.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace distance
{
template
<
typename PointOrSegmentIterator,
typename Geometry,
typename Strategy
>
class point_or_segment_range_to_geometry_rtree
{
private:
typedef typename std::iterator_traits
<
PointOrSegmentIterator
>::value_type point_or_segment_type;
typedef iterator_selector<Geometry const> selector_type;
typedef detail::closest_feature::range_to_range_rtree range_to_range;
public:
typedef typename strategy::distance::services::return_type
<
Strategy,
typename point_type<point_or_segment_type>::type,
typename point_type<Geometry>::type
>::type return_type;
static inline return_type apply(PointOrSegmentIterator first,
PointOrSegmentIterator last,
Geometry const& geometry,
Strategy const& strategy)
{
namespace sds = strategy::distance::services;
BOOST_GEOMETRY_ASSERT( first != last );
if ( geometry::has_one_element(first, last) )
{
return dispatch::distance
<
point_or_segment_type, Geometry, Strategy
>::apply(*first, geometry, strategy);
}
typename sds::return_type
<
typename sds::comparable_type<Strategy>::type,
typename point_type<point_or_segment_type>::type,
typename point_type<Geometry>::type
>::type cd_min;
std::pair
<
point_or_segment_type,
typename selector_type::iterator_type
> closest_features
= range_to_range::apply(first,
last,
selector_type::begin(geometry),
selector_type::end(geometry),
sds::get_comparable
<
Strategy
>::apply(strategy),
cd_min);
return
is_comparable<Strategy>::value
?
cd_min
:
dispatch::distance
<
point_or_segment_type,
typename std::iterator_traits
<
typename selector_type::iterator_type
>::value_type,
Strategy
>::apply(closest_features.first,
*closest_features.second,
strategy);
}
};
}} // namespace detail::distance
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_RANGE_TO_GEOMETRY_RTREE_HPP

View File

@@ -0,0 +1,889 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2019 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
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_BOX_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_BOX_HPP
#include <cstddef>
#include <functional>
#include <vector>
#include <boost/core/ignore_unused.hpp>
#include <boost/mpl/if.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
#include <boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp>
#include <boost/geometry/algorithms/detail/disjoint/segment_box.hpp>
#include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/algorithms/dispatch/distance.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/util/calculation_type.hpp>
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/has_nan_coordinate.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/strategies/disjoint.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/tags.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace distance
{
// TODO: Take strategy
template <typename Segment, typename Box>
inline bool intersects_segment_box(Segment const& segment, Box const& box)
{
typedef typename strategy::disjoint::services::default_strategy
<
Segment, Box
>::type strategy_type;
return ! detail::disjoint::disjoint_segment_box::apply(segment, box,
strategy_type());
}
template
<
typename Segment,
typename Box,
typename Strategy,
bool UsePointBoxStrategy = false
>
class segment_to_box_2D_generic
{
private:
typedef typename point_type<Segment>::type segment_point;
typedef typename point_type<Box>::type box_point;
typedef typename strategy::distance::services::comparable_type
<
typename Strategy::distance_ps_strategy::type
>::type comparable_strategy;
typedef detail::closest_feature::point_to_point_range
<
segment_point,
std::vector<box_point>,
open,
comparable_strategy
> point_to_point_range;
typedef typename strategy::distance::services::return_type
<
comparable_strategy, segment_point, box_point
>::type comparable_return_type;
public:
typedef typename strategy::distance::services::return_type
<
Strategy, segment_point, box_point
>::type return_type;
static inline return_type apply(Segment const& segment,
Box const& box,
Strategy const& strategy,
bool check_intersection = true)
{
if (check_intersection && intersects_segment_box(segment, box))
{
return 0;
}
comparable_strategy cstrategy =
strategy::distance::services::get_comparable
<
typename Strategy::distance_ps_strategy::type
>::apply(strategy.get_distance_ps_strategy());
// get segment points
segment_point p[2];
detail::assign_point_from_index<0>(segment, p[0]);
detail::assign_point_from_index<1>(segment, p[1]);
// get box points
std::vector<box_point> box_points(4);
detail::assign_box_corners_oriented<true>(box, box_points);
comparable_return_type cd[6];
for (unsigned int i = 0; i < 4; ++i)
{
cd[i] = cstrategy.apply(box_points[i], p[0], p[1]);
}
std::pair
<
typename std::vector<box_point>::const_iterator,
typename std::vector<box_point>::const_iterator
> bit_min[2];
bit_min[0] = point_to_point_range::apply(p[0],
box_points.begin(),
box_points.end(),
cstrategy,
cd[4]);
bit_min[1] = point_to_point_range::apply(p[1],
box_points.begin(),
box_points.end(),
cstrategy,
cd[5]);
unsigned int imin = 0;
for (unsigned int i = 1; i < 6; ++i)
{
if (cd[i] < cd[imin])
{
imin = i;
}
}
if (BOOST_GEOMETRY_CONDITION(is_comparable<Strategy>::value))
{
return cd[imin];
}
if (imin < 4)
{
return strategy.get_distance_ps_strategy().apply(box_points[imin], p[0], p[1]);
}
else
{
unsigned int bimin = imin - 4;
return strategy.get_distance_ps_strategy().apply(p[bimin],
*bit_min[bimin].first,
*bit_min[bimin].second);
}
}
};
template
<
typename Segment,
typename Box,
typename Strategy
>
class segment_to_box_2D_generic<Segment, Box, Strategy, true>
{
private:
typedef typename point_type<Segment>::type segment_point;
typedef typename point_type<Box>::type box_point;
typedef typename strategy::distance::services::comparable_type
<
Strategy
>::type comparable_strategy;
typedef typename strategy::distance::services::return_type
<
comparable_strategy, segment_point, box_point
>::type comparable_return_type;
typedef typename detail::distance::default_strategy
<
segment_point, Box
>::type point_box_strategy;
typedef typename strategy::distance::services::comparable_type
<
point_box_strategy
>::type point_box_comparable_strategy;
public:
typedef typename strategy::distance::services::return_type
<
Strategy, segment_point, box_point
>::type return_type;
static inline return_type apply(Segment const& segment,
Box const& box,
Strategy const& strategy,
bool check_intersection = true)
{
if (check_intersection && intersects_segment_box(segment, box))
{
return 0;
}
comparable_strategy cstrategy =
strategy::distance::services::get_comparable
<
Strategy
>::apply(strategy);
boost::ignore_unused(cstrategy);
// get segment points
segment_point p[2];
detail::assign_point_from_index<0>(segment, p[0]);
detail::assign_point_from_index<1>(segment, p[1]);
// get box points
std::vector<box_point> box_points(4);
detail::assign_box_corners_oriented<true>(box, box_points);
comparable_return_type cd[6];
for (unsigned int i = 0; i < 4; ++i)
{
cd[i] = cstrategy.apply(box_points[i], p[0], p[1]);
}
point_box_comparable_strategy pb_cstrategy;
boost::ignore_unused(pb_cstrategy);
cd[4] = pb_cstrategy.apply(p[0], box);
cd[5] = pb_cstrategy.apply(p[1], box);
unsigned int imin = 0;
for (unsigned int i = 1; i < 6; ++i)
{
if (cd[i] < cd[imin])
{
imin = i;
}
}
if (is_comparable<Strategy>::value)
{
return cd[imin];
}
if (imin < 4)
{
strategy.apply(box_points[imin], p[0], p[1]);
}
else
{
return point_box_strategy().apply(p[imin - 4], box);
}
}
};
template
<
typename ReturnType,
typename SegmentPoint,
typename BoxPoint,
typename SBStrategy
>
class segment_to_box_2D
{
private:
template <typename Result>
struct cast_to_result
{
template <typename T>
static inline Result apply(T const& t)
{
return boost::numeric_cast<Result>(t);
}
};
template <typename T, bool IsLess /* true */>
struct compare_less_equal
{
typedef compare_less_equal<T, !IsLess> other;
template <typename T1, typename T2>
inline bool operator()(T1 const& t1, T2 const& t2) const
{
return std::less_equal<T>()(cast_to_result<T>::apply(t1),
cast_to_result<T>::apply(t2));
}
};
template <typename T>
struct compare_less_equal<T, false>
{
typedef compare_less_equal<T, true> other;
template <typename T1, typename T2>
inline bool operator()(T1 const& t1, T2 const& t2) const
{
return std::greater_equal<T>()(cast_to_result<T>::apply(t1),
cast_to_result<T>::apply(t2));
}
};
template <typename LessEqual>
struct other_compare
{
typedef typename LessEqual::other type;
};
// it is assumed here that p0 lies to the right of the box (so the
// entire segment lies to the right of the box)
template <typename LessEqual>
struct right_of_box
{
static inline ReturnType apply(SegmentPoint const& p0,
SegmentPoint const& p1,
BoxPoint const& bottom_right,
BoxPoint const& top_right,
SBStrategy const& sb_strategy)
{
boost::ignore_unused(sb_strategy);
// the implementation below is written for non-negative slope
// segments
//
// for negative slope segments swap the roles of bottom_right
// and top_right and use greater_equal instead of less_equal.
typedef cast_to_result<ReturnType> cast;
LessEqual less_equal;
typename SBStrategy::distance_ps_strategy::type ps_strategy =
sb_strategy.get_distance_ps_strategy();
if (less_equal(geometry::get<1>(bottom_right), geometry::get<1>(p0)))
{
//if p0 is in box's band
if (less_equal(geometry::get<1>(p0), geometry::get<1>(top_right)))
{
// segment & crosses band (TODO:merge with box-box dist)
if (math::equals(geometry::get<0>(p0), geometry::get<0>(p1)))
{
SegmentPoint high = geometry::get<1>(p1) > geometry::get<1>(p0) ? p1 : p0;
if (less_equal(geometry::get<1>(high), geometry::get<1>(top_right)))
{
return cast::apply(ps_strategy.apply(high, bottom_right, top_right));
}
return cast::apply(ps_strategy.apply(top_right, p0, p1));
}
return cast::apply(ps_strategy.apply(p0, bottom_right, top_right));
}
// distance is realized between the top-right
// corner of the box and the segment
return cast::apply(ps_strategy.apply(top_right, p0, p1));
}
else
{
// distance is realized between the bottom-right
// corner of the box and the segment
return cast::apply(ps_strategy.apply(bottom_right, p0, p1));
}
}
};
// it is assumed here that p0 lies above the box (so the
// entire segment lies above the box)
template <typename LessEqual>
struct above_of_box
{
static inline ReturnType apply(SegmentPoint const& p0,
SegmentPoint const& p1,
BoxPoint const& top_left,
SBStrategy const& sb_strategy)
{
boost::ignore_unused(sb_strategy);
return apply(p0, p1, p0, top_left, sb_strategy);
}
static inline ReturnType apply(SegmentPoint const& p0,
SegmentPoint const& p1,
SegmentPoint const& p_max,
BoxPoint const& top_left,
SBStrategy const& sb_strategy)
{
boost::ignore_unused(sb_strategy);
typedef cast_to_result<ReturnType> cast;
LessEqual less_equal;
// p0 is above the upper segment of the box (and inside its band)
// then compute the vertical (i.e. meridian for spherical) distance
if (less_equal(geometry::get<0>(top_left), geometry::get<0>(p_max)))
{
ReturnType diff =
sb_strategy.get_distance_ps_strategy().vertical_or_meridian(
geometry::get_as_radian<1>(p_max),
geometry::get_as_radian<1>(top_left));
return strategy::distance::services::result_from_distance
<
SBStrategy, SegmentPoint, BoxPoint
>::apply(sb_strategy, math::abs(diff));
}
// p0 is to the left of the box, but p1 is above the box
// in this case the distance is realized between the
// top-left corner of the box and the segment
return cast::apply(sb_strategy.get_distance_ps_strategy().
apply(top_left, p0, p1));
}
};
template <typename LessEqual>
struct check_right_left_of_box
{
static inline bool apply(SegmentPoint const& p0,
SegmentPoint const& p1,
BoxPoint const& top_left,
BoxPoint const& top_right,
BoxPoint const& bottom_left,
BoxPoint const& bottom_right,
SBStrategy const& sb_strategy,
ReturnType& result)
{
// p0 lies to the right of the box
if (geometry::get<0>(p0) >= geometry::get<0>(top_right))
{
result = right_of_box
<
LessEqual
>::apply(p0, p1, bottom_right, top_right,
sb_strategy);
return true;
}
// p1 lies to the left of the box
if (geometry::get<0>(p1) <= geometry::get<0>(bottom_left))
{
result = right_of_box
<
typename other_compare<LessEqual>::type
>::apply(p1, p0, top_left, bottom_left,
sb_strategy);
return true;
}
return false;
}
};
template <typename LessEqual>
struct check_above_below_of_box
{
static inline bool apply(SegmentPoint const& p0,
SegmentPoint const& p1,
BoxPoint const& top_left,
BoxPoint const& top_right,
BoxPoint const& bottom_left,
BoxPoint const& bottom_right,
SBStrategy const& sb_strategy,
ReturnType& result)
{
typedef compare_less_equal<ReturnType, false> GreaterEqual;
// the segment lies below the box
if (geometry::get<1>(p1) < geometry::get<1>(bottom_left))
{
result = sb_strategy.template segment_below_of_box
<
LessEqual,
ReturnType
>(p0, p1,
top_left, top_right,
bottom_left, bottom_right);
return true;
}
// the segment lies above the box
if (geometry::get<1>(p0) > geometry::get<1>(top_right))
{
result = (std::min)(above_of_box
<
LessEqual
>::apply(p0, p1, top_left, sb_strategy),
above_of_box
<
GreaterEqual
>::apply(p1, p0, top_right, sb_strategy));
return true;
}
return false;
}
};
struct check_generic_position
{
static inline bool apply(SegmentPoint const& p0,
SegmentPoint const& p1,
BoxPoint const& corner1,
BoxPoint const& corner2,
SBStrategy const& sb_strategy,
ReturnType& result)
{
typedef typename geometry::strategy::side::services::default_strategy
<
typename geometry::cs_tag<SegmentPoint>::type
>::type side;
typedef cast_to_result<ReturnType> cast;
ReturnType diff1 = cast::apply(geometry::get<1>(p1))
- cast::apply(geometry::get<1>(p0));
typename SBStrategy::distance_ps_strategy::type ps_strategy =
sb_strategy.get_distance_ps_strategy();
int sign = diff1 < 0 ? -1 : 1;
if (side::apply(p0, p1, corner1) * sign < 0)
{
result = cast::apply(ps_strategy.apply(corner1, p0, p1));
return true;
}
if (side::apply(p0, p1, corner2) * sign > 0)
{
result = cast::apply(ps_strategy.apply(corner2, p0, p1));
return true;
}
return false;
}
};
static inline ReturnType
non_negative_slope_segment(SegmentPoint const& p0,
SegmentPoint const& p1,
BoxPoint const& top_left,
BoxPoint const& top_right,
BoxPoint const& bottom_left,
BoxPoint const& bottom_right,
SBStrategy const& sb_strategy)
{
typedef compare_less_equal<ReturnType, true> less_equal;
// assert that the segment has non-negative slope
BOOST_GEOMETRY_ASSERT( ( math::equals(geometry::get<0>(p0), geometry::get<0>(p1))
&& geometry::get<1>(p0) < geometry::get<1>(p1))
||
( geometry::get<0>(p0) < geometry::get<0>(p1)
&& geometry::get<1>(p0) <= geometry::get<1>(p1) )
|| geometry::has_nan_coordinate(p0)
|| geometry::has_nan_coordinate(p1));
ReturnType result(0);
if (check_right_left_of_box
<
less_equal
>::apply(p0, p1,
top_left, top_right, bottom_left, bottom_right,
sb_strategy, result))
{
return result;
}
if (check_above_below_of_box
<
less_equal
>::apply(p0, p1,
top_left, top_right, bottom_left, bottom_right,
sb_strategy, result))
{
return result;
}
if (check_generic_position::apply(p0, p1,
top_left, bottom_right,
sb_strategy, result))
{
return result;
}
// in all other cases the box and segment intersect, so return 0
return result;
}
static inline ReturnType
negative_slope_segment(SegmentPoint const& p0,
SegmentPoint const& p1,
BoxPoint const& top_left,
BoxPoint const& top_right,
BoxPoint const& bottom_left,
BoxPoint const& bottom_right,
SBStrategy const& sb_strategy)
{
typedef compare_less_equal<ReturnType, false> greater_equal;
// assert that the segment has negative slope
BOOST_GEOMETRY_ASSERT( ( geometry::get<0>(p0) < geometry::get<0>(p1)
&& geometry::get<1>(p0) > geometry::get<1>(p1) )
|| geometry::has_nan_coordinate(p0)
|| geometry::has_nan_coordinate(p1) );
ReturnType result(0);
if (check_right_left_of_box
<
greater_equal
>::apply(p0, p1,
bottom_left, bottom_right, top_left, top_right,
sb_strategy, result))
{
return result;
}
if (check_above_below_of_box
<
greater_equal
>::apply(p1, p0,
top_right, top_left, bottom_right, bottom_left,
sb_strategy, result))
{
return result;
}
if (check_generic_position::apply(p0, p1,
bottom_left, top_right,
sb_strategy, result))
{
return result;
}
// in all other cases the box and segment intersect, so return 0
return result;
}
public:
static inline ReturnType apply(SegmentPoint const& p0,
SegmentPoint const& p1,
BoxPoint const& top_left,
BoxPoint const& top_right,
BoxPoint const& bottom_left,
BoxPoint const& bottom_right,
SBStrategy const& sb_strategy)
{
BOOST_GEOMETRY_ASSERT( geometry::less<SegmentPoint>()(p0, p1)
|| geometry::has_nan_coordinate(p0)
|| geometry::has_nan_coordinate(p1) );
if (geometry::get<0>(p0) < geometry::get<0>(p1)
&& geometry::get<1>(p0) > geometry::get<1>(p1))
{
return negative_slope_segment(p0, p1,
top_left, top_right,
bottom_left, bottom_right,
sb_strategy);
}
return non_negative_slope_segment(p0, p1,
top_left, top_right,
bottom_left, bottom_right,
sb_strategy);
}
template <typename LessEqual>
static inline ReturnType call_above_of_box(SegmentPoint const& p0,
SegmentPoint const& p1,
SegmentPoint const& p_max,
BoxPoint const& top_left,
SBStrategy const& sb_strategy)
{
return above_of_box<LessEqual>::apply(p0, p1, p_max, top_left, sb_strategy);
}
template <typename LessEqual>
static inline ReturnType call_above_of_box(SegmentPoint const& p0,
SegmentPoint const& p1,
BoxPoint const& top_left,
SBStrategy const& sb_strategy)
{
return above_of_box<LessEqual>::apply(p0, p1, top_left, sb_strategy);
}
};
//=========================================================================
template
<
typename Segment,
typename Box,
typename std::size_t Dimension,
typename SBStrategy
>
class segment_to_box
: not_implemented<Segment, Box>
{};
template
<
typename Segment,
typename Box,
typename SBStrategy
>
class segment_to_box<Segment, Box, 2, SBStrategy>
{
private:
typedef typename point_type<Segment>::type segment_point;
typedef typename point_type<Box>::type box_point;
typedef typename strategy::distance::services::comparable_type
<
SBStrategy
>::type ps_comparable_strategy;
typedef typename strategy::distance::services::return_type
<
ps_comparable_strategy, segment_point, box_point
>::type comparable_return_type;
public:
typedef typename strategy::distance::services::return_type
<
SBStrategy, segment_point, box_point
>::type return_type;
static inline return_type apply(Segment const& segment,
Box const& box,
SBStrategy const& sb_strategy)
{
segment_point p[2];
detail::assign_point_from_index<0>(segment, p[0]);
detail::assign_point_from_index<1>(segment, p[1]);
if (detail::equals::equals_point_point(p[0], p[1],
sb_strategy.get_equals_point_point_strategy()))
{
typedef typename boost::mpl::if_
<
boost::is_same
<
ps_comparable_strategy,
SBStrategy
>,
typename strategy::distance::services::comparable_type
<
typename detail::distance::default_strategy
<
segment_point, Box
>::type
>::type,
typename detail::distance::default_strategy
<
segment_point, Box
>::type
>::type point_box_strategy_type;
return dispatch::distance
<
segment_point,
Box,
point_box_strategy_type
>::apply(p[0], box, point_box_strategy_type());
}
box_point top_left, top_right, bottom_left, bottom_right;
detail::assign_box_corners(box, bottom_left, bottom_right,
top_left, top_right);
SBStrategy::mirror(p[0], p[1],
bottom_left, bottom_right,
top_left, top_right);
if (geometry::less<segment_point>()(p[0], p[1]))
{
return segment_to_box_2D
<
return_type,
segment_point,
box_point,
SBStrategy
>::apply(p[0], p[1],
top_left, top_right, bottom_left, bottom_right,
sb_strategy);
}
else
{
return segment_to_box_2D
<
return_type,
segment_point,
box_point,
SBStrategy
>::apply(p[1], p[0],
top_left, top_right, bottom_left, bottom_right,
sb_strategy);
}
}
};
}} // namespace detail::distance
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
template <typename Segment, typename Box, typename Strategy>
struct distance
<
Segment, Box, Strategy, segment_tag, box_tag,
strategy_tag_distance_segment_box, false
>
{
typedef typename strategy::distance::services::return_type
<
Strategy,
typename point_type<Segment>::type,
typename point_type<Box>::type
>::type return_type;
static inline return_type apply(Segment const& segment,
Box const& box,
Strategy const& strategy)
{
assert_dimension_equal<Segment, Box>();
return detail::distance::segment_to_box
<
Segment,
Box,
dimension<Segment>::value,
Strategy
>::apply(segment, box, strategy);
}
};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_BOX_HPP

View File

@@ -0,0 +1,152 @@
// 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_DISTANCE_SEGMENT_TO_SEGMENT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_SEGMENT_HPP
#include <algorithm>
#include <iterator>
#include <boost/core/addressof.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/tags.hpp>
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/intersects.hpp>
#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
#include <boost/geometry/algorithms/dispatch/distance.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace distance
{
// compute segment-segment distance
template<typename Segment1, typename Segment2, typename Strategy>
class segment_to_segment
{
private:
typedef typename strategy::distance::services::comparable_type
<
Strategy
>::type comparable_strategy;
typedef typename strategy::distance::services::return_type
<
comparable_strategy,
typename point_type<Segment1>::type,
typename point_type<Segment2>::type
>::type comparable_return_type;
public:
typedef typename strategy::distance::services::return_type
<
Strategy,
typename point_type<Segment1>::type,
typename point_type<Segment2>::type
>::type return_type;
static inline return_type
apply(Segment1 const& segment1, Segment2 const& segment2,
Strategy const& strategy)
{
if (geometry::intersects(segment1, segment2))
{
return 0;
}
typename point_type<Segment1>::type p[2];
detail::assign_point_from_index<0>(segment1, p[0]);
detail::assign_point_from_index<1>(segment1, p[1]);
typename point_type<Segment2>::type q[2];
detail::assign_point_from_index<0>(segment2, q[0]);
detail::assign_point_from_index<1>(segment2, q[1]);
comparable_strategy cstrategy =
strategy::distance::services::get_comparable
<
Strategy
>::apply(strategy);
comparable_return_type d[4];
d[0] = cstrategy.apply(q[0], p[0], p[1]);
d[1] = cstrategy.apply(q[1], p[0], p[1]);
d[2] = cstrategy.apply(p[0], q[0], q[1]);
d[3] = cstrategy.apply(p[1], q[0], q[1]);
std::size_t imin = std::distance(boost::addressof(d[0]),
std::min_element(d, d + 4));
if (BOOST_GEOMETRY_CONDITION(is_comparable<Strategy>::value))
{
return d[imin];
}
switch (imin)
{
case 0:
return strategy.apply(q[0], p[0], p[1]);
case 1:
return strategy.apply(q[1], p[0], p[1]);
case 2:
return strategy.apply(p[0], q[0], q[1]);
default:
return strategy.apply(p[1], q[0], q[1]);
}
}
};
}} // namespace detail::distance
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
// segment-segment
template <typename Segment1, typename Segment2, typename Strategy>
struct distance
<
Segment1, Segment2, Strategy, segment_tag, segment_tag,
strategy_tag_distance_point_segment, false
>
: detail::distance::segment_to_segment<Segment1, Segment2, Strategy>
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_SEGMENT_HPP