diff --git a/include/boost/geometry/algorithms/detail/distance/single_to_multi.hpp b/include/boost/geometry/algorithms/detail/distance/single_to_multi.hpp new file mode 100644 index 000000000..6b43144ac --- /dev/null +++ b/include/boost/geometry/algorithms/detail/distance/single_to_multi.hpp @@ -0,0 +1,480 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2014 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2014 Mateusz Loskot, London, UK. + +// This file was modified by Oracle on 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_SINGLE_TO_MULTI_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SINGLE_TO_MULTI_HPP + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include + +#include + +// includes needed from multi.hpp -- start +#include +#include +#include +#include + +#include +#include +#include + +#include +// includes needed from multi.hpp -- end + +#include + + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace distance +{ + + +template +struct distance_single_to_multi_generic +{ + typedef typename strategy::distance::services::comparable_type + < + Strategy + >::type comparable_strategy; + + typedef typename strategy::distance::services::return_type + < + Strategy, + typename point_type::type, + typename point_type::type + >::type return_type; + + static inline return_type apply(Geometry const& geometry, + MultiGeometry const& multi, + Strategy const& strategy) + { + return_type min_cdist = return_type(); + bool first = true; + + comparable_strategy cstrategy = + strategy::distance::services::get_comparable + < + Strategy + >::apply(strategy); + + for (typename range_iterator::type it = boost::begin(multi); + it != boost::end(multi); + ++it, first = false) + { + return_type cdist = dispatch::distance + < + Geometry, + typename range_value::type, + comparable_strategy + >::apply(geometry, *it, cstrategy); + + if (first || cdist < min_cdist) + { + min_cdist = cdist; + } + if ( geometry::math::equals(min_cdist, 0) ) + { + break; + } + } + + return strategy::distance::services::comparable_to_regular + < + comparable_strategy, Strategy, Geometry, MultiGeometry + >::apply(min_cdist); + } +}; + + + +template +struct distance_multi_to_single_generic +{ + typedef typename strategy::distance::services::return_type + < + Strategy, + typename point_type::type, + typename point_type::type + >::type return_type; + + static inline return_type apply(MultiGeometry const& multi, + Geometry const& geometry, + Strategy const& strategy) + { + return distance_single_to_multi_generic + < + Geometry, MultiGeometry, Strategy + >::apply(geometry, multi, strategy); + } +}; + + + + +}} // namespace detail::distance +#endif // DOXYGEN_NO_DETAIL + + + +#ifndef DOXYGEN_NO_DISPATCH +namespace dispatch +{ + + +namespace splitted_dispatch +{ + + +template +< + typename Geometry, + typename MultiGeometry, + typename Strategy, + typename GeometryTag, + typename MultiGeometryTag, + typename StrategyTag +> +struct distance_single_to_multi + : not_implemented +{}; + + + +template +struct distance_single_to_multi + < + Point, MultiPoint, Strategy, + point_tag, multi_point_tag, + strategy_tag_distance_point_point + > : detail::distance::distance_single_to_multi_generic + < + Point, MultiPoint, Strategy + > +{}; + + + +template +struct distance_single_to_multi + < + Point, MultiLinestring, Strategy, + point_tag, multi_linestring_tag, + strategy_tag_distance_point_segment + > : detail::distance::distance_single_to_multi_generic + < + Point, MultiLinestring, Strategy + > +{}; + + + +template +struct distance_single_to_multi + < + Point, MultiPolygon, Strategy, + point_tag, multi_polygon_tag, + strategy_tag_distance_point_segment + > : detail::distance::distance_single_to_multi_generic + < + Point, MultiPolygon, Strategy + > +{}; + + + +template +struct distance_single_to_multi + < + Linestring, MultiLinestring, Strategy, + linestring_tag, multi_linestring_tag, + strategy_tag_distance_point_segment + > : detail::distance::geometry_to_geometry_rtree + < + Linestring, MultiLinestring, Strategy + > +{}; + + + +template +struct distance_single_to_multi + < + Linestring, MultiPolygon, Strategy, + linestring_tag, multi_polygon_tag, + strategy_tag_distance_point_segment + > : detail::distance::geometry_to_geometry_rtree + < + Linestring, MultiPolygon, Strategy + > +{}; + + + +template +struct distance_single_to_multi + < + Polygon, MultiPoint, Strategy, + polygon_tag, multi_point_tag, + strategy_tag_distance_point_segment + > : detail::distance::distance_single_to_multi_generic + < + Polygon, MultiPoint, Strategy + > +{}; + + + +template +struct distance_single_to_multi + < + Polygon, MultiLinestring, Strategy, + polygon_tag, multi_linestring_tag, + strategy_tag_distance_point_segment + > : detail::distance::geometry_to_geometry_rtree + < + Polygon, MultiLinestring, Strategy + > +{}; + + + +template +struct distance_single_to_multi + < + Polygon, MultiPolygon, Strategy, + polygon_tag, multi_polygon_tag, + strategy_tag_distance_point_segment + > : detail::distance::geometry_to_geometry_rtree + < + Polygon, MultiPolygon, Strategy + > +{}; + + + +template +struct distance_single_to_multi + < + MultiLinestring, Ring, Strategy, + multi_linestring_tag, ring_tag, + strategy_tag_distance_point_segment + > : detail::distance::geometry_to_geometry_rtree + < + MultiLinestring, Ring, Strategy + > +{}; + + +template +struct distance_single_to_multi + < + MultiPolygon, Ring, Strategy, + multi_polygon_tag, ring_tag, + strategy_tag_distance_point_segment + > : detail::distance::geometry_to_geometry_rtree + < + MultiPolygon, Ring, Strategy + > +{}; + + + +template +< + typename MultiGeometry, + typename Geometry, + typename Strategy, + typename MultiGeometryTag, + typename GeometryTag, + typename StrategyTag +> +struct distance_multi_to_single + : not_implemented +{}; + + + +template +< + typename MultiPoint, + typename Segment, + typename Strategy +> +struct distance_multi_to_single + < + MultiPoint, Segment, Strategy, + multi_point_tag, segment_tag, + strategy_tag_distance_point_segment + > : detail::distance::distance_multi_to_single_generic + < + MultiPoint, Segment, Strategy + > +{}; + + + +template +< + typename MultiPoint, + typename Box, + typename Strategy +> +struct distance_multi_to_single + < + MultiPoint, Box, Strategy, + multi_point_tag, box_tag, + strategy_tag_distance_point_box + > : detail::distance::distance_multi_to_single_generic + < + MultiPoint, Box, Strategy + > +{}; + + +template +struct distance_multi_to_single + < + MultiLinestring, Segment, Strategy, + multi_linestring_tag, segment_tag, + strategy_tag_distance_point_segment + > : detail::distance::distance_multi_to_single_generic + < + MultiLinestring, Segment, Strategy + > +{}; + + + +template +struct distance_multi_to_single + < + MultiLinestring, Box, Strategy, + multi_linestring_tag, box_tag, + strategy_tag_distance_point_segment + > : detail::distance::distance_multi_to_single_generic + < + MultiLinestring, Box, Strategy + > +{}; + + + +template +struct distance_multi_to_single + < + MultiPolygon, Segment, Strategy, + multi_polygon_tag, segment_tag, + strategy_tag_distance_point_segment + > : detail::distance::distance_multi_to_single_generic + < + MultiPolygon, Segment, Strategy + > +{}; + + + +template +struct distance_multi_to_single + < + MultiPolygon, Box, Strategy, + multi_polygon_tag, box_tag, + strategy_tag_distance_point_segment + > : detail::distance::distance_multi_to_single_generic + < + MultiPolygon, Box, Strategy + > +{}; + + +} // namespace splitted_dispatch + + +template +< + typename Geometry, + typename MultiGeometry, + typename Strategy, + typename GeometryTag, + typename StrategyTag +> +struct distance + < + Geometry, MultiGeometry, Strategy, GeometryTag, multi_tag, + StrategyTag, false + > : splitted_dispatch::distance_single_to_multi + < + Geometry, MultiGeometry, Strategy, + GeometryTag, typename tag::type, + StrategyTag + > +{}; + + + +template +< + typename MultiGeometry, + typename Geometry, + typename Strategy, + typename GeometryTag, + typename StrategyTag +> +struct distance + < + MultiGeometry, Geometry, Strategy, multi_tag, GeometryTag, + StrategyTag, false + > : splitted_dispatch::distance_multi_to_single + < + MultiGeometry, Geometry, Strategy, + typename tag::type, GeometryTag, + StrategyTag + > +{}; + + + +} // namespace dispatch +#endif // DOXYGEN_NO_DISPATCH + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SINGLE_TO_MULTI_HPP