From 22142c9040c91fc77b2847542978bd24df271c74 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Thu, 8 May 2014 14:52:13 +0300 Subject: [PATCH] [distance] add distance code for multi-to-multi geometry combinations and dispatch specializations; some of the code in this file originated from multi/algorithms/distance.hpp --- .../detail/distance/multi_to_multi.hpp | 248 ++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 include/boost/geometry/algorithms/detail/distance/multi_to_multi.hpp diff --git a/include/boost/geometry/algorithms/detail/distance/multi_to_multi.hpp b/include/boost/geometry/algorithms/detail/distance/multi_to_multi.hpp new file mode 100644 index 000000000..0be5b8641 --- /dev/null +++ b/include/boost/geometry/algorithms/detail/distance/multi_to_multi.hpp @@ -0,0 +1,248 @@ +// 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_MULTI_TO_MULTI_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTI_TO_MULTI_HPP + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include + +#include +#include + + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace distance +{ + + + +template +struct distance_multi_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(Multi1 const& multi1, + Multi2 const& multi2, 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(multi1); + it != boost::end(multi1); + ++it, first = false) + { + return_type cdist = + dispatch::splitted_dispatch::distance_single_to_multi + < + typename range_value::type, + Multi2, + comparable_strategy, + typename tag::type>::type, + typename tag::type, + typename strategy::distance::services::tag + < + comparable_strategy + >::type + >::apply(*it, multi2, 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, + Multi1, + Multi2 + >::apply(min_cdist); + } +}; + + +}} // namespace detail::distance +#endif // DOXYGEN_NO_DETAIL + + + +#ifndef DOXYGEN_NO_DISPATCH +namespace dispatch +{ + + +namespace splitted_dispatch +{ + + +template +< + typename MultiGeometry1, + typename MultiGeometry2, + typename Strategy, + typename Tag1, + typename Tag2, + typename StrategyTag +> +struct distance_multi_to_multi + : not_implemented +{}; + + + +template +< + typename MultiPoint, + typename MultiPolygon, + typename Strategy +> +struct distance_multi_to_multi + < + MultiPoint, MultiPolygon, Strategy, + multi_point_tag, multi_polygon_tag, + strategy_tag_distance_point_segment + > : detail::distance::distance_multi_to_multi_generic + < + MultiPoint, MultiPolygon, Strategy + > +{}; + + + +template +< + typename MultiLinestring1, + typename MultiLinestring2, + typename Strategy +> +struct distance_multi_to_multi + < + MultiLinestring1, MultiLinestring2, Strategy, + multi_linestring_tag, multi_linestring_tag, + strategy_tag_distance_point_segment + > : detail::distance::geometry_to_geometry_rtree + < + MultiLinestring1, MultiLinestring2, Strategy + > +{}; + + +template +< + typename MultiLinestring, + typename MultiPolygon, + typename Strategy +> +struct distance_multi_to_multi + < + MultiLinestring, MultiPolygon, Strategy, + multi_linestring_tag, multi_polygon_tag, + strategy_tag_distance_point_segment + > : detail::distance::geometry_to_geometry_rtree + < + MultiLinestring, MultiPolygon, Strategy + > +{}; + + +template +struct distance_multi_to_multi + < + MultiPolygon1, MultiPolygon2, Strategy, + multi_polygon_tag, multi_polygon_tag, + strategy_tag_distance_point_segment + > : detail::distance::geometry_to_geometry_rtree + < + MultiPolygon1, MultiPolygon2, Strategy + > +{}; + + +} // namespace splitted_dispatch + + + + +template +< + typename MultiGeometry1, + typename MultiGeometry2, + typename Strategy, + typename StrategyTag +> +struct distance + < + MultiGeometry1, MultiGeometry2, Strategy, multi_tag, multi_tag, + StrategyTag, false + > : splitted_dispatch::distance_multi_to_multi + < + MultiGeometry1, MultiGeometry2, Strategy, + typename geometry::tag::type, + typename geometry::tag::type, + StrategyTag + > +{}; + + + +} // namespace dispatch +#endif // DOXYGEN_NO_DISPATCH + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTI_TO_MULTI_HPP