summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2017-09-13 11:08:07 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2017-09-13 11:09:00 +0900
commitb5c87084afaef42b2d058f68091be31988a6a874 (patch)
treeadef9a65870a41181687e11d57fdf98e7629de3c /boost/geometry/algorithms
parent34bd32e225e2a8a94104489b31c42e5801cc1f4a (diff)
downloadboost-b5c87084afaef42b2d058f68091be31988a6a874.tar.gz
boost-b5c87084afaef42b2d058f68091be31988a6a874.tar.bz2
boost-b5c87084afaef42b2d058f68091be31988a6a874.zip
Imported Upstream version 1.64.0upstream/1.64.0
Change-Id: Id9212edd016dd55f21172c427aa7894d1d24148b Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'boost/geometry/algorithms')
-rw-r--r--boost/geometry/algorithms/area.hpp7
-rw-r--r--boost/geometry/algorithms/buffer.hpp10
-rw-r--r--boost/geometry/algorithms/centroid.hpp7
-rw-r--r--boost/geometry/algorithms/covered_by.hpp31
-rw-r--r--boost/geometry/algorithms/crosses.hpp141
-rw-r--r--boost/geometry/algorithms/detail/azimuth.hpp25
-rw-r--r--boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp57
-rw-r--r--boost/geometry/algorithms/detail/buffer/buffer_policies.hpp6
-rw-r--r--boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp49
-rw-r--r--boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp12
-rw-r--r--boost/geometry/algorithms/detail/calculate_sum.hpp6
-rw-r--r--boost/geometry/algorithms/detail/disjoint/areal_areal.hpp74
-rw-r--r--boost/geometry/algorithms/detail/disjoint/box_box.hpp16
-rw-r--r--boost/geometry/algorithms/detail/disjoint/interface.hpp157
-rw-r--r--boost/geometry/algorithms/detail/disjoint/linear_areal.hpp87
-rw-r--r--boost/geometry/algorithms/detail/disjoint/linear_linear.hpp38
-rw-r--r--boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp11
-rw-r--r--boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp88
-rw-r--r--boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp25
-rw-r--r--boost/geometry/algorithms/detail/disjoint/point_box.hpp28
-rw-r--r--boost/geometry/algorithms/detail/disjoint/point_geometry.hpp9
-rw-r--r--boost/geometry/algorithms/detail/disjoint/point_point.hpp18
-rw-r--r--boost/geometry/algorithms/detail/disjoint/segment_box.hpp242
-rw-r--r--boost/geometry/algorithms/detail/envelope/box.hpp17
-rw-r--r--boost/geometry/algorithms/detail/envelope/implementation.hpp13
-rw-r--r--boost/geometry/algorithms/detail/envelope/interface.hpp124
-rw-r--r--boost/geometry/algorithms/detail/envelope/linear.hpp28
-rw-r--r--boost/geometry/algorithms/detail/envelope/multipoint.hpp13
-rw-r--r--boost/geometry/algorithms/detail/envelope/point.hpp15
-rw-r--r--boost/geometry/algorithms/detail/envelope/range.hpp44
-rw-r--r--boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp21
-rw-r--r--boost/geometry/algorithms/detail/envelope/segment.hpp209
-rw-r--r--boost/geometry/algorithms/detail/equals/collect_vectors.hpp97
-rw-r--r--boost/geometry/algorithms/detail/expand/box.hpp17
-rw-r--r--boost/geometry/algorithms/detail/expand/indexed.hpp25
-rw-r--r--boost/geometry/algorithms/detail/expand/interface.hpp99
-rw-r--r--boost/geometry/algorithms/detail/expand/point.hpp27
-rw-r--r--boost/geometry/algorithms/detail/expand/segment.hpp42
-rw-r--r--boost/geometry/algorithms/detail/flattening.hpp69
-rw-r--r--boost/geometry/algorithms/detail/has_self_intersections.hpp23
-rw-r--r--boost/geometry/algorithms/detail/intersection/interface.hpp279
-rw-r--r--boost/geometry/algorithms/detail/is_simple/always_simple.hpp6
-rw-r--r--boost/geometry/algorithms/detail/is_simple/areal.hpp18
-rw-r--r--boost/geometry/algorithms/detail/is_simple/interface.hpp77
-rw-r--r--boost/geometry/algorithms/detail/is_simple/linear.hpp31
-rw-r--r--boost/geometry/algorithms/detail/is_simple/multipoint.hpp6
-rw-r--r--boost/geometry/algorithms/detail/is_valid/box.hpp6
-rw-r--r--boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp15
-rw-r--r--boost/geometry/algorithms/detail/is_valid/interface.hpp163
-rw-r--r--boost/geometry/algorithms/detail/is_valid/linear.hpp15
-rw-r--r--boost/geometry/algorithms/detail/is_valid/multipolygon.hpp33
-rw-r--r--boost/geometry/algorithms/detail/is_valid/pointlike.hpp11
-rw-r--r--boost/geometry/algorithms/detail/is_valid/polygon.hpp49
-rw-r--r--boost/geometry/algorithms/detail/is_valid/ring.hpp47
-rw-r--r--boost/geometry/algorithms/detail/is_valid/segment.hpp6
-rw-r--r--boost/geometry/algorithms/detail/not.hpp13
-rw-r--r--boost/geometry/algorithms/detail/overlay/assign_parents.hpp9
-rw-r--r--boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp40
-rw-r--r--boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp5
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp49
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turn_info.hpp31
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp21
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp139
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp59
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp32
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turns.hpp130
-rw-r--r--boost/geometry/algorithms/detail/overlay/intersection_insert.hpp63
-rw-r--r--boost/geometry/algorithms/detail/overlay/linear_linear.hpp11
-rw-r--r--boost/geometry/algorithms/detail/overlay/overlay.hpp10
-rw-r--r--boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp42
-rw-r--r--boost/geometry/algorithms/detail/overlay/self_turn_points.hpp42
-rw-r--r--boost/geometry/algorithms/detail/overlay/traversal.hpp6
-rw-r--r--boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp11
-rw-r--r--boost/geometry/algorithms/detail/overlay/traverse.hpp5
-rw-r--r--boost/geometry/algorithms/detail/partition.hpp499
-rw-r--r--boost/geometry/algorithms/detail/relate/areal_areal.hpp87
-rw-r--r--boost/geometry/algorithms/detail/relate/implementation.hpp7
-rw-r--r--boost/geometry/algorithms/detail/relate/interface.hpp135
-rw-r--r--boost/geometry/algorithms/detail/relate/linear_areal.hpp79
-rw-r--r--boost/geometry/algorithms/detail/relate/linear_linear.hpp16
-rw-r--r--boost/geometry/algorithms/detail/relate/point_geometry.hpp16
-rw-r--r--boost/geometry/algorithms/detail/relate/point_point.hpp34
-rw-r--r--boost/geometry/algorithms/detail/relate/relate_impl.hpp5
-rw-r--r--boost/geometry/algorithms/detail/relate/result.hpp4
-rw-r--r--boost/geometry/algorithms/detail/relate/turns.hpp24
-rw-r--r--boost/geometry/algorithms/detail/relation/interface.hpp93
-rw-r--r--boost/geometry/algorithms/detail/throw_on_empty_input.hpp7
-rw-r--r--boost/geometry/algorithms/detail/within/point_in_geometry.hpp98
-rw-r--r--boost/geometry/algorithms/difference.hpp305
-rw-r--r--boost/geometry/algorithms/dispatch/disjoint.hpp27
-rw-r--r--boost/geometry/algorithms/equals.hpp319
-rw-r--r--boost/geometry/algorithms/intersects.hpp40
-rw-r--r--boost/geometry/algorithms/overlaps.hpp46
-rw-r--r--boost/geometry/algorithms/sym_difference.hpp288
-rw-r--r--boost/geometry/algorithms/touches.hpp212
-rw-r--r--boost/geometry/algorithms/union.hpp294
-rw-r--r--boost/geometry/algorithms/within.hpp37
97 files changed, 4217 insertions, 1962 deletions
diff --git a/boost/geometry/algorithms/area.hpp b/boost/geometry/algorithms/area.hpp
index 4751d4e742..18aea24036 100644
--- a/boost/geometry/algorithms/area.hpp
+++ b/boost/geometry/algorithms/area.hpp
@@ -4,6 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017 Oracle and/or its affiliates.
+// 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.
@@ -303,7 +307,8 @@ inline typename default_area_result<Geometry>::type area(Geometry const& geometr
[heading Available Strategies]
\* [link geometry.reference.strategies.strategy_area_surveyor Surveyor (cartesian)]
-\* [link geometry.reference.strategies.strategy_area_huiller Huiller (spherical)]
+\* [link geometry.reference.strategies.strategy_area_spherical Spherical]
+[/link geometry.reference.strategies.strategy_area_geographic Geographic]
}
*/
template <typename Geometry, typename Strategy>
diff --git a/boost/geometry/algorithms/buffer.hpp b/boost/geometry/algorithms/buffer.hpp
index e1d3c20e44..fd6f0fbe6a 100644
--- a/boost/geometry/algorithms/buffer.hpp
+++ b/boost/geometry/algorithms/buffer.hpp
@@ -4,6 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017 Oracle and/or its affiliates.
+// 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.
@@ -274,6 +278,11 @@ inline void buffer(GeometryIn const& geometry_in,
geometry::envelope(geometry_in, box);
geometry::buffer(box, box, distance_strategy.max_distance(join_strategy, end_strategy));
+ typename strategy::intersection::services::default_strategy
+ <
+ typename cs_tag<GeometryIn>::type
+ >::type intersection_strategy;
+
rescale_policy_type rescale_policy
= boost::geometry::get_rescale_policy<rescale_policy_type>(box);
@@ -283,6 +292,7 @@ inline void buffer(GeometryIn const& geometry_in,
join_strategy,
end_strategy,
point_strategy,
+ intersection_strategy,
rescale_policy);
}
diff --git a/boost/geometry/algorithms/centroid.hpp b/boost/geometry/algorithms/centroid.hpp
index fc2908ab1c..6a58033f37 100644
--- a/boost/geometry/algorithms/centroid.hpp
+++ b/boost/geometry/algorithms/centroid.hpp
@@ -3,7 +3,7 @@
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2014-2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2014, 2015.
// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
@@ -26,6 +26,7 @@
#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
+#include <boost/throw_exception.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/static_visitor.hpp>
@@ -183,7 +184,7 @@ inline bool range_ok(Range const& range, Point& centroid)
else if (n <= 0)
{
#if ! defined(BOOST_GEOMETRY_CENTROID_NO_THROW)
- throw centroid_exception();
+ BOOST_THROW_EXCEPTION(centroid_exception());
#else
return false;
#endif
@@ -366,7 +367,7 @@ struct centroid_multi
// to calculate the centroid
if (geometry::is_empty(multi))
{
- throw centroid_exception();
+ BOOST_THROW_EXCEPTION(centroid_exception());
}
#endif
diff --git a/boost/geometry/algorithms/covered_by.hpp b/boost/geometry/algorithms/covered_by.hpp
index 2001d5810c..f9d9dcc486 100644
--- a/boost/geometry/algorithms/covered_by.hpp
+++ b/boost/geometry/algorithms/covered_by.hpp
@@ -4,8 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2013, 2014.
-// Modifications copyright (c) 2013, 2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2017.
+// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
+
+// 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.
@@ -14,8 +16,6 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP
#define BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP
@@ -51,9 +51,13 @@ struct use_point_in_geometry
struct use_relate
{
template <typename Geometry1, typename Geometry2, typename Strategy>
- static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& /*strategy*/)
+ static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
{
- return Strategy::apply(geometry1, geometry2);
+ typedef typename detail::de9im::static_mask_covered_by_type
+ <
+ Geometry1, Geometry2
+ >::type covered_by_mask;
+ return geometry::relate(geometry1, geometry2, covered_by_mask(), strategy);
}
};
@@ -281,23 +285,8 @@ struct covered_by
Geometry2 const& geometry2,
default_strategy)
{
- typedef typename point_type<Geometry1>::type point_type1;
- typedef typename point_type<Geometry2>::type point_type2;
-
typedef typename strategy::covered_by::services::default_strategy
<
- typename tag<Geometry1>::type,
- typename tag<Geometry2>::type,
- typename tag<Geometry1>::type,
- typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
- typename tag_cast
- <
- typename cs_tag<point_type1>::type, spherical_tag
- >::type,
- typename tag_cast
- <
- typename cs_tag<point_type2>::type, spherical_tag
- >::type,
Geometry1,
Geometry2
>::type strategy_type;
diff --git a/boost/geometry/algorithms/crosses.hpp b/boost/geometry/algorithms/crosses.hpp
index 73d86ef529..c9e3651ab2 100644
--- a/boost/geometry/algorithms/crosses.hpp
+++ b/boost/geometry/algorithms/crosses.hpp
@@ -5,8 +5,10 @@
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2014 Samuel Debionne, Grenoble, France.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2017.
+// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
+
+// 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.
@@ -15,8 +17,6 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_ALGORITHMS_CROSSES_HPP
#define BOOST_GEOMETRY_ALGORITHMS_CROSSES_HPP
@@ -26,12 +26,12 @@
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
+#include <boost/geometry/algorithms/relate.hpp>
+#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
#include <boost/geometry/core/access.hpp>
-
#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/strategies/default_strategy.hpp>
-#include <boost/geometry/algorithms/relate.hpp>
-#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
namespace boost { namespace geometry
{
@@ -62,20 +62,51 @@ struct crosses
#endif // DOXYGEN_NO_DISPATCH
+namespace resolve_strategy
+{
+
+struct crosses
+{
+ template <typename Geometry1, typename Geometry2, typename Strategy>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+ {
+ concepts::check<Geometry1 const>();
+ concepts::check<Geometry2 const>();
+
+ return dispatch::crosses<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
+ }
+
+ template <typename Geometry1, typename Geometry2>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ default_strategy)
+ {
+ typedef typename strategy::relate::services::default_strategy
+ <
+ Geometry1,
+ Geometry2
+ >::type strategy_type;
+
+ return apply(geometry1, geometry2, strategy_type());
+ }
+};
+
+} // namespace resolve_strategy
+
+
namespace resolve_variant
{
template <typename Geometry1, typename Geometry2>
struct crosses
{
- static inline bool
- apply(
- const Geometry1& geometry1,
- const Geometry2& geometry2)
+ template <typename Strategy>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
{
- concepts::check<Geometry1 const>();
- concepts::check<Geometry2 const>();
-
- return dispatch::crosses<Geometry1, Geometry2>::apply(geometry1, geometry2);
+ return resolve_strategy::crosses::apply(geometry1, geometry2, strategy);
}
};
@@ -83,12 +114,15 @@ namespace resolve_variant
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
struct crosses<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
{
+ template <typename Strategy>
struct visitor: static_visitor<bool>
{
Geometry2 const& m_geometry2;
+ Strategy const& m_strategy;
- visitor(Geometry2 const& geometry2)
+ visitor(Geometry2 const& geometry2, Strategy const& strategy)
: m_geometry2(geometry2)
+ , m_strategy(strategy)
{}
template <typename Geometry1>
@@ -98,15 +132,16 @@ namespace resolve_variant
<
Geometry1,
Geometry2
- >::apply(geometry1, m_geometry2);
+ >::apply(geometry1, m_geometry2, m_strategy);
}
};
- static inline bool
- apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
- Geometry2 const& geometry2)
+ template <typename Strategy>
+ static inline bool apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
{
- return boost::apply_visitor(visitor(geometry2), geometry1);
+ return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
}
};
@@ -114,12 +149,15 @@ namespace resolve_variant
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct crosses<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
+ template <typename Strategy>
struct visitor: static_visitor<bool>
{
Geometry1 const& m_geometry1;
+ Strategy const& m_strategy;
- visitor(Geometry1 const& geometry1)
+ visitor(Geometry1 const& geometry1, Strategy const& strategy)
: m_geometry1(geometry1)
+ , m_strategy(strategy)
{}
template <typename Geometry2>
@@ -129,15 +167,16 @@ namespace resolve_variant
<
Geometry1,
Geometry2
- >::apply(m_geometry1, geometry2);
+ >::apply(m_geometry1, geometry2, m_strategy);
}
};
- static inline bool
- apply(Geometry1 const& geometry1,
- const variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry2)
+ template <typename Strategy>
+ static inline bool apply(Geometry1 const& geometry1,
+ variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
+ Strategy const& strategy)
{
- return boost::apply_visitor(visitor(geometry1), geometry2);
+ return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
}
};
@@ -145,8 +184,15 @@ namespace resolve_variant
template <BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2)>
struct crosses<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
{
+ template <typename Strategy>
struct visitor: static_visitor<bool>
{
+ Strategy const& m_strategy;
+
+ visitor(Strategy const& strategy)
+ : m_strategy(strategy)
+ {}
+
template <typename Geometry1, typename Geometry2>
result_type operator()(Geometry1 const& geometry1,
Geometry2 const& geometry2) const
@@ -155,15 +201,16 @@ namespace resolve_variant
<
Geometry1,
Geometry2
- >::apply(geometry1, geometry2);
+ >::apply(geometry1, geometry2, m_strategy);
}
};
- static inline bool
- apply(const variant<BOOST_VARIANT_ENUM_PARAMS(T1)>& geometry1,
- const variant<BOOST_VARIANT_ENUM_PARAMS(T2)>& geometry2)
+ template <typename Strategy>
+ static inline bool apply(variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
+ variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
+ Strategy const& strategy)
{
- return boost::apply_visitor(visitor(), geometry1, geometry2);
+ return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
}
};
@@ -175,6 +222,31 @@ namespace resolve_variant
\ingroup crosses
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry
+\tparam Strategy \tparam_strategy{Crosses}
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param strategy \param_strategy{crosses}
+\return \return_check2{crosses}
+
+\qbk{distinguish,with strategy}
+\qbk{[include reference/algorithms/crosses.qbk]}
+*/
+template <typename Geometry1, typename Geometry2, typename Strategy>
+inline bool crosses(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+{
+ return resolve_variant::crosses
+ <
+ Geometry1, Geometry2
+ >::apply(geometry1, geometry2, strategy);
+}
+
+/*!
+\brief \brief_check2{crosses}
+\ingroup crosses
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\return \return_check2{crosses}
@@ -184,7 +256,10 @@ namespace resolve_variant
template <typename Geometry1, typename Geometry2>
inline bool crosses(Geometry1 const& geometry1, Geometry2 const& geometry2)
{
- return resolve_variant::crosses<Geometry1, Geometry2>::apply(geometry1, geometry2);
+ return resolve_variant::crosses
+ <
+ Geometry1, Geometry2
+ >::apply(geometry1, geometry2, default_strategy());
}
}} // namespace boost::geometry
diff --git a/boost/geometry/algorithms/detail/azimuth.hpp b/boost/geometry/algorithms/detail/azimuth.hpp
index 7e0d1691ed..a5863d7d24 100644
--- a/boost/geometry/algorithms/detail/azimuth.hpp
+++ b/boost/geometry/algorithms/detail/azimuth.hpp
@@ -2,9 +2,10 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2014, 2016.
-// Modifications copyright (c) 2014-2016, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2016, 2017.
+// Modifications copyright (c) 2014-2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
@@ -23,6 +24,7 @@
#include <boost/geometry/algorithms/not_implemented.hpp>
+#include <boost/geometry/formulas/spherical.hpp>
#include <boost/geometry/formulas/vincenty_inverse.hpp>
namespace boost { namespace geometry
@@ -69,22 +71,9 @@ struct azimuth<ReturnType, spherical_equatorial_tag>
template <typename P1, typename P2, typename Sphere>
static inline ReturnType apply(P1 const& p1, P2 const& p2, Sphere const& /*unused*/)
{
- // http://williams.best.vwh.net/avform.htm#Crs
- ReturnType dlon = get_as_radian<0>(p2) - get_as_radian<0>(p1);
- ReturnType cos_p2lat = cos(get_as_radian<1>(p2));
-
- // An optimization which should kick in often for Boxes
- //if ( math::equals(dlon, ReturnType(0)) )
- //if ( get<0>(p1) == get<0>(p2) )
- //{
- // return - sin(get_as_radian<1>(p1)) * cos_p2lat);
- //}
-
- // "An alternative formula, not requiring the pre-computation of d"
- // In the formula below dlon is used as "d"
- return atan2(sin(dlon) * cos_p2lat,
- cos(get_as_radian<1>(p1)) * sin(get_as_radian<1>(p2))
- - sin(get_as_radian<1>(p1)) * cos_p2lat * cos(dlon));
+ return geometry::formula::spherical_azimuth<ReturnType, false>
+ ( get_as_radian<0>(p1), get_as_radian<1>(p1),
+ get_as_radian<0>(p2), get_as_radian<1>(p2)).azimuth;
}
template <typename P1, typename P2>
diff --git a/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp b/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp
index 8447532a6c..029053dda3 100644
--- a/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp
+++ b/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp
@@ -2,6 +2,10 @@
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017 Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// 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)
@@ -449,13 +453,14 @@ struct buffer_inserter<point_tag, Point, RingOutput>
}
};
-
+// Not a specialization, but called from specializations of ring and of polygon.
+// Calling code starts/finishes ring before/after apply
template
<
typename RingInput,
typename RingOutput
>
-struct buffer_inserter<ring_tag, RingInput, RingOutput>
+struct buffer_inserter_ring
{
typedef typename point_type<RingOutput>::type output_point_type;
@@ -568,6 +573,43 @@ struct buffer_inserter<ring_tag, RingInput, RingOutput>
template
<
+ typename RingInput,
+ typename RingOutput
+>
+struct buffer_inserter<ring_tag, RingInput, RingOutput>
+{
+ template
+ <
+ typename Collection,
+ typename DistanceStrategy,
+ typename SideStrategy,
+ typename JoinStrategy,
+ typename EndStrategy,
+ typename PointStrategy,
+ typename RobustPolicy
+ >
+ static inline strategy::buffer::result_code apply(RingInput const& ring,
+ Collection& collection,
+ DistanceStrategy const& distance,
+ SideStrategy const& side_strategy,
+ JoinStrategy const& join_strategy,
+ EndStrategy const& end_strategy,
+ PointStrategy const& point_strategy,
+ RobustPolicy const& robust_policy)
+ {
+ collection.start_new_ring();
+ strategy::buffer::result_code const code
+ = buffer_inserter_ring<RingInput, RingOutput>::apply(ring,
+ collection, distance,
+ side_strategy, join_strategy, end_strategy, point_strategy,
+ robust_policy);
+ collection.finish_ring(code);
+ return code;
+ }
+};
+
+template
+<
typename Linestring,
typename Polygon
>
@@ -709,7 +751,7 @@ private:
typedef typename ring_type<PolygonInput>::type input_ring_type;
typedef typename ring_type<PolygonOutput>::type output_ring_type;
- typedef buffer_inserter<ring_tag, input_ring_type, output_ring_type> policy;
+ typedef buffer_inserter_ring<input_ring_type, output_ring_type> policy;
template
@@ -854,6 +896,7 @@ template
typename JoinStrategy,
typename EndStrategy,
typename PointStrategy,
+ typename IntersectionStrategy,
typename RobustPolicy,
typename VisitPiecesPolicy
>
@@ -863,6 +906,7 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
PointStrategy const& point_strategy,
+ IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
VisitPiecesPolicy& visit_pieces_policy
)
@@ -872,9 +916,10 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
typedef detail::buffer::buffered_piece_collection
<
typename geometry::ring_type<GeometryOutput>::type,
+ IntersectionStrategy,
RobustPolicy
> collection_type;
- collection_type collection(robust_policy);
+ collection_type collection(intersection_strategy, robust_policy);
collection_type const& const_collection = collection;
bool const areal = boost::is_same
@@ -961,6 +1006,7 @@ template
typename JoinStrategy,
typename EndStrategy,
typename PointStrategy,
+ typename IntersectionStrategy,
typename RobustPolicy
>
inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator out,
@@ -969,13 +1015,14 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
PointStrategy const& point_strategy,
+ IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy)
{
detail::buffer::visit_pieces_default_policy visitor;
buffer_inserter<GeometryOutput>(geometry_input, out,
distance_strategy, side_strategy, join_strategy,
end_strategy, point_strategy,
- robust_policy, visitor);
+ intersection_strategy, robust_policy, visitor);
}
#endif // DOXYGEN_NO_DETAIL
diff --git a/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp b/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp
index c1f04f93b5..92dcdcc7b0 100644
--- a/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp
+++ b/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp
@@ -2,6 +2,10 @@
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// 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)
@@ -52,6 +56,7 @@ public :
typename Rings,
typename Turns,
typename Geometry,
+ typename Strategy,
typename RobustPolicy,
typename Visitor
>
@@ -63,6 +68,7 @@ public :
detail::overlay::traverse_error_type /*traverse_error*/,
Geometry const& ,
Geometry const& ,
+ Strategy const& ,
RobustPolicy const& ,
state_type& state,
Visitor& /*visitor*/
diff --git a/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp b/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp
index e7214428e6..7fbbb790bb 100644
--- a/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp
+++ b/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2016.
-// Modifications copyright (c) 2016 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2016-2017.
+// Modifications copyright (c) 2016-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
@@ -117,10 +117,13 @@ enum segment_relation_code
*/
-template <typename Ring, typename RobustPolicy>
+template <typename Ring, typename IntersectionStrategy, typename RobustPolicy>
struct buffered_piece_collection
{
- typedef buffered_piece_collection<Ring, RobustPolicy> this_type;
+ typedef buffered_piece_collection
+ <
+ Ring, IntersectionStrategy, RobustPolicy
+ > this_type;
typedef typename geometry::point_type<Ring>::type point_type;
typedef typename geometry::coordinate_type<Ring>::type coordinate_type;
@@ -303,7 +306,7 @@ struct buffered_piece_collection
cluster_type m_clusters;
-
+ IntersectionStrategy const& m_intersection_strategy;
RobustPolicy const& m_robust_policy;
struct redundant_turn
@@ -314,8 +317,10 @@ struct buffered_piece_collection
}
};
- buffered_piece_collection(RobustPolicy const& robust_policy)
+ buffered_piece_collection(IntersectionStrategy const& intersection_strategy,
+ RobustPolicy const& robust_policy)
: m_first_piece_index(-1)
+ , m_intersection_strategy(intersection_strategy)
, m_robust_policy(robust_policy)
{}
@@ -512,10 +517,11 @@ struct buffered_piece_collection
geometry::partition
<
robust_box_type,
- turn_get_box, turn_in_original_ovelaps_box,
- original_get_box, original_ovelaps_box,
- include_turn_policy, detail::partition::include_all_policy
- >::apply(m_turns, robust_originals, visitor);
+ include_turn_policy,
+ detail::partition::include_all_policy
+ >::apply(m_turns, robust_originals, visitor,
+ turn_get_box(), turn_in_original_ovelaps_box(),
+ original_get_box(), original_ovelaps_box());
bool const deflate = distance_strategy.negative();
@@ -767,15 +773,17 @@ struct buffered_piece_collection
piece_vector_type,
buffered_ring_collection<buffered_ring<Ring> >,
turn_vector_type,
+ IntersectionStrategy,
RobustPolicy
- > visitor(m_pieces, offsetted_rings, m_turns, m_robust_policy);
+ > visitor(m_pieces, offsetted_rings, m_turns,
+ m_intersection_strategy, m_robust_policy);
geometry::partition
<
- robust_box_type,
- detail::section::get_section_box,
- detail::section::overlaps_section_box
- >::apply(monotonic_sections, visitor);
+ robust_box_type
+ >::apply(monotonic_sections, visitor,
+ detail::section::get_section_box(),
+ detail::section::overlaps_section_box());
}
insert_rescaled_piece_turns();
@@ -795,10 +803,10 @@ struct buffered_piece_collection
geometry::partition
<
- robust_box_type,
- turn_get_box, turn_ovelaps_box,
- piece_get_box, piece_ovelaps_box
- >::apply(m_turns, m_pieces, visitor);
+ robust_box_type
+ >::apply(m_turns, m_pieces, visitor,
+ turn_get_box(), turn_ovelaps_box(),
+ piece_get_box(), piece_ovelaps_box());
}
}
@@ -1354,7 +1362,8 @@ struct buffered_piece_collection
traversed_rings.clear();
buffer_overlay_visitor visitor;
traverser::apply(offsetted_rings, offsetted_rings,
- m_robust_policy, m_turns, traversed_rings,
+ m_intersection_strategy, m_robust_policy,
+ m_turns, traversed_rings,
m_clusters, visitor);
}
diff --git a/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp b/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp
index 3425ee6ffd..178c7bcafe 100644
--- a/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp
+++ b/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp
@@ -2,6 +2,10 @@
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017 Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// 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)
@@ -62,6 +66,7 @@ template
typename Pieces,
typename Rings,
typename Turns,
+ typename IntersectionStrategy,
typename RobustPolicy
>
class piece_turn_visitor
@@ -69,6 +74,7 @@ class piece_turn_visitor
Pieces const& m_pieces;
Rings const& m_rings;
Turns& m_turns;
+ IntersectionStrategy const& m_intersection_strategy;
RobustPolicy const& m_robust_policy;
template <typename Piece>
@@ -243,7 +249,9 @@ class piece_turn_visitor
turn_policy::apply(*prev1, *it1, *next1,
*prev2, *it2, *next2,
false, false, false, false,
- the_model, m_robust_policy,
+ the_model,
+ m_intersection_strategy,
+ m_robust_policy,
std::back_inserter(m_turns));
}
}
@@ -254,10 +262,12 @@ public:
piece_turn_visitor(Pieces const& pieces,
Rings const& ring_collection,
Turns& turns,
+ IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy)
: m_pieces(pieces)
, m_rings(ring_collection)
, m_turns(turns)
+ , m_intersection_strategy(intersection_strategy)
, m_robust_policy(robust_policy)
{}
diff --git a/boost/geometry/algorithms/detail/calculate_sum.hpp b/boost/geometry/algorithms/detail/calculate_sum.hpp
index b23e70171b..732a2f5753 100644
--- a/boost/geometry/algorithms/detail/calculate_sum.hpp
+++ b/boost/geometry/algorithms/detail/calculate_sum.hpp
@@ -8,6 +8,10 @@
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2016.
+// Modifications copyright (c) 2016 Oracle and/or its affiliates.
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+
// 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)
@@ -30,7 +34,7 @@ class calculate_polygon_sum
template <typename ReturnType, typename Policy, typename Rings, typename Strategy>
static inline ReturnType sum_interior_rings(Rings const& rings, Strategy const& strategy)
{
- ReturnType sum = ReturnType();
+ ReturnType sum = ReturnType(0);
for (typename boost::range_iterator<Rings const>::type
it = boost::begin(rings); it != boost::end(rings); ++it)
{
diff --git a/boost/geometry/algorithms/detail/disjoint/areal_areal.hpp b/boost/geometry/algorithms/detail/disjoint/areal_areal.hpp
index 284858a130..664c995384 100644
--- a/boost/geometry/algorithms/detail/disjoint/areal_areal.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/areal_areal.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013-2014.
-// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013-2017.
+// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -39,15 +39,45 @@ namespace detail { namespace disjoint
{
-template<typename Geometry>
+template <typename Geometry, typename Tag = typename tag<Geometry>::type>
+struct check_each_ring_for_within_call_covered_by
+{
+ /*!
+ \tparam Strategy point_in_geometry strategy
+ */
+ template <typename Point, typename Strategy>
+ static inline bool apply(Point const& p, Geometry const& g, Strategy const& strategy)
+ {
+ return geometry::covered_by(p, g, strategy);
+ }
+};
+
+template <typename Geometry>
+struct check_each_ring_for_within_call_covered_by<Geometry, box_tag>
+{
+ template <typename Point, typename Strategy>
+ static inline bool apply(Point const& p, Geometry const& g, Strategy const& )
+ {
+ return geometry::covered_by(p, g);
+ }
+};
+
+
+/*!
+\tparam Strategy point_in_geometry strategy
+*/
+template<typename Geometry, typename Strategy>
struct check_each_ring_for_within
{
bool not_disjoint;
Geometry const& m_geometry;
+ Strategy const& m_strategy;
- inline check_each_ring_for_within(Geometry const& g)
+ inline check_each_ring_for_within(Geometry const& g,
+ Strategy const& strategy)
: not_disjoint(false)
, m_geometry(g)
+ , m_strategy(strategy)
{}
template <typename Range>
@@ -56,17 +86,26 @@ struct check_each_ring_for_within
typename point_type<Range>::type pt;
not_disjoint = not_disjoint
|| ( geometry::point_on_border(pt, range)
- && geometry::covered_by(pt, m_geometry) );
+ && check_each_ring_for_within_call_covered_by
+ <
+ Geometry
+ >::apply(pt, m_geometry, m_strategy) );
}
};
-
-template <typename FirstGeometry, typename SecondGeometry>
+/*!
+\tparam Strategy point_in_geometry strategy
+*/
+template <typename FirstGeometry, typename SecondGeometry, typename Strategy>
inline bool rings_containing(FirstGeometry const& geometry1,
- SecondGeometry const& geometry2)
+ SecondGeometry const& geometry2,
+ Strategy const& strategy)
{
- check_each_ring_for_within<FirstGeometry> checker(geometry1);
+ check_each_ring_for_within
+ <
+ FirstGeometry, Strategy
+ > checker(geometry1, strategy);
geometry::detail::for_each_range(geometry2, checker);
return checker.not_disjoint;
}
@@ -76,10 +115,15 @@ inline bool rings_containing(FirstGeometry const& geometry1,
template <typename Geometry1, typename Geometry2>
struct general_areal
{
- static inline
- bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
+ /*!
+ \tparam Strategy relate (segments intersection) strategy
+ */
+ template <typename Strategy>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
{
- if ( ! disjoint_linear<Geometry1, Geometry2>::apply(geometry1, geometry2) )
+ if ( ! disjoint_linear<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy) )
{
return false;
}
@@ -90,8 +134,10 @@ struct general_areal
// We check that using a point on the border (external boundary),
// and see if that is contained in the other geometry. And vice versa.
- if ( rings_containing(geometry1, geometry2)
- || rings_containing(geometry2, geometry1) )
+ if ( rings_containing(geometry1, geometry2,
+ strategy.template get_point_in_geometry_strategy<Geometry2, Geometry1>())
+ || rings_containing(geometry2, geometry1,
+ strategy.template get_point_in_geometry_strategy<Geometry1, Geometry2>()) )
{
return false;
}
diff --git a/boost/geometry/algorithms/detail/disjoint/box_box.hpp b/boost/geometry/algorithms/detail/disjoint/box_box.hpp
index 3b81755e20..f830f8161c 100644
--- a/boost/geometry/algorithms/detail/disjoint/box_box.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/box_box.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013-2016.
-// Modifications copyright (c) 2013-2016, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013-2017.
+// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -52,6 +52,12 @@ template
>
struct box_box
{
+ template <typename Strategy>
+ static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const&)
+ {
+ return apply(box1, box2);
+ }
+
static inline bool apply(Box1 const& box1, Box2 const& box2)
{
if (get<max_corner, Dimension>(box1) < get<min_corner, Dimension>(box2))
@@ -84,6 +90,12 @@ struct box_box<Box1, Box2, DimensionCount, DimensionCount, CSTag>
template <typename Box1, typename Box2, std::size_t DimensionCount>
struct box_box<Box1, Box2, 0, DimensionCount, spherical_tag>
{
+ template <typename Strategy>
+ static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const&)
+ {
+ return apply(box1, box2);
+ }
+
static inline bool apply(Box1 const& box1, Box2 const& box2)
{
typedef typename geometry::select_most_precise
diff --git a/boost/geometry/algorithms/detail/disjoint/interface.hpp b/boost/geometry/algorithms/detail/disjoint/interface.hpp
index ce7fe6d45c..64898e35fe 100644
--- a/boost/geometry/algorithms/detail/disjoint/interface.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/interface.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013-2014.
-// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013-2017.
+// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -27,43 +27,51 @@
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
+#include <boost/geometry/algorithms/detail/relate/interface.hpp>
+#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
+
#include <boost/geometry/geometries/concepts/check.hpp>
-#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
+#include <boost/geometry/strategies/disjoint.hpp>
namespace boost { namespace geometry
{
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
+namespace resolve_strategy
{
-
-// If reversal is needed, perform it
-template
-<
- typename Geometry1, typename Geometry2,
- std::size_t DimensionCount,
- typename Tag1, typename Tag2
->
-struct disjoint<Geometry1, Geometry2, DimensionCount, Tag1, Tag2, true>
+struct disjoint
{
- static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
+ template <typename Geometry1, typename Geometry2, typename Strategy>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
{
- return disjoint
+ return dispatch::disjoint
+ <
+ Geometry1, Geometry2
+ >::apply(geometry1, geometry2, strategy);
+ }
+
+ template <typename Geometry1, typename Geometry2>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ default_strategy)
+ {
+ typedef typename strategy::disjoint::services::default_strategy
<
- Geometry2, Geometry1,
- DimensionCount,
- Tag2, Tag1
- >::apply(g2, g1);
+ Geometry1, Geometry2
+ >::type strategy_type;
+
+ return dispatch::disjoint
+ <
+ Geometry1, Geometry2
+ >::apply(geometry1, geometry2, strategy_type());
}
};
-
-} // namespace dispatch
-#endif // DOXYGEN_NO_DISPATCH
+} // namespace resolve_strategy
namespace resolve_variant {
@@ -71,7 +79,8 @@ namespace resolve_variant {
template <typename Geometry1, typename Geometry2>
struct disjoint
{
- static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
+ template <typename Strategy>
+ static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
{
concepts::check_concepts_and_equal_dimensions
<
@@ -79,88 +88,135 @@ struct disjoint
Geometry2 const
>();
- return dispatch::disjoint<Geometry1, Geometry2>::apply(geometry1, geometry2);
+ return resolve_strategy::disjoint::apply(geometry1, geometry2, strategy);
}
};
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
struct disjoint<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
{
+ template <typename Strategy>
struct visitor: boost::static_visitor<bool>
{
Geometry2 const& m_geometry2;
+ Strategy const& m_strategy;
- visitor(Geometry2 const& geometry2): m_geometry2(geometry2) {}
+ visitor(Geometry2 const& geometry2, Strategy const& strategy)
+ : m_geometry2(geometry2)
+ , m_strategy(strategy)
+ {}
template <typename Geometry1>
bool operator()(Geometry1 const& geometry1) const
{
- return disjoint<Geometry1, Geometry2>::apply(geometry1, m_geometry2);
+ return disjoint<Geometry1, Geometry2>::apply(geometry1, m_geometry2, m_strategy);
}
};
- static inline bool
- apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
- Geometry2 const& geometry2)
+ template <typename Strategy>
+ static inline bool apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
{
- return boost::apply_visitor(visitor(geometry2), geometry1);
+ return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
}
};
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct disjoint<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
+ template <typename Strategy>
struct visitor: boost::static_visitor<bool>
{
Geometry1 const& m_geometry1;
+ Strategy const& m_strategy;
- visitor(Geometry1 const& geometry1): m_geometry1(geometry1) {}
+ visitor(Geometry1 const& geometry1, Strategy const& strategy)
+ : m_geometry1(geometry1)
+ , m_strategy(strategy)
+ {}
template <typename Geometry2>
bool operator()(Geometry2 const& geometry2) const
{
- return disjoint<Geometry1, Geometry2>::apply(m_geometry1, geometry2);
+ return disjoint<Geometry1, Geometry2>::apply(m_geometry1, geometry2, m_strategy);
}
};
- static inline bool
- apply(Geometry1 const& geometry1,
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2)
+ template <typename Strategy>
+ static inline bool apply(Geometry1 const& geometry1,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
+ Strategy const& strategy)
{
- return boost::apply_visitor(visitor(geometry1), geometry2);
+ return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
}
};
-template <
+template
+<
BOOST_VARIANT_ENUM_PARAMS(typename T1),
BOOST_VARIANT_ENUM_PARAMS(typename T2)
>
-struct disjoint<
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
->
+struct disjoint
+ <
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
+ >
{
+ template <typename Strategy>
struct visitor: boost::static_visitor<bool>
{
+ Strategy const& m_strategy;
+
+ visitor(Strategy const& strategy)
+ : m_strategy(strategy)
+ {}
+
template <typename Geometry1, typename Geometry2>
bool operator()(Geometry1 const& geometry1,
Geometry2 const& geometry2) const
{
- return disjoint<Geometry1, Geometry2>::apply(geometry1, geometry2);
+ return disjoint<Geometry1, Geometry2>::apply(geometry1, geometry2, m_strategy);
}
};
- static inline bool
- apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2)
+ template <typename Strategy>
+ static inline bool 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(), geometry1, geometry2);
+ return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
}
};
} // namespace resolve_variant
+/*!
+\brief \brief_check2{are disjoint}
+\ingroup disjoint
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam Strategy \tparam_strategy{Disjoint}
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param strategy \param_strategy{disjoint}
+\return \return_check2{are disjoint}
+
+\qbk{distinguish,with strategy}
+\qbk{[include reference/algorithms/disjoint.qbk]}
+*/
+template <typename Geometry1, typename Geometry2, typename Strategy>
+inline bool disjoint(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+{
+ return resolve_variant::disjoint
+ <
+ Geometry1, Geometry2
+ >::apply(geometry1, geometry2, strategy);
+}
+
/*!
\brief \brief_check2{are disjoint}
@@ -177,7 +233,10 @@ template <typename Geometry1, typename Geometry2>
inline bool disjoint(Geometry1 const& geometry1,
Geometry2 const& geometry2)
{
- return resolve_variant::disjoint<Geometry1, Geometry2>::apply(geometry1, geometry2);
+ return resolve_variant::disjoint
+ <
+ Geometry1, Geometry2
+ >::apply(geometry1, geometry2, default_strategy());
}
diff --git a/boost/geometry/algorithms/detail/disjoint/linear_areal.hpp b/boost/geometry/algorithms/detail/disjoint/linear_areal.hpp
index 6a48b684a1..e6077d3e7f 100644
--- a/boost/geometry/algorithms/detail/disjoint/linear_areal.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/linear_areal.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013-2015.
-// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013-2017.
+// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -61,19 +61,28 @@ template <typename Geometry1, typename Geometry2,
typename Tag1OrMulti = typename tag_cast<Tag1, multi_tag>::type>
struct disjoint_no_intersections_policy
{
- static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
+ /*!
+ \tparam Strategy point_in_geometry strategy
+ */
+ template <typename Strategy>
+ static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
{
typedef typename point_type<Geometry1>::type point1_type;
point1_type p;
geometry::point_on_border(p, g1);
- return !geometry::covered_by(p, g2);
+
+ return !geometry::covered_by(p, g2, strategy);
}
};
template <typename Geometry1, typename Geometry2, typename Tag1>
struct disjoint_no_intersections_policy<Geometry1, Geometry2, Tag1, multi_tag>
{
- static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
+ /*!
+ \tparam Strategy point_in_geometry strategy
+ */
+ template <typename Strategy>
+ static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
{
// TODO: use partition or rtree on g2
typedef typename boost::range_iterator<Geometry1 const>::type iterator;
@@ -81,7 +90,7 @@ struct disjoint_no_intersections_policy<Geometry1, Geometry2, Tag1, multi_tag>
{
typedef typename boost::range_value<Geometry1 const>::type value_type;
if ( ! disjoint_no_intersections_policy<value_type const, Geometry2>
- ::apply(*it, g2) )
+ ::apply(*it, g2, strategy) )
{
return false;
}
@@ -96,15 +105,21 @@ template<typename Geometry1, typename Geometry2,
= disjoint_no_intersections_policy<Geometry1, Geometry2> >
struct disjoint_linear_areal
{
- static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
+ /*!
+ \tparam Strategy relate (segments intersection) strategy
+ */
+ template <typename Strategy>
+ static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
{
// if there are intersections - return false
- if ( !disjoint_linear<Geometry1, Geometry2>::apply(g1, g2) )
+ if ( !disjoint_linear<Geometry1, Geometry2>::apply(g1, g2, strategy) )
{
return false;
}
- return NoIntersectionsPolicy::apply(g1, g2);
+ return NoIntersectionsPolicy
+ ::apply(g1, g2,
+ strategy.template get_point_in_geometry_strategy<Geometry1, Geometry2>());
}
};
@@ -126,16 +141,18 @@ template <typename Segment, typename Polygon>
class disjoint_segment_areal<Segment, Polygon, polygon_tag>
{
private:
- template <typename InteriorRings>
+ template <typename InteriorRings, typename Strategy>
static inline
bool check_interior_rings(InteriorRings const& interior_rings,
- Segment const& segment)
+ Segment const& segment,
+ Strategy const& strategy)
{
typedef typename boost::range_value<InteriorRings>::type ring_type;
typedef unary_disjoint_geometry_to_query_geometry
<
Segment,
+ Strategy,
disjoint_range_segment_or_box
<
ring_type, closure<ring_type>::value, Segment
@@ -147,24 +164,27 @@ private:
unary_predicate_type
>::apply(boost::begin(interior_rings),
boost::end(interior_rings),
- unary_predicate_type(segment));
+ unary_predicate_type(segment, strategy));
}
public:
- static inline bool apply(Segment const& segment, Polygon const& polygon)
+ template <typename IntersectionStrategy>
+ static inline bool apply(Segment const& segment,
+ Polygon const& polygon,
+ IntersectionStrategy const& strategy)
{
typedef typename geometry::ring_type<Polygon>::type ring;
if ( !disjoint_range_segment_or_box
<
ring, closure<Polygon>::value, Segment
- >::apply(geometry::exterior_ring(polygon), segment) )
+ >::apply(geometry::exterior_ring(polygon), segment, strategy) )
{
return false;
}
- if ( !check_interior_rings(geometry::interior_rings(polygon), segment) )
+ if ( !check_interior_rings(geometry::interior_rings(polygon), segment, strategy) )
{
return false;
}
@@ -172,7 +192,8 @@ public:
typename point_type<Segment>::type p;
detail::assign_point_from_index<0>(segment, p);
- return !geometry::covered_by(p, polygon);
+ return !geometry::covered_by(p, polygon,
+ strategy.template get_point_in_geometry_strategy<Segment, Polygon>());
}
};
@@ -180,13 +201,14 @@ public:
template <typename Segment, typename MultiPolygon>
struct disjoint_segment_areal<Segment, MultiPolygon, multi_polygon_tag>
{
- static inline
- bool apply(Segment const& segment, MultiPolygon const& multipolygon)
+ template <typename IntersectionStrategy>
+ static inline bool apply(Segment const& segment, MultiPolygon const& multipolygon,
+ IntersectionStrategy const& strategy)
{
return multirange_constant_size_geometry
<
MultiPolygon, Segment
- >::apply(multipolygon, segment);
+ >::apply(multipolygon, segment, strategy);
}
};
@@ -194,20 +216,24 @@ struct disjoint_segment_areal<Segment, MultiPolygon, multi_polygon_tag>
template <typename Segment, typename Ring>
struct disjoint_segment_areal<Segment, Ring, ring_tag>
{
- static inline bool apply(Segment const& segment, Ring const& ring)
+ template <typename IntersectionStrategy>
+ static inline bool apply(Segment const& segment,
+ Ring const& ring,
+ IntersectionStrategy const& strategy)
{
if ( !disjoint_range_segment_or_box
<
Ring, closure<Ring>::value, Segment
- >::apply(ring, segment) )
+ >::apply(ring, segment, strategy) )
{
return false;
}
typename point_type<Segment>::type p;
detail::assign_point_from_index<0>(segment, p);
-
- return !geometry::covered_by(p, ring);
+
+ return !geometry::covered_by(p, ring,
+ strategy.template get_point_in_geometry_strategy<Segment, Ring>());
}
};
@@ -231,14 +257,15 @@ struct disjoint<Linear, Areal, 2, linear_tag, areal_tag, false>
template <typename Areal, typename Linear>
struct disjoint<Areal, Linear, 2, areal_tag, linear_tag, false>
-{
- static inline
- bool apply(Areal const& areal, Linear const& linear)
+{
+ template <typename Strategy>
+ static inline bool apply(Areal const& areal, Linear const& linear,
+ Strategy const& strategy)
{
return detail::disjoint::disjoint_linear_areal
<
Linear, Areal
- >::apply(linear, areal);
+ >::apply(linear, areal, strategy);
}
};
@@ -246,12 +273,14 @@ struct disjoint<Areal, Linear, 2, areal_tag, linear_tag, false>
template <typename Areal, typename Segment>
struct disjoint<Areal, Segment, 2, areal_tag, segment_tag, false>
{
- static inline bool apply(Areal const& g1, Segment const& g2)
+ template <typename Strategy>
+ static inline bool apply(Areal const& g1, Segment const& g2,
+ Strategy const& strategy)
{
return detail::disjoint::disjoint_segment_areal
<
Segment, Areal
- >::apply(g2, g1);
+ >::apply(g2, g1, strategy);
}
};
diff --git a/boost/geometry/algorithms/detail/disjoint/linear_linear.hpp b/boost/geometry/algorithms/detail/disjoint/linear_linear.hpp
index 91f985edb8..989b8df247 100644
--- a/boost/geometry/algorithms/detail/disjoint/linear_linear.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/linear_linear.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013-2014.
-// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013-2017.
+// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -53,7 +53,9 @@ namespace detail { namespace disjoint
template <typename Segment1, typename Segment2>
struct disjoint_segment
{
- static inline bool apply(Segment1 const& segment1, Segment2 const& segment2)
+ template <typename Strategy>
+ static inline bool apply(Segment1 const& segment1, Segment2 const& segment2,
+ Strategy const& strategy)
{
typedef typename point_type<Segment1>::type point_type;
@@ -62,23 +64,23 @@ struct disjoint_segment
rescale_policy_type robust_policy;
typedef segment_intersection_points
- <
- point_type,
- typename segment_ratio_type
+ <
+ point_type,
+ typename segment_ratio_type
<
point_type,
rescale_policy_type
>::type
- > intersection_return_type;
+ > intersection_return_type;
- intersection_return_type is
- = strategy::intersection::relate_cartesian_segments
+ typedef policies::relate::segments_intersection_points
<
- policies::relate::segments_intersection_points
- <
- intersection_return_type
- >
- >::apply(segment1, segment2, robust_policy);
+ intersection_return_type
+ > intersection_policy;
+
+ intersection_return_type is = strategy.apply(segment1, segment2,
+ intersection_policy(),
+ robust_policy);
return is.count == 0;
}
@@ -109,8 +111,10 @@ struct assign_disjoint_policy
template <typename Geometry1, typename Geometry2>
struct disjoint_linear
{
- static inline
- bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
+ template <typename Strategy>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
{
typedef typename geometry::point_type<Geometry1>::type point_type;
typedef detail::no_rescale_policy rescale_policy_type;
@@ -147,7 +151,7 @@ struct disjoint_linear
Geometry1, Geometry2, assign_disjoint_policy
>
>::apply(0, geometry1, 1, geometry2,
- rescale_policy_type(), turns, interrupt_policy);
+ strategy, rescale_policy_type(), turns, interrupt_policy);
return !interrupt_policy.has_intersections;
}
diff --git a/boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp b/boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp
index 8d82f7c911..b4c71c8f30 100644
--- a/boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp
@@ -53,8 +53,10 @@ template
>
struct disjoint_range_segment_or_box
{
- static inline
- bool apply(Range const& range, SegmentOrBox const& segment_or_box)
+ template <typename Strategy>
+ static inline bool apply(Range const& range,
+ SegmentOrBox const& segment_or_box,
+ Strategy const& strategy)
{
typedef typename closeable_view<Range const, Closure>::type view_type;
@@ -85,7 +87,8 @@ struct disjoint_range_segment_or_box
<
point_type, SegmentOrBox
>::apply(geometry::range::front<view_type const>(view),
- segment_or_box);
+ segment_or_box,
+ strategy.template get_point_in_geometry_strategy<Range, SegmentOrBox>());
}
else
{
@@ -99,7 +102,7 @@ struct disjoint_range_segment_or_box
if ( !dispatch::disjoint
<
range_segment, SegmentOrBox
- >::apply(rng_segment, segment_or_box) )
+ >::apply(rng_segment, segment_or_box, strategy) )
{
return false;
}
diff --git a/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp b/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp
index 29e438e546..7c1a93cdb7 100644
--- a/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp
@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014-2015, Oracle and/or its affiliates.
+// Copyright (c) 2014-2017, 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
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -14,8 +15,10 @@
#include <vector>
#include <boost/range.hpp>
+#include <boost/mpl/assert.hpp>
#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/box.hpp>
@@ -105,36 +108,74 @@ template <typename MultiPoint, typename Linear>
class multipoint_linear
{
private:
- // structs for partition -- start
- struct expand_box
+ struct expand_box_point
{
- template <typename Box, typename Geometry>
- static inline void apply(Box& total, Geometry const& geometry)
+ template <typename Box, typename Point>
+ static inline void apply(Box& total, Point const& point)
{
- geometry::expand(total, geometry::return_envelope<Box>(geometry));
+ geometry::expand(total, point);
}
+ };
+ // TODO: After adding non-cartesian Segment envelope to the library
+ // this policy should be modified to take envelope strategy.
+ struct expand_box_segment
+ {
+ template <typename Box, typename Segment>
+ static inline void apply(Box& total, Segment const& segment)
+ {
+ geometry::expand(total, geometry::return_envelope<Box>(segment));
+ }
};
- struct overlaps_box
+ struct overlaps_box_point
{
- template <typename Box, typename Geometry>
- static inline bool apply(Box const& box, Geometry const& geometry)
+ template <typename Box, typename Point>
+ static inline bool apply(Box const& box, Point const& point)
{
- return ! dispatch::disjoint<Geometry, Box>::apply(geometry, box);
+ // The default strategy is enough in this case
+ typedef typename strategy::disjoint::services::default_strategy
+ <
+ Point, Box
+ >::type strategy_type;
+ return ! dispatch::disjoint<Point, Box>::apply(point, box, strategy_type());
}
};
+ // TODO: After implementing disjoint Segment/Box for non-cartesian geometries
+ // this strategy should be passed here.
+ // TODO: This Segment/Box strategy should somehow be derived from Point/Segment strategy
+ // which by default is winding containing CS-specific side strategy
+ // TODO: disjoint Segment/Box will be called in this case which may take
+ // quite long in non-cartesian CS. So we should consider passing range of bounding boxes
+ // of segments after calculating them once.
+ struct overlaps_box_segment
+ {
+ template <typename Box, typename Segment>
+ static inline bool apply(Box const& box, Segment const& segment)
+ {
+ typedef typename strategy::disjoint::services::default_strategy
+ <
+ Segment, Box
+ >::type strategy_type;
+ return ! dispatch::disjoint<Segment, Box>::apply(segment, box, strategy_type());
+ }
+ };
+
+ template <typename PtSegStrategy>
class item_visitor_type
{
public:
- item_visitor_type() : m_intersection_found(false) {}
+ item_visitor_type(PtSegStrategy const& strategy)
+ : m_intersection_found(false)
+ , m_strategy(strategy)
+ {}
template <typename Item1, typename Item2>
inline void apply(Item1 const& item1, Item2 const& item2)
{
if (! m_intersection_found
- && ! dispatch::disjoint<Item1, Item2>::apply(item1, item2))
+ && ! dispatch::disjoint<Item1, Item2>::apply(item1, item2, m_strategy))
{
m_intersection_found = true;
}
@@ -144,6 +185,7 @@ private:
private:
bool m_intersection_found;
+ PtSegStrategy const& m_strategy;
};
// structs for partition -- end
@@ -172,23 +214,25 @@ private:
};
public:
- static inline bool apply(MultiPoint const& multipoint, Linear const& linear)
+ template <typename Strategy>
+ static inline bool apply(MultiPoint const& multipoint, Linear const& linear, Strategy const& strategy)
{
- item_visitor_type visitor;
+ item_visitor_type<Strategy> visitor(strategy);
geometry::partition
<
- geometry::model::box<typename point_type<MultiPoint>::type>,
- expand_box,
- overlaps_box
- >::apply(multipoint, segment_range(linear), visitor);
+ geometry::model::box<typename point_type<MultiPoint>::type>
+ >::apply(multipoint, segment_range(linear), visitor,
+ expand_box_point(), overlaps_box_point(),
+ expand_box_segment(), overlaps_box_segment());
return ! visitor.intersection_found();
}
- static inline bool apply(Linear const& linear, MultiPoint const& multipoint)
+ template <typename Strategy>
+ static inline bool apply(Linear const& linear, MultiPoint const& multipoint, Strategy const& strategy)
{
- return apply(multipoint, linear);
+ return apply(multipoint, linear, strategy);
}
};
@@ -240,8 +284,10 @@ struct disjoint
multi_point_tag, multi_point_tag, false
>
{
+ template <typename Strategy>
static inline bool apply(MultiPoint1 const& multipoint1,
- MultiPoint2 const& multipoint2)
+ MultiPoint2 const& multipoint2,
+ Strategy const& )
{
if ( boost::size(multipoint2) < boost::size(multipoint1) )
{
diff --git a/boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp b/boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp
index 78a683e46e..53fb1642af 100644
--- a/boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp
@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2017, 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
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -25,34 +26,40 @@ namespace detail { namespace disjoint
{
-template <typename Geometry, typename BinaryPredicate>
+template <typename Geometry, typename Strategy, typename BinaryPredicate>
class unary_disjoint_geometry_to_query_geometry
{
public:
- unary_disjoint_geometry_to_query_geometry(Geometry const& geometry)
+ unary_disjoint_geometry_to_query_geometry(Geometry const& geometry,
+ Strategy const& strategy)
: m_geometry(geometry)
+ , m_strategy(strategy)
{}
template <typename QueryGeometry>
inline bool apply(QueryGeometry const& query_geometry) const
{
- return BinaryPredicate::apply(query_geometry, m_geometry);
+ return BinaryPredicate::apply(query_geometry, m_geometry, m_strategy);
}
private:
Geometry const& m_geometry;
+ Strategy const& m_strategy;
};
template<typename MultiRange, typename ConstantSizeGeometry>
struct multirange_constant_size_geometry
{
+ template <typename Strategy>
static inline bool apply(MultiRange const& multirange,
- ConstantSizeGeometry const& constant_size_geometry)
+ ConstantSizeGeometry const& constant_size_geometry,
+ Strategy const& strategy)
{
typedef unary_disjoint_geometry_to_query_geometry
<
ConstantSizeGeometry,
+ Strategy,
dispatch::disjoint
<
typename boost::range_value<MultiRange>::type,
@@ -64,13 +71,15 @@ struct multirange_constant_size_geometry
<
unary_predicate_type
>::apply(boost::begin(multirange), boost::end(multirange),
- unary_predicate_type(constant_size_geometry));
+ unary_predicate_type(constant_size_geometry, strategy));
}
+ template <typename Strategy>
static inline bool apply(ConstantSizeGeometry const& constant_size_geometry,
- MultiRange const& multirange)
+ MultiRange const& multirange,
+ Strategy const& strategy)
{
- return apply(multirange, constant_size_geometry);
+ return apply(multirange, constant_size_geometry, strategy);
}
};
diff --git a/boost/geometry/algorithms/detail/disjoint/point_box.hpp b/boost/geometry/algorithms/detail/disjoint/point_box.hpp
index 2f1085ada9..2e6773d221 100644
--- a/boost/geometry/algorithms/detail/disjoint/point_box.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/point_box.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland
-// This file was modified by Oracle on 2013-2016.
-// Modifications copyright (c) 2013-2016, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013-2017.
+// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -28,7 +28,7 @@
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
-#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
+#include <boost/geometry/strategies/disjoint.hpp>
namespace boost { namespace geometry
{
@@ -44,13 +44,13 @@ namespace detail { namespace disjoint
template <typename Point, typename Box>
inline bool disjoint_point_box(Point const& point, Box const& box)
{
+ typedef typename strategy::disjoint::services::default_strategy
+ <
+ Point, Box
+ >::type strategy_type;
+
// ! covered_by(point, box)
- return ! strategy::within::relate_point_box_loop
- <
- strategy::within::covered_by_range,
- Point, Box,
- 0, dimension<Point>::type::value
- >::apply(point, box);
+ return ! strategy_type::apply(point, box);
}
@@ -66,15 +66,11 @@ namespace dispatch
template <typename Point, typename Box, std::size_t DimensionCount>
struct disjoint<Point, Box, DimensionCount, point_tag, box_tag, false>
{
- static inline bool apply(Point const& point, Box const& box)
+ template <typename Strategy>
+ static inline bool apply(Point const& point, Box const& box, Strategy const& )
{
// ! covered_by(point, box)
- return ! strategy::within::relate_point_box_loop
- <
- strategy::within::covered_by_range,
- Point, Box,
- 0, DimensionCount
- >::apply(point, box);
+ return ! Strategy::apply(point, box);
}
};
diff --git a/boost/geometry/algorithms/detail/disjoint/point_geometry.hpp b/boost/geometry/algorithms/detail/disjoint/point_geometry.hpp
index 9ae43f73d0..66bd7c26ce 100644
--- a/boost/geometry/algorithms/detail/disjoint/point_geometry.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/point_geometry.hpp
@@ -39,11 +39,12 @@ namespace detail { namespace disjoint
struct reverse_covered_by
{
- template <typename Geometry1, typename Geometry2>
- static inline
- bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
+ template <typename Geometry1, typename Geometry2, typename Strategy>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
{
- return ! geometry::covered_by(geometry1, geometry2);
+ return ! geometry::covered_by(geometry1, geometry2, strategy);
}
};
diff --git a/boost/geometry/algorithms/detail/disjoint/point_point.hpp b/boost/geometry/algorithms/detail/disjoint/point_point.hpp
index 7580b7287b..13ac34d718 100644
--- a/boost/geometry/algorithms/detail/disjoint/point_point.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/point_point.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland
-// This file was modified by Oracle on 2013, 2014, 2015.
-// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017.
+// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -59,6 +59,12 @@ namespace detail { namespace disjoint
template <std::size_t Dimension, std::size_t DimensionCount>
struct point_point_generic
{
+ template <typename Point1, typename Point2, typename Strategy>
+ static inline bool apply(Point1 const& p1, Point2 const& p2, Strategy const& )
+ {
+ return apply(p1, p2);
+ }
+
template <typename Point1, typename Point2>
static inline bool apply(Point1 const& p1, Point2 const& p2)
{
@@ -75,7 +81,7 @@ template <std::size_t DimensionCount>
struct point_point_generic<DimensionCount, DimensionCount>
{
template <typename Point1, typename Point2>
- static inline bool apply(Point1 const&, Point2 const&)
+ static inline bool apply(Point1 const&, Point2 const& )
{
return false;
}
@@ -135,6 +141,12 @@ private:
};
public:
+ template <typename Point1, typename Point2, typename Strategy>
+ static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& )
+ {
+ return apply(point1, point2);
+ }
+
template <typename Point1, typename Point2>
static inline bool apply(Point1 const& point1, Point2 const& point2)
{
diff --git a/boost/geometry/algorithms/detail/disjoint/segment_box.hpp b/boost/geometry/algorithms/detail/disjoint/segment_box.hpp
index cc0c7949e3..c2741ce72c 100644
--- a/boost/geometry/algorithms/detail/disjoint/segment_box.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/segment_box.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013-2014.
-// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013-2017.
+// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -22,19 +22,8 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_SEGMENT_BOX_HPP
#include <cstddef>
-#include <utility>
-#include <boost/numeric/conversion/cast.hpp>
-
-#include <boost/geometry/util/math.hpp>
-#include <boost/geometry/util/calculation_type.hpp>
-
-#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/tags.hpp>
-#include <boost/geometry/core/coordinate_dimension.hpp>
-#include <boost/geometry/core/point_type.hpp>
-
-#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
@@ -47,236 +36,19 @@ namespace boost { namespace geometry
namespace detail { namespace disjoint
{
-
-template <std::size_t I>
-struct compute_tmin_tmax_per_dim
-{
- template <typename SegmentPoint, typename Box, typename RelativeDistance>
- static inline void apply(SegmentPoint const& p0,
- SegmentPoint const& p1,
- Box const& box,
- RelativeDistance& ti_min,
- RelativeDistance& ti_max,
- RelativeDistance& diff)
- {
- typedef typename coordinate_type<Box>::type box_coordinate_type;
- typedef typename coordinate_type
- <
- SegmentPoint
- >::type point_coordinate_type;
-
- RelativeDistance c_p0 = boost::numeric_cast
- <
- point_coordinate_type
- >( geometry::get<I>(p0) );
-
- RelativeDistance c_p1 = boost::numeric_cast
- <
- point_coordinate_type
- >( geometry::get<I>(p1) );
-
- RelativeDistance c_b_min = boost::numeric_cast
- <
- box_coordinate_type
- >( geometry::get<geometry::min_corner, I>(box) );
-
- RelativeDistance c_b_max = boost::numeric_cast
- <
- box_coordinate_type
- >( geometry::get<geometry::max_corner, I>(box) );
-
- if ( geometry::get<I>(p1) >= geometry::get<I>(p0) )
- {
- diff = c_p1 - c_p0;
- ti_min = c_b_min - c_p0;
- ti_max = c_b_max - c_p0;
- }
- else
- {
- diff = c_p0 - c_p1;
- ti_min = c_p0 - c_b_max;
- ti_max = c_p0 - c_b_min;
- }
- }
-};
-
-
-template
-<
- typename RelativeDistance,
- typename SegmentPoint,
- typename Box,
- std::size_t I,
- std::size_t Dimension
->
-struct disjoint_segment_box_impl
-{
- template <typename RelativeDistancePair>
- static inline bool apply(SegmentPoint const& p0,
- SegmentPoint const& p1,
- Box const& box,
- RelativeDistancePair& t_min,
- RelativeDistancePair& t_max)
- {
- RelativeDistance ti_min, ti_max, diff;
-
- compute_tmin_tmax_per_dim<I>::apply(p0, p1, box, ti_min, ti_max, diff);
-
- if ( geometry::math::equals(diff, 0) )
- {
- if ( (geometry::math::equals(t_min.second, 0)
- && t_min.first > ti_max)
- ||
- (geometry::math::equals(t_max.second, 0)
- && t_max.first < ti_min)
- ||
- (math::sign(ti_min) * math::sign(ti_max) > 0) )
- {
- return true;
- }
- }
-
- RelativeDistance t_min_x_diff = t_min.first * diff;
- RelativeDistance t_max_x_diff = t_max.first * diff;
-
- if ( t_min_x_diff > ti_max * t_min.second
- || t_max_x_diff < ti_min * t_max.second )
- {
- return true;
- }
-
- if ( ti_min * t_min.second > t_min_x_diff )
- {
- t_min.first = ti_min;
- t_min.second = diff;
- }
- if ( ti_max * t_max.second < t_max_x_diff )
- {
- t_max.first = ti_max;
- t_max.second = diff;
- }
-
- if ( t_min.first > t_min.second || t_max.first < 0 )
- {
- return true;
- }
-
- return disjoint_segment_box_impl
- <
- RelativeDistance,
- SegmentPoint,
- Box,
- I + 1,
- Dimension
- >::apply(p0, p1, box, t_min, t_max);
- }
-};
-
-
-template
-<
- typename RelativeDistance,
- typename SegmentPoint,
- typename Box,
- std::size_t Dimension
->
-struct disjoint_segment_box_impl
- <
- RelativeDistance, SegmentPoint, Box, 0, Dimension
- >
-{
- static inline bool apply(SegmentPoint const& p0,
- SegmentPoint const& p1,
- Box const& box)
- {
- std::pair<RelativeDistance, RelativeDistance> t_min, t_max;
- RelativeDistance diff;
-
- compute_tmin_tmax_per_dim<0>::apply(p0, p1, box,
- t_min.first, t_max.first, diff);
-
- if ( geometry::math::equals(diff, 0) )
- {
- if ( geometry::math::equals(t_min.first, 0) ) { t_min.first = -1; }
- if ( geometry::math::equals(t_max.first, 0) ) { t_max.first = 1; }
-
- if (math::sign(t_min.first) * math::sign(t_max.first) > 0)
- {
- return true;
- }
- }
-
- if ( t_min.first > diff || t_max.first < 0 )
- {
- return true;
- }
-
- t_min.second = t_max.second = diff;
-
- return disjoint_segment_box_impl
- <
- RelativeDistance, SegmentPoint, Box, 1, Dimension
- >::apply(p0, p1, box, t_min, t_max);
- }
-};
-
-
-template
-<
- typename RelativeDistance,
- typename SegmentPoint,
- typename Box,
- std::size_t Dimension
->
-struct disjoint_segment_box_impl
- <
- RelativeDistance, SegmentPoint, Box, Dimension, Dimension
- >
-{
- template <typename RelativeDistancePair>
- static inline bool apply(SegmentPoint const&, SegmentPoint const&,
- Box const&,
- RelativeDistancePair&, RelativeDistancePair&)
- {
- return false;
- }
-};
-
-
-//=========================================================================
-
-
-template <typename Segment, typename Box>
struct disjoint_segment_box
-{
- static inline bool apply(Segment const& segment, Box const& box)
+{
+ template <typename Segment, typename Box, typename Strategy>
+ static inline bool apply(Segment const& segment, Box const& box, Strategy const& strategy)
{
- assert_dimension_equal<Segment, Box>();
-
- typedef typename util::calculation_type::geometric::binary
- <
- Segment, Box, void
- >::type relative_distance_type;
-
- typedef typename point_type<Segment>::type segment_point_type;
- segment_point_type p0, p1;
- geometry::detail::assign_point_from_index<0>(segment, p0);
- geometry::detail::assign_point_from_index<1>(segment, p1);
-
- return disjoint_segment_box_impl
- <
- relative_distance_type, segment_point_type, Box,
- 0, dimension<Box>::value
- >::apply(p0, p1, box);
+ return strategy.apply(segment, box);
}
};
-
}} // namespace detail::disjoint
#endif // DOXYGEN_NO_DETAIL
-
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
@@ -284,7 +56,7 @@ namespace dispatch
template <typename Segment, typename Box, std::size_t DimensionCount>
struct disjoint<Segment, Box, DimensionCount, segment_tag, box_tag, false>
- : detail::disjoint::disjoint_segment_box<Segment, Box>
+ : detail::disjoint::disjoint_segment_box
{};
diff --git a/boost/geometry/algorithms/detail/envelope/box.hpp b/boost/geometry/algorithms/detail/envelope/box.hpp
index 3790262948..795f51392e 100644
--- a/boost/geometry/algorithms/detail/envelope/box.hpp
+++ b/boost/geometry/algorithms/detail/envelope/box.hpp
@@ -4,9 +4,10 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2016.
+// Modifications copyright (c) 2015-2016, 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
// Distributed under the Boost Software License, Version 1.0.
@@ -97,8 +98,10 @@ struct envelope_indexed_box_on_spheroid
struct envelope_box
{
- template<typename BoxIn, typename BoxOut>
- static inline void apply(BoxIn const& box_in, BoxOut& mbr)
+ template<typename BoxIn, typename BoxOut, typename Strategy>
+ static inline void apply(BoxIn const& box_in,
+ BoxOut& mbr,
+ Strategy const&)
{
envelope_indexed_box
<
@@ -115,8 +118,10 @@ struct envelope_box
struct envelope_box_on_spheroid
{
- template <typename BoxIn, typename BoxOut>
- static inline void apply(BoxIn const& box_in, BoxOut& mbr)
+ template <typename BoxIn, typename BoxOut, typename Strategy>
+ static inline void apply(BoxIn const& box_in,
+ BoxOut& mbr,
+ Strategy const&)
{
BoxIn box_in_normalized = detail::return_normalized<BoxIn>(box_in);
diff --git a/boost/geometry/algorithms/detail/envelope/implementation.hpp b/boost/geometry/algorithms/detail/envelope/implementation.hpp
index c1dbf8e589..d549700791 100644
--- a/boost/geometry/algorithms/detail/envelope/implementation.hpp
+++ b/boost/geometry/algorithms/detail/envelope/implementation.hpp
@@ -4,9 +4,10 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2016.
+// Modifications copyright (c) 2015-2016, 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
@@ -45,8 +46,8 @@ namespace detail { namespace envelope
struct envelope_polygon
{
- template <typename Polygon, typename Box>
- static inline void apply(Polygon const& polygon, Box& mbr)
+ template <typename Polygon, typename Box, typename Strategy>
+ static inline void apply(Polygon const& polygon, Box& mbr, Strategy const& strategy)
{
typename ring_return_type<Polygon const>::type ext_ring
= exterior_ring(polygon);
@@ -57,12 +58,12 @@ struct envelope_polygon
envelope_multi_range
<
envelope_range
- >::apply(interior_rings(polygon), mbr);
+ >::apply(interior_rings(polygon), mbr, strategy);
}
else
{
// otherwise, consider only the exterior ring
- envelope_range::apply(ext_ring, mbr);
+ envelope_range::apply(ext_ring, mbr, strategy);
}
}
};
diff --git a/boost/geometry/algorithms/detail/envelope/interface.hpp b/boost/geometry/algorithms/detail/envelope/interface.hpp
index befe4e42db..8e9c35b395 100644
--- a/boost/geometry/algorithms/detail/envelope/interface.hpp
+++ b/boost/geometry/algorithms/detail/envelope/interface.hpp
@@ -4,10 +4,12 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2016, 2017.
+// Modifications copyright (c) 2015-2017, 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
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -27,54 +29,124 @@
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+#include <boost/geometry/strategies/default_strategy.hpp>
+#include <boost/geometry/strategies/envelope.hpp>
+#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
+#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
+#include <boost/geometry/strategies/geographic/envelope_segment.hpp>
namespace boost { namespace geometry
{
-namespace resolve_variant
+namespace resolve_strategy
{
template <typename Geometry>
struct envelope
{
+ template <typename Box, typename Strategy>
+ static inline void apply(Geometry const& geometry,
+ Box& box,
+ Strategy const& strategy)
+ {
+ dispatch::envelope<Geometry>::apply(geometry, box, strategy);
+ }
+
template <typename Box>
- static inline void apply(Geometry const& geometry, Box& box)
+ static inline void apply(Geometry const& geometry,
+ Box& box,
+ default_strategy)
+ {
+ typedef typename point_type<Geometry>::type point_type;
+ typedef typename coordinate_type<point_type>::type coordinate_type;
+
+ typedef typename strategy::envelope::services::default_strategy
+ <
+ typename cs_tag<point_type>::type,
+ coordinate_type
+ >::type strategy_type;
+
+ dispatch::envelope<Geometry>::apply(geometry, box, strategy_type());
+ }
+};
+
+} // namespace resolve_strategy
+
+namespace resolve_variant
+{
+
+template <typename Geometry>
+struct envelope
+{
+ template <typename Box, typename Strategy>
+ static inline void apply(Geometry const& geometry,
+ Box& box,
+ Strategy const& strategy)
{
concepts::check<Geometry const>();
concepts::check<Box>();
- dispatch::envelope<Geometry>::apply(geometry, box);
+ resolve_strategy::envelope<Geometry>::apply(geometry, box, strategy);
}
};
+
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct envelope<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
- template <typename Box>
+ template <typename Box, typename Strategy>
struct visitor: boost::static_visitor<void>
{
Box& m_box;
+ Strategy const& m_strategy;
- visitor(Box& box): m_box(box) {}
+ visitor(Box& box, Strategy const& strategy)
+ : m_box(box)
+ , m_strategy(strategy)
+ {}
template <typename Geometry>
void operator()(Geometry const& geometry) const
{
- envelope<Geometry>::apply(geometry, m_box);
+ envelope<Geometry>::apply(geometry, m_box, m_strategy);
}
};
- template <typename Box>
+ template <typename Box, typename Strategy>
static inline void
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
- Box& box)
+ Box& box,
+ Strategy const& strategy)
{
- boost::apply_visitor(visitor<Box>(box), geometry);
+ boost::apply_visitor(visitor<Box, Strategy>(box, strategy), geometry);
}
};
} // namespace resolve_variant
+/*!
+\brief \brief_calc{envelope (with strategy)}
+\ingroup envelope
+\details \details_calc{envelope,\det_envelope}.
+\tparam Geometry \tparam_geometry
+\tparam Box \tparam_box
+\tparam Strategy \tparam_strategy{Envelope}
+\param geometry \param_geometry
+\param mbr \param_box \param_set{envelope}
+\param strategy \param_strategy{envelope}
+
+\qbk{distinguish,with strategy}
+\qbk{[include reference/algorithms/envelope.qbk]}
+\qbk{
+[heading Example]
+[envelope] [envelope_output]
+}
+*/
+template<typename Geometry, typename Box, typename Strategy>
+inline void envelope(Geometry const& geometry, Box& mbr, Strategy const& strategy)
+{
+ resolve_variant::envelope<Geometry>::apply(geometry, mbr, strategy);
+}
/*!
\brief \brief_calc{envelope}
@@ -94,7 +166,7 @@ struct envelope<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
template<typename Geometry, typename Box>
inline void envelope(Geometry const& geometry, Box& mbr)
{
- resolve_variant::envelope<Geometry>::apply(geometry, mbr);
+ resolve_variant::envelope<Geometry>::apply(geometry, mbr, default_strategy());
}
@@ -104,6 +176,32 @@ inline void envelope(Geometry const& geometry, Box& mbr)
\details \details_calc{return_envelope,\det_envelope}. \details_return{envelope}
\tparam Box \tparam_box
\tparam Geometry \tparam_geometry
+\tparam Strategy \tparam_strategy{Envelope}
+\param geometry \param_geometry
+\param strategy \param_strategy{envelope}
+\return \return_calc{envelope}
+
+\qbk{distinguish,with strategy}
+\qbk{[include reference/algorithms/envelope.qbk]}
+\qbk{
+[heading Example]
+[return_envelope] [return_envelope_output]
+}
+*/
+template<typename Box, typename Geometry, typename Strategy>
+inline Box return_envelope(Geometry const& geometry, Strategy const& strategy)
+{
+ Box mbr;
+ resolve_variant::envelope<Geometry>::apply(geometry, mbr, strategy);
+ return mbr;
+}
+
+/*!
+\brief \brief_calc{envelope}
+\ingroup envelope
+\details \details_calc{return_envelope,\det_envelope}. \details_return{envelope}
+\tparam Box \tparam_box
+\tparam Geometry \tparam_geometry
\param geometry \param_geometry
\return \return_calc{envelope}
@@ -117,7 +215,7 @@ template<typename Box, typename Geometry>
inline Box return_envelope(Geometry const& geometry)
{
Box mbr;
- resolve_variant::envelope<Geometry>::apply(geometry, mbr);
+ resolve_variant::envelope<Geometry>::apply(geometry, mbr, default_strategy());
return mbr;
}
diff --git a/boost/geometry/algorithms/detail/envelope/linear.hpp b/boost/geometry/algorithms/detail/envelope/linear.hpp
index 49c3cf3135..09d8a76da5 100644
--- a/boost/geometry/algorithms/detail/envelope/linear.hpp
+++ b/boost/geometry/algorithms/detail/envelope/linear.hpp
@@ -4,9 +4,10 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2016.
+// Modifications copyright (c) 2015-2016, 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
// Distributed under the Boost Software License, Version 1.0.
@@ -36,12 +37,15 @@ namespace detail { namespace envelope
struct envelope_linestring_on_spheroid
{
- template <typename Linestring, typename Box>
- static inline void apply(Linestring const& linestring, Box& mbr)
+ template <typename Linestring, typename Box, typename Strategy>
+ static inline void apply(Linestring const& linestring,
+ Box& mbr,
+ Strategy const& strategy)
{
envelope_range::apply(geometry::segments_begin(linestring),
geometry::segments_end(linestring),
- mbr);
+ mbr,
+ strategy);
}
};
@@ -65,6 +69,11 @@ struct envelope<Linestring, linestring_tag, spherical_equatorial_tag>
: detail::envelope::envelope_linestring_on_spheroid
{};
+template <typename Linestring>
+struct envelope<Linestring, linestring_tag, geographic_tag>
+ : detail::envelope::envelope_linestring_on_spheroid
+{};
+
template <typename MultiLinestring, typename CS_Tag>
struct envelope
@@ -86,6 +95,15 @@ struct envelope
>
{};
+template <typename MultiLinestring>
+struct envelope
+ <
+ MultiLinestring, multi_linestring_tag, geographic_tag
+ > : detail::envelope::envelope_multi_range_on_spheroid
+ <
+ detail::envelope::envelope_linestring_on_spheroid
+ >
+{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
diff --git a/boost/geometry/algorithms/detail/envelope/multipoint.hpp b/boost/geometry/algorithms/detail/envelope/multipoint.hpp
index 210debfdba..efee4701c9 100644
--- a/boost/geometry/algorithms/detail/envelope/multipoint.hpp
+++ b/boost/geometry/algorithms/detail/envelope/multipoint.hpp
@@ -1,7 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2015, Oracle and/or its affiliates.
+// Copyright (c) 2015-2016, 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
// Distributed under the Boost Software License, Version 1.0.
@@ -226,8 +227,8 @@ private:
}
public:
- template <typename MultiPoint, typename Box>
- static inline void apply(MultiPoint const& multipoint, Box& mbr)
+ template <typename MultiPoint, typename Box, typename Strategy>
+ static inline void apply(MultiPoint const& multipoint, Box& mbr, Strategy const& strategy)
{
typedef typename point_type<MultiPoint>::type point_type;
typedef typename coordinate_type<MultiPoint>::type coordinate_type;
@@ -255,7 +256,7 @@ public:
return dispatch::envelope
<
typename boost::range_value<MultiPoint>::type
- >::apply(range::front(multipoint), mbr);
+ >::apply(range::front(multipoint), mbr, strategy);
}
// analyze the points and put the non-pole ones in the
@@ -329,7 +330,7 @@ public:
// compute envelope for higher coordinates
iterator_type it = boost::begin(multipoint);
- envelope_one_point<2, dimension<Box>::value>::apply(*it, mbr);
+ envelope_one_point<2, dimension<Box>::value>::apply(*it, mbr, strategy);
for (++it; it != boost::end(multipoint); ++it)
{
@@ -338,7 +339,7 @@ public:
strategy::compare::default_strategy,
strategy::compare::default_strategy,
2, dimension<Box>::value
- >::apply(mbr, *it);
+ >::apply(mbr, *it, strategy);
}
}
};
diff --git a/boost/geometry/algorithms/detail/envelope/point.hpp b/boost/geometry/algorithms/detail/envelope/point.hpp
index e914e7e8a0..ee0559bf5f 100644
--- a/boost/geometry/algorithms/detail/envelope/point.hpp
+++ b/boost/geometry/algorithms/detail/envelope/point.hpp
@@ -4,9 +4,10 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2016.
+// Modifications copyright (c) 2015-2016, 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
// Distributed under the Boost Software License, Version 1.0.
@@ -58,8 +59,8 @@ struct envelope_one_point
>::apply(point, box_corner);
}
- template <typename Point, typename Box>
- static inline void apply(Point const& point, Box& mbr)
+ template <typename Point, typename Box, typename Strategy>
+ static inline void apply(Point const& point, Box& mbr, Strategy const&)
{
apply<min_corner>(point, mbr);
apply<max_corner>(point, mbr);
@@ -69,8 +70,8 @@ struct envelope_one_point
struct envelope_point_on_spheroid
{
- template<typename Point, typename Box>
- static inline void apply(Point const& point, Box& mbr)
+ template<typename Point, typename Box, typename Strategy>
+ static inline void apply(Point const& point, Box& mbr, Strategy const& strategy)
{
Point normalized_point = detail::return_normalized<Point>(point);
@@ -88,7 +89,7 @@ struct envelope_point_on_spheroid
envelope_one_point
<
2, dimension<Point>::value
- >::apply(normalized_point, mbr);
+ >::apply(normalized_point, mbr, strategy);
}
};
diff --git a/boost/geometry/algorithms/detail/envelope/range.hpp b/boost/geometry/algorithms/detail/envelope/range.hpp
index 63b518114b..b5591f61ab 100644
--- a/boost/geometry/algorithms/detail/envelope/range.hpp
+++ b/boost/geometry/algorithms/detail/envelope/range.hpp
@@ -4,9 +4,10 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2016.
+// Modifications copyright (c) 2015-2016, 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
@@ -51,8 +52,11 @@ namespace detail { namespace envelope
// implementation for simple ranges
struct envelope_range
{
- template <typename Iterator, typename Box>
- static inline void apply(Iterator first, Iterator last, Box& mbr)
+ template <typename Iterator, typename Box, typename Strategy>
+ static inline void apply(Iterator first,
+ Iterator last,
+ Box& mbr,
+ Strategy const& strategy)
{
typedef typename std::iterator_traits<Iterator>::value_type value_type;
@@ -63,20 +67,20 @@ struct envelope_range
if (it != last)
{
// initialize box with first element in range
- dispatch::envelope<value_type>::apply(*it, mbr);
+ dispatch::envelope<value_type>::apply(*it, mbr, strategy);
// consider now the remaining elements in the range (if any)
for (++it; it != last; ++it)
{
- dispatch::expand<Box, value_type>::apply(mbr, *it);
+ dispatch::expand<Box, value_type>::apply(mbr, *it, strategy);
}
}
}
- template <typename Range, typename Box>
- static inline void apply(Range const& range, Box& mbr)
+ template <typename Range, typename Box, typename Strategy>
+ static inline void apply(Range const& range, Box& mbr, Strategy const& strategy)
{
- return apply(boost::begin(range), boost::end(range), mbr);
+ return apply(boost::begin(range), boost::end(range), mbr, strategy);
}
};
@@ -85,8 +89,10 @@ struct envelope_range
template <typename EnvelopePolicy>
struct envelope_multi_range
{
- template <typename MultiRange, typename Box>
- static inline void apply(MultiRange const& multirange, Box& mbr)
+ template <typename MultiRange, typename Box, typename Strategy>
+ static inline void apply(MultiRange const& multirange,
+ Box& mbr,
+ Strategy const& strategy)
{
typedef typename boost::range_iterator
<
@@ -103,14 +109,14 @@ struct envelope_multi_range
if (initialized)
{
Box helper_mbr;
- EnvelopePolicy::apply(*it, helper_mbr);
+ EnvelopePolicy::apply(*it, helper_mbr, strategy);
- dispatch::expand<Box, Box>::apply(mbr, helper_mbr);
+ dispatch::expand<Box, Box>::apply(mbr, helper_mbr, strategy);
}
else
{
// compute the initial envelope
- EnvelopePolicy::apply(*it, mbr);
+ EnvelopePolicy::apply(*it, mbr, strategy);
initialized = true;
}
}
@@ -129,8 +135,10 @@ struct envelope_multi_range
template <typename EnvelopePolicy>
struct envelope_multi_range_on_spheroid
{
- template <typename MultiRange, typename Box>
- static inline void apply(MultiRange const& multirange, Box& mbr)
+ template <typename MultiRange, typename Box, typename Strategy>
+ static inline void apply(MultiRange const& multirange,
+ Box& mbr,
+ Strategy const& strategy)
{
typedef typename boost::range_iterator
<
@@ -147,7 +155,7 @@ struct envelope_multi_range_on_spheroid
if (! geometry::is_empty(*it))
{
Box helper_box;
- EnvelopePolicy::apply(*it, helper_box);
+ EnvelopePolicy::apply(*it, helper_box, strategy);
boxes.push_back(helper_box);
}
}
@@ -159,7 +167,7 @@ struct envelope_multi_range_on_spheroid
// and the MBR is simply initialized
if (! boxes.empty())
{
- envelope_range_of_boxes::apply(boxes, mbr);
+ envelope_range_of_boxes::apply(boxes, mbr, strategy);
}
else
{
diff --git a/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp b/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp
index 64bdb9b9cb..f61fc422de 100644
--- a/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp
+++ b/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp
@@ -1,7 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2015, Oracle and/or its affiliates.
+// Copyright (c) 2015-2016, 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
// Distributed under the Boost Software License, Version 1.0.
@@ -149,8 +150,10 @@ struct envelope_range_of_longitudes
template <std::size_t Dimension, std::size_t DimensionCount>
struct envelope_range_of_boxes_by_expansion
{
- template <typename RangeOfBoxes, typename Box>
- static inline void apply(RangeOfBoxes const& range_of_boxes, Box& mbr)
+ template <typename RangeOfBoxes, typename Box, typename Strategy>
+ static inline void apply(RangeOfBoxes const& range_of_boxes,
+ Box& mbr,
+ Strategy const& strategy)
{
typedef typename boost::range_value<RangeOfBoxes>::type box_type;
@@ -196,7 +199,7 @@ struct envelope_range_of_boxes_by_expansion
min_corner,
Dimension,
DimensionCount
- >::apply(mbr, *it);
+ >::apply(mbr, *it, strategy);
detail::expand::indexed_loop
<
@@ -205,7 +208,7 @@ struct envelope_range_of_boxes_by_expansion
max_corner,
Dimension,
DimensionCount
- >::apply(mbr, *it);
+ >::apply(mbr, *it, strategy);
}
}
@@ -225,8 +228,10 @@ struct envelope_range_of_boxes
}
};
- template <typename RangeOfBoxes, typename Box>
- static inline void apply(RangeOfBoxes const& range_of_boxes, Box& mbr)
+ template <typename RangeOfBoxes, typename Box, typename Strategy>
+ static inline void apply(RangeOfBoxes const& range_of_boxes,
+ Box& mbr,
+ Strategy const& strategy)
{
// boxes in the range are assumed to be normalized already
@@ -313,7 +318,7 @@ struct envelope_range_of_boxes
envelope_range_of_boxes_by_expansion
<
2, dimension<Box>::value
- >::apply(range_of_boxes, mbr);
+ >::apply(range_of_boxes, mbr, strategy);
}
};
diff --git a/boost/geometry/algorithms/detail/envelope/segment.hpp b/boost/geometry/algorithms/detail/envelope/segment.hpp
index 6186e72a3a..7631e84883 100644
--- a/boost/geometry/algorithms/detail/envelope/segment.hpp
+++ b/boost/geometry/algorithms/detail/envelope/segment.hpp
@@ -4,9 +4,10 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2015, 2016.
-// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015-2017.
+// Modifications copyright (c) 2015-2017, 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
@@ -26,6 +27,7 @@
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/srs.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -34,10 +36,9 @@
#include <boost/geometry/geometries/helper_geometry.hpp>
-#include <boost/geometry/strategies/compare.hpp>
+#include <boost/geometry/formulas/vertex_latitude.hpp>
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
-#include <boost/geometry/algorithms/detail/normalize.hpp>
#include <boost/geometry/algorithms/detail/envelope/point.hpp>
#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
@@ -46,7 +47,6 @@
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
-
namespace boost { namespace geometry
{
@@ -54,63 +54,36 @@ namespace boost { namespace geometry
namespace detail { namespace envelope
{
-
-template <std::size_t Dimension, std::size_t DimensionCount>
-struct envelope_one_segment
+template <typename CalculationType, typename CS_Tag>
+struct envelope_segment_call_vertex_latitude
{
- template<typename Point, typename Box>
- static inline void apply(Point const& p1, Point const& p2, Box& mbr)
+ template <typename T1, typename T2, typename Strategy>
+ static inline CalculationType apply(T1 const& lat1,
+ T2 const& alp1,
+ Strategy const& )
{
- envelope_one_point<Dimension, DimensionCount>::apply(p1, mbr);
- detail::expand::point_loop
- <
- strategy::compare::default_strategy,
- strategy::compare::default_strategy,
- Dimension,
- DimensionCount
- >::apply(mbr, p2);
+ return geometry::formula::vertex_latitude<CalculationType, CS_Tag>
+ ::apply(lat1, alp1);
}
};
-
-// Computes the MBR of a segment given by (lon1, lat1) and (lon2,
-// lat2), and with azimuths a1 and a2 at the two endpoints of the
-// segment.
-// It is assumed that the spherical coordinates of the segment are
-// normalized and in radians.
-// The longitudes and latitudes of the endpoints are overridden by
-// those of the box.
-class compute_mbr_of_segment
+template <typename CalculationType>
+struct envelope_segment_call_vertex_latitude<CalculationType, geographic_tag>
{
-private:
- // computes the azimuths of the segment with endpoints (lon1, lat1)
- // and (lon2, lat2)
- // radians
- template <typename CalculationType>
- static inline void azimuths(CalculationType const& lon1,
- CalculationType const& lat1,
- CalculationType const& lon2,
- CalculationType const& lat2,
- CalculationType& a1,
- CalculationType& a2)
+ template <typename T1, typename T2, typename Strategy>
+ static inline CalculationType apply(T1 const& lat1,
+ T2 const& alp1,
+ Strategy const& strategy)
{
- BOOST_GEOMETRY_ASSERT(lon1 <= lon2);
-
- CalculationType dlon = lon2 - lon1;
- CalculationType sin_dlon = sin(dlon);
- CalculationType cos_dlon = cos(dlon);
- CalculationType cos_lat1 = cos(lat1);
- CalculationType cos_lat2 = cos(lat2);
- CalculationType sin_lat1 = sin(lat1);
- CalculationType sin_lat2 = sin(lat2);
-
- a1 = atan2(sin_dlon * cos_lat2,
- cos_lat1 * sin_lat2 - sin_lat1 * cos_lat2 * cos_dlon);
-
- a2 = atan2(-sin_dlon * cos_lat1,
- cos_lat2 * sin_lat1 - sin_lat2 * cos_lat1 * cos_dlon);
- a2 += math::pi<CalculationType>();
+ return geometry::formula::vertex_latitude<CalculationType, geographic_tag>
+ ::apply(lat1, alp1, strategy.model());
}
+};
+
+template <typename CS_Tag>
+class envelope_segment_impl
+{
+private:
// degrees or radians
template <typename CalculationType>
@@ -134,8 +107,8 @@ private:
static CalculationType const pi_half = math::half_pi<CalculationType>();
return (a1 < a2)
- ? (a1 < pi_half && pi_half < a2)
- : (a1 > pi_half && pi_half > a2);
+ ? (a1 < pi_half && pi_half < a2)
+ : (a1 > pi_half && pi_half > a2);
}
// radians or degrees
@@ -151,21 +124,13 @@ private:
return math::abs(lon1 - lon2) > constants::half_period(); // > pi
}
- // radians
- template <typename CalculationType>
- static inline CalculationType max_latitude(CalculationType const& azimuth,
- CalculationType const& latitude)
- {
- // azimuth and latitude are assumed to be in radians
- return acos( math::abs(cos(latitude) * sin(azimuth)) );
- }
-
// degrees or radians
- template <typename Units, typename CalculationType>
+ template <typename Units, typename CalculationType, typename Strategy>
static inline void compute_box_corners(CalculationType& lon1,
CalculationType& lat1,
CalculationType& lon2,
- CalculationType& lat2)
+ CalculationType& lat2,
+ Strategy const& strategy)
{
// coordinates are assumed to be in radians
BOOST_GEOMETRY_ASSERT(lon1 <= lon2);
@@ -175,13 +140,14 @@ private:
CalculationType lon2_rad = math::as_radian<Units>(lon2);
CalculationType lat2_rad = math::as_radian<Units>(lat2);
- CalculationType a1 = 0, a2 = 0;
- azimuths(lon1_rad, lat1_rad, lon2_rad, lat2_rad, a1, a2);
+ CalculationType a1, a2;
+ strategy.apply(lon1_rad, lat1_rad, lon2_rad, lat2_rad, a1, a2);
if (lat1 > lat2)
{
std::swap(lat1, lat2);
std::swap(lat1_rad, lat2_rad);
+ std::swap(a1, a2);
}
if (math::equals(a1, a2))
@@ -192,12 +158,16 @@ private:
if (contains_pi_half(a1, a2))
{
+ CalculationType p_max = envelope_segment_call_vertex_latitude
+ <CalculationType, CS_Tag>::apply(lat1_rad, a1, strategy);
+
CalculationType const mid_lat = lat1 + lat2;
if (mid_lat < 0)
{
// update using min latitude
- CalculationType const lat_min_rad = -max_latitude(a1, lat1_rad);
- CalculationType const lat_min = math::from_radian<Units>(lat_min_rad);
+ CalculationType const lat_min_rad = -p_max;
+ CalculationType const lat_min
+ = math::from_radian<Units>(lat_min_rad);
if (lat1 > lat_min)
{
@@ -207,8 +177,9 @@ private:
else if (mid_lat > 0)
{
// update using max latitude
- CalculationType const lat_max_rad = max_latitude(a1, lat1_rad);
- CalculationType const lat_max = math::from_radian<Units>(lat_max_rad);
+ CalculationType const lat_max_rad = p_max;
+ CalculationType const lat_max
+ = math::from_radian<Units>(lat_max_rad);
if (lat2 < lat_max)
{
@@ -218,11 +189,12 @@ private:
}
}
- template <typename Units, typename CalculationType>
+ template <typename Units, typename CalculationType, typename Strategy>
static inline void apply(CalculationType& lon1,
CalculationType& lat1,
CalculationType& lon2,
- CalculationType& lat2)
+ CalculationType& lat2,
+ Strategy const& strategy)
{
typedef math::detail::constants_on_spheroid
<
@@ -278,16 +250,22 @@ private:
swap(lon1, lat1, lon2, lat2);
}
- compute_box_corners<Units>(lon1, lat1, lon2, lat2);
+ compute_box_corners<Units>(lon1, lat1, lon2, lat2, strategy);
}
public:
- template <typename Units, typename CalculationType, typename Box>
+ template <
+ typename Units,
+ typename CalculationType,
+ typename Box,
+ typename Strategy
+ >
static inline void apply(CalculationType lon1,
CalculationType lat1,
CalculationType lon2,
CalculationType lat2,
- Box& mbr)
+ Box& mbr,
+ Strategy const& strategy)
{
typedef typename coordinate_type<Box>::type box_coordinate_type;
@@ -298,7 +276,7 @@ public:
helper_box_type radian_mbr;
- apply<Units>(lon1, lat1, lon2, lat2);
+ apply<Units>(lon1, lat1, lon2, lat2, strategy);
geometry::set
<
@@ -324,29 +302,42 @@ public:
}
};
+template <std::size_t Dimension, std::size_t DimensionCount>
+struct envelope_one_segment
+{
+ template<typename Point, typename Box, typename Strategy>
+ static inline void apply(Point const& p1,
+ Point const& p2,
+ Box& mbr,
+ Strategy const& strategy)
+ {
+ envelope_one_point<Dimension, DimensionCount>::apply(p1, mbr, strategy);
+ detail::expand::point_loop
+ <
+ strategy::compare::default_strategy,
+ strategy::compare::default_strategy,
+ Dimension,
+ DimensionCount
+ >::apply(mbr, p2, strategy);
+ }
+};
+
template <std::size_t DimensionCount>
-struct envelope_segment_on_sphere
+struct envelope_segment
{
- template <typename Point, typename Box>
- static inline void apply(Point const& p1, Point const& p2, Box& mbr)
+ template <typename Point, typename Box, typename Strategy>
+ static inline void apply(Point const& p1,
+ Point const& p2,
+ Box& mbr,
+ Strategy const& strategy)
{
// first compute the envelope range for the first two coordinates
- Point p1_normalized = detail::return_normalized<Point>(p1);
- Point p2_normalized = detail::return_normalized<Point>(p2);
-
- typedef typename coordinate_system<Point>::type::units units_type;
-
- compute_mbr_of_segment::template apply<units_type>(
- geometry::get<0>(p1_normalized),
- geometry::get<1>(p1_normalized),
- geometry::get<0>(p2_normalized),
- geometry::get<1>(p2_normalized),
- mbr);
+ strategy.apply(p1, p2, mbr);
// now compute the envelope range for coordinates of
// dimension 2 and higher
- envelope_one_segment<2, DimensionCount>::apply(p1, p2, mbr);
+ envelope_one_segment<2, DimensionCount>::apply(p1, p2, mbr, strategy);
}
template <typename Segment, typename Box>
@@ -359,21 +350,6 @@ struct envelope_segment_on_sphere
}
};
-
-
-template <std::size_t DimensionCount, typename CS_Tag>
-struct envelope_segment
- : envelope_one_segment<0, DimensionCount>
-{};
-
-
-template <std::size_t DimensionCount>
-struct envelope_segment<DimensionCount, spherical_equatorial_tag>
- : envelope_segment_on_sphere<DimensionCount>
-{};
-
-
-
}} // namespace detail::envelope
#endif // DOXYGEN_NO_DETAIL
@@ -383,23 +359,24 @@ namespace dispatch
{
-template <typename Segment, typename CS_Tag>
-struct envelope<Segment, segment_tag, CS_Tag>
+template <typename Segment>
+struct envelope<Segment, segment_tag>
{
- template <typename Box>
- static inline void apply(Segment const& segment, Box& mbr)
+ template <typename Box, typename Strategy>
+ static inline void apply(Segment const& segment,
+ Box& mbr,
+ Strategy const& strategy)
{
typename point_type<Segment>::type p[2];
detail::assign_point_from_index<0>(segment, p[0]);
detail::assign_point_from_index<1>(segment, p[1]);
detail::envelope::envelope_segment
<
- dimension<Segment>::value, CS_Tag
- >::apply(p[0], p[1], mbr);
+ dimension<Segment>::value
+ >::apply(p[0], p[1], mbr, strategy);
}
};
-
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
diff --git a/boost/geometry/algorithms/detail/equals/collect_vectors.hpp b/boost/geometry/algorithms/detail/equals/collect_vectors.hpp
index eab73ea680..9625f18426 100644
--- a/boost/geometry/algorithms/detail/equals/collect_vectors.hpp
+++ b/boost/geometry/algorithms/detail/equals/collect_vectors.hpp
@@ -3,7 +3,12 @@
// 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) 2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2014-2017 Adam Wulkiewicz, Lodz, Poland.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017 Oracle and/or its affiliates.
+
+// 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.
@@ -20,6 +25,7 @@
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
#include <boost/geometry/algorithms/detail/normalize.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/interior_rings.hpp>
@@ -32,21 +38,37 @@
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/range.hpp>
+#include <boost/geometry/views/detail/normalized_view.hpp>
+
+#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
+#include <boost/geometry/strategies/spherical/ssf.hpp>
+
namespace boost { namespace geometry
{
+// TODO: dispatch only by SideStrategy instead of Geometry/CSTag?
+
// Since these vectors (though ray would be a better name) are used in the
// implementation of equals() for Areal geometries the internal representation
-// should be consistent with the default side strategy for CS because currently
-// it's used in other relops.
-
-template <
+// should be consistent with the side strategy.
+template
+<
typename T,
typename Geometry,
+ typename SideStrategy,
typename CSTag = typename cs_tag<Geometry>::type
>
struct collected_vector
+ : nyi::not_implemented_tag
+{};
+
+// compatible with side_by_triangle cartesian strategy
+template <typename T, typename Geometry, typename CT, typename CSTag>
+struct collected_vector
+ <
+ T, Geometry, strategy::side::side_by_triangle<CT>, CSTag
+ >
{
typedef T type;
@@ -136,8 +158,13 @@ private:
//T dx_0, dy_0;
};
-template <typename T, typename Geometry>
-struct collected_vector<T, Geometry, spherical_equatorial_tag>
+// Compatible with spherical_side_formula which currently
+// is the default spherical and geographical strategy
+template <typename T, typename Geometry, typename CT, typename CSTag>
+struct collected_vector
+ <
+ T, Geometry, strategy::side::spherical_side_formula<CT>, CSTag
+ >
{
typedef T type;
@@ -232,11 +259,27 @@ private:
vector_type next; // used for collinearity check
};
-template <typename T, typename Geometry>
-struct collected_vector<T, Geometry, spherical_polar_tag>
- : public collected_vector<T, Geometry, spherical_equatorial_tag>
+// Specialization for spherical polar
+template <typename T, typename Geometry, typename CT>
+struct collected_vector
+ <
+ T, Geometry,
+ strategy::side::spherical_side_formula<CT>,
+ spherical_polar_tag
+ >
+ : public collected_vector
+ <
+ T, Geometry,
+ strategy::side::spherical_side_formula<CT>,
+ spherical_equatorial_tag
+ >
{
- typedef collected_vector<T, Geometry, spherical_equatorial_tag> base_type;
+ typedef collected_vector
+ <
+ T, Geometry,
+ strategy::side::spherical_side_formula<CT>,
+ spherical_equatorial_tag
+ > base_type;
collected_vector() {}
@@ -265,24 +308,6 @@ private:
}
};
-// This is consistent with the currently used default geographic side
-// and intersection strategies. Spherical strategies are used by default.
-// When default strategies are changed in the future this specialization
-// should be changed too.
-template <typename T, typename Geometry>
-struct collected_vector<T, Geometry, geographic_tag>
- : public collected_vector<T, Geometry, spherical_equatorial_tag>
-{
- typedef collected_vector<T, Geometry, spherical_equatorial_tag> base_type;
-
- collected_vector() {}
-
- template <typename Point>
- collected_vector(Point const& p1, Point const& p2)
- : base_type(p1, p2)
- {}
-};
-
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace collect_vectors
@@ -297,6 +322,18 @@ struct range_collect_vectors
static inline void apply(Collection& collection, Range const& range)
{
+ typedef geometry::detail::normalized_view
+ <
+ Range const
+ > normalized_range_type;
+
+ apply_impl(collection, normalized_range_type(range));
+ }
+
+private:
+ template <typename NormalizedRange>
+ static inline void apply_impl(Collection& collection, NormalizedRange const& range)
+ {
if (boost::size(range) < 2)
{
return;
@@ -305,7 +342,7 @@ struct range_collect_vectors
typedef typename boost::range_size<Collection>::type collection_size_t;
collection_size_t c_old_size = boost::size(collection);
- typedef typename boost::range_iterator<Range const>::type iterator;
+ typedef typename boost::range_iterator<NormalizedRange const>::type iterator;
bool is_first = true;
iterator it = boost::begin(range);
diff --git a/boost/geometry/algorithms/detail/expand/box.hpp b/boost/geometry/algorithms/detail/expand/box.hpp
index 4c89e6f1d4..3edb23f5ae 100644
--- a/boost/geometry/algorithms/detail/expand/box.hpp
+++ b/boost/geometry/algorithms/detail/expand/box.hpp
@@ -5,9 +5,10 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2016.
+// Modifications copyright (c) 2015-2016, 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
// Distributed under the Boost Software License, Version 1.0.
@@ -44,16 +45,18 @@ namespace detail { namespace expand
struct box_on_spheroid
{
- template <typename BoxOut, typename BoxIn>
- static inline void apply(BoxOut& box_out, BoxIn const& box_in)
+ template <typename BoxOut, typename BoxIn, typename Strategy>
+ static inline void apply(BoxOut& box_out,
+ BoxIn const& box_in,
+ Strategy const& strategy)
{
// normalize both boxes and convert box-in to be of type of box-out
BoxOut mbrs[2];
- detail::envelope::envelope_box_on_spheroid::apply(box_in, mbrs[0]);
- detail::envelope::envelope_box_on_spheroid::apply(box_out, mbrs[1]);
+ detail::envelope::envelope_box_on_spheroid::apply(box_in, mbrs[0], strategy);
+ detail::envelope::envelope_box_on_spheroid::apply(box_out, mbrs[1], strategy);
// compute the envelope of the two boxes
- detail::envelope::envelope_range_of_boxes::apply(mbrs, box_out);
+ detail::envelope::envelope_range_of_boxes::apply(mbrs, box_out, strategy);
}
};
diff --git a/boost/geometry/algorithms/detail/expand/indexed.hpp b/boost/geometry/algorithms/detail/expand/indexed.hpp
index bdd6eb4506..28cf0e2e4f 100644
--- a/boost/geometry/algorithms/detail/expand/indexed.hpp
+++ b/boost/geometry/algorithms/detail/expand/indexed.hpp
@@ -5,9 +5,10 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2016.
+// Modifications copyright (c) 2015-2016, 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
@@ -49,8 +50,8 @@ template
>
struct indexed_loop
{
- template <typename Box, typename Geometry>
- static inline void apply(Box& box, Geometry const& source)
+ template <typename Box, typename Geometry, typename Strategy>
+ static inline void apply(Box& box, Geometry const& source, Strategy const& strategy)
{
typedef typename strategy::compare::detail::select_strategy
<
@@ -87,7 +88,7 @@ struct indexed_loop
<
StrategyLess, StrategyGreater,
Index, Dimension + 1, DimensionCount
- >::apply(box, source);
+ >::apply(box, source, strategy);
}
};
@@ -103,8 +104,8 @@ struct indexed_loop
Index, DimensionCount, DimensionCount
>
{
- template <typename Box, typename Geometry>
- static inline void apply(Box&, Geometry const&) {}
+ template <typename Box, typename Geometry, typename Strategy>
+ static inline void apply(Box&, Geometry const&, Strategy const&) {}
};
@@ -117,20 +118,22 @@ template
>
struct expand_indexed
{
- template <typename Box, typename Geometry>
- static inline void apply(Box& box, Geometry const& geometry)
+ template <typename Box, typename Geometry, typename Strategy>
+ static inline void apply(Box& box,
+ Geometry const& geometry,
+ Strategy const& strategy)
{
indexed_loop
<
StrategyLess, StrategyGreater,
0, Dimension, DimensionCount
- >::apply(box, geometry);
+ >::apply(box, geometry, strategy);
indexed_loop
<
StrategyLess, StrategyGreater,
1, Dimension, DimensionCount
- >::apply(box, geometry);
+ >::apply(box, geometry, strategy);
}
};
diff --git a/boost/geometry/algorithms/detail/expand/interface.hpp b/boost/geometry/algorithms/detail/expand/interface.hpp
index 140754af4e..5aacd8e72a 100644
--- a/boost/geometry/algorithms/detail/expand/interface.hpp
+++ b/boost/geometry/algorithms/detail/expand/interface.hpp
@@ -5,9 +5,10 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2016.
+// Modifications copyright (c) 2015-2016, 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
@@ -28,10 +29,50 @@
#include <boost/geometry/algorithms/dispatch/expand.hpp>
+#include <boost/geometry/strategies/default_strategy.hpp>
+
+#include <boost/geometry/strategies/envelope.hpp>
+#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
+#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
+#include <boost/geometry/strategies/geographic/envelope_segment.hpp>
namespace boost { namespace geometry
{
+namespace resolve_strategy
+{
+
+template <typename Geometry>
+struct expand
+{
+ template <typename Box, typename Strategy>
+ static inline void apply(Box& box,
+ Geometry const& geometry,
+ Strategy const& strategy)
+ {
+ dispatch::expand<Box, Geometry>::apply(box, geometry, strategy);
+ }
+
+ template <typename Box>
+ static inline void apply(Box& box,
+ Geometry const& geometry,
+ default_strategy)
+ {
+ typedef typename point_type<Geometry>::type point_type;
+ typedef typename coordinate_type<point_type>::type coordinate_type;
+
+ typedef typename strategy::envelope::services::default_strategy
+ <
+ typename cs_tag<point_type>::type,
+ coordinate_type
+ >::type strategy_type;
+
+ dispatch::expand<Box, Geometry>::apply(box, geometry, strategy_type());
+ }
+};
+
+} //namespace resolve_strategy
+
namespace resolve_variant
{
@@ -39,40 +80,48 @@ namespace resolve_variant
template <typename Geometry>
struct expand
{
- template <typename Box>
- static inline void apply(Box& box, Geometry const& geometry)
+ template <typename Box, typename Strategy>
+ static inline void apply(Box& box,
+ Geometry const& geometry,
+ Strategy const& strategy)
{
concepts::check<Box>();
concepts::check<Geometry const>();
concepts::check_concepts_and_equal_dimensions<Box, Geometry const>();
- dispatch::expand<Box, Geometry>::apply(box, geometry);
+ resolve_strategy::expand<Geometry>::apply(box, geometry, strategy);
}
};
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct expand<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
- template <typename Box>
+ template <typename Box, typename Strategy>
struct visitor: boost::static_visitor<void>
{
Box& m_box;
+ Strategy const& m_strategy;
- visitor(Box& box) : m_box(box) {}
+ visitor(Box& box, Strategy const& strategy)
+ : m_box(box)
+ , m_strategy(strategy)
+ {}
template <typename Geometry>
void operator()(Geometry const& geometry) const
{
- return expand<Geometry>::apply(m_box, geometry);
+ return expand<Geometry>::apply(m_box, geometry, m_strategy);
}
};
- template <class Box>
+ template <class Box, typename Strategy>
static inline void
apply(Box& box,
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
+ Strategy const& strategy)
{
- return boost::apply_visitor(visitor<Box>(box), geometry);
+ return boost::apply_visitor(visitor<Box, Strategy>(box, strategy),
+ geometry);
}
};
@@ -106,21 +155,43 @@ inline void expand(Box& box, Geometry const& geometry,
}
***/
+/*!
+\brief Expands (with strategy)
+\ingroup expand
+\tparam Box type of the box
+\tparam Geometry \tparam_geometry
+\tparam Strategy \tparam_strategy{expand}
+\param box box to be expanded using another geometry, mutable
+\param geometry \param_geometry geometry which envelope (bounding box)
+\param strategy \param_strategy{expand}
+will be added to the box
+
+\qbk{distinguish,with strategy}
+\qbk{[include reference/algorithms/expand.qbk]}
+ */
+template <typename Box, typename Geometry, typename Strategy>
+inline void expand(Box& box, Geometry const& geometry, Strategy const& strategy)
+{
+
+ resolve_variant::expand<Geometry>::apply(box, geometry, strategy);
+}
/*!
-\brief Expands a box using the bounding box (envelope) of another geometry (box, point)
+\brief Expands a box using the bounding box (envelope) of another geometry
+(box, point)
\ingroup expand
\tparam Box type of the box
\tparam Geometry \tparam_geometry
\param box box to be expanded using another geometry, mutable
-\param geometry \param_geometry geometry which envelope (bounding box) will be added to the box
+\param geometry \param_geometry geometry which envelope (bounding box) will be
+added to the box
\qbk{[include reference/algorithms/expand.qbk]}
*/
template <typename Box, typename Geometry>
inline void expand(Box& box, Geometry const& geometry)
{
- resolve_variant::expand<Geometry>::apply(box, geometry);
+ resolve_variant::expand<Geometry>::apply(box, geometry, default_strategy());
}
}} // namespace boost::geometry
diff --git a/boost/geometry/algorithms/detail/expand/point.hpp b/boost/geometry/algorithms/detail/expand/point.hpp
index 56b7f1c738..f0cbd1db02 100644
--- a/boost/geometry/algorithms/detail/expand/point.hpp
+++ b/boost/geometry/algorithms/detail/expand/point.hpp
@@ -5,9 +5,10 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2016.
+// Modifications copyright (c) 2015-2016, 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
@@ -59,8 +60,8 @@ template
>
struct point_loop
{
- template <typename Box, typename Point>
- static inline void apply(Box& box, Point const& source)
+ template <typename Box, typename Point, typename Strategy>
+ static inline void apply(Box& box, Point const& source, Strategy const& strategy)
{
typedef typename strategy::compare::detail::select_strategy
<
@@ -95,22 +96,24 @@ struct point_loop
point_loop
<
StrategyLess, StrategyGreater, Dimension + 1, DimensionCount
- >::apply(box, source);
+ >::apply(box, source, strategy);
}
};
template
<
- typename StrategyLess, typename StrategyGreater, std::size_t DimensionCount
+ typename StrategyLess,
+ typename StrategyGreater,
+ std::size_t DimensionCount
>
struct point_loop
<
StrategyLess, StrategyGreater, DimensionCount, DimensionCount
>
{
- template <typename Box, typename Point>
- static inline void apply(Box&, Point const&) {}
+ template <typename Box, typename Point, typename Strategy>
+ static inline void apply(Box&, Point const&, Strategy const&) {}
};
@@ -123,8 +126,10 @@ template
>
struct point_loop_on_spheroid
{
- template <typename Box, typename Point>
- static inline void apply(Box& box, Point const& point)
+ template <typename Box, typename Point, typename Strategy>
+ static inline void apply(Box& box,
+ Point const& point,
+ Strategy const& strategy)
{
typedef typename point_type<Box>::type box_point_type;
typedef typename coordinate_type<Box>::type box_coordinate_type;
@@ -224,7 +229,7 @@ struct point_loop_on_spheroid
point_loop
<
StrategyLess, StrategyGreater, 2, DimensionCount
- >::apply(box, point);
+ >::apply(box, point, strategy);
}
};
diff --git a/boost/geometry/algorithms/detail/expand/segment.hpp b/boost/geometry/algorithms/detail/expand/segment.hpp
index 041c1e175f..0570e944d4 100644
--- a/boost/geometry/algorithms/detail/expand/segment.hpp
+++ b/boost/geometry/algorithms/detail/expand/segment.hpp
@@ -5,9 +5,10 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2016.
+// Modifications copyright (c) 2015-2016, 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
// Distributed under the Boost Software License, Version 1.0.
@@ -39,25 +40,29 @@ namespace boost { namespace geometry
namespace detail { namespace expand
{
-
-struct segment_on_sphere
+struct segment
{
- template <typename Box, typename Segment>
- static inline void apply(Box& box, Segment const& segment)
+ template <typename Box, typename Segment, typename Strategy>
+ static inline void apply(Box& box,
+ Segment const& segment,
+ Strategy const& strategy)
{
Box mbrs[2];
// compute the envelope of the segment
- detail::envelope::envelope_segment_on_sphere
+ typename point_type<Segment>::type p[2];
+ detail::assign_point_from_index<0>(segment, p[0]);
+ detail::assign_point_from_index<1>(segment, p[1]);
+ detail::envelope::envelope_segment
<
dimension<Segment>::value
- >::apply(segment, mbrs[0]);
+ >::apply(p[0], p[1], mbrs[0], strategy);
// normalize the box
- detail::envelope::envelope_box_on_spheroid::apply(box, mbrs[1]);
+ detail::envelope::envelope_box_on_spheroid::apply(box, mbrs[1], strategy);
// compute the envelope of the two boxes
- detail::envelope::envelope_range_of_boxes::apply(mbrs, box);
+ detail::envelope::envelope_range_of_boxes::apply(mbrs, box, strategy);
}
};
@@ -69,7 +74,6 @@ struct segment_on_sphere
namespace dispatch
{
-
template
<
typename Box, typename Segment,
@@ -103,13 +107,27 @@ struct expand
StrategyLess, StrategyGreater,
box_tag, segment_tag,
spherical_equatorial_tag, spherical_equatorial_tag
- > : detail::expand::segment_on_sphere
+ > : detail::expand::segment
{};
+template
+<
+ typename Box, typename Segment,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand
+ <
+ Box, Segment,
+ StrategyLess, StrategyGreater,
+ box_tag, segment_tag,
+ geographic_tag, geographic_tag
+ > : detail::expand::segment
+{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
+
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_SEGMENT_HPP
diff --git a/boost/geometry/algorithms/detail/flattening.hpp b/boost/geometry/algorithms/detail/flattening.hpp
deleted file mode 100644
index 8ed5fd9a89..0000000000
--- a/boost/geometry/algorithms/detail/flattening.hpp
+++ /dev/null
@@ -1,69 +0,0 @@
-// Boost.Geometry
-
-// Copyright (c) 2014 Oracle and/or its affiliates.
-
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
-// 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_FLATTENING_HPP
-#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_FLATTENING_HPP
-
-#include <boost/geometry/core/radius.hpp>
-#include <boost/geometry/core/tag.hpp>
-#include <boost/geometry/core/tags.hpp>
-
-#include <boost/geometry/algorithms/not_implemented.hpp>
-
-namespace boost { namespace geometry
-{
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace detail_dispatch
-{
-
-template <typename ResultType, typename Geometry, typename Tag = typename tag<Geometry>::type>
-struct flattening
- : not_implemented<Tag>
-{};
-
-template <typename ResultType, typename Geometry>
-struct flattening<ResultType, Geometry, srs_sphere_tag>
-{
- static inline ResultType apply(Geometry const& /*geometry*/)
- {
- return ResultType(0);
- }
-};
-
-template <typename ResultType, typename Geometry>
-struct flattening<ResultType, Geometry, srs_spheroid_tag>
-{
- static inline ResultType apply(Geometry const& geometry)
- {
- return ResultType(get_radius<0>(geometry) - get_radius<2>(geometry))
- / ResultType(get_radius<0>(geometry));
- }
-};
-
-} // namespace detail_dispatch
-#endif // DOXYGEN_NO_DISPATCH
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail
-{
-
-template <typename ResultType, typename Geometry>
-ResultType flattening(Geometry const& geometry)
-{
- return detail_dispatch::flattening<ResultType, Geometry>::apply(geometry);
-}
-
-} // namespace detail
-#endif // DOXYGEN_NO_DETAIL
-
-}} // namespace boost::geometry
-
-#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_FLATTENING_HPP
diff --git a/boost/geometry/algorithms/detail/has_self_intersections.hpp b/boost/geometry/algorithms/detail/has_self_intersections.hpp
index 24746ac627..9a388a4d80 100644
--- a/boost/geometry/algorithms/detail/has_self_intersections.hpp
+++ b/boost/geometry/algorithms/detail/has_self_intersections.hpp
@@ -1,6 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017 Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -12,6 +17,8 @@
#include <deque>
#include <boost/range.hpp>
+#include <boost/throw_exception.hpp>
+
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
@@ -59,8 +66,9 @@ namespace detail { namespace overlay
{
-template <typename Geometry, typename RobustPolicy>
+template <typename Geometry, typename Strategy, typename RobustPolicy>
inline bool has_self_intersections(Geometry const& geometry,
+ Strategy const& strategy,
RobustPolicy const& robust_policy,
bool throw_on_self_intersection = true)
{
@@ -73,7 +81,7 @@ inline bool has_self_intersections(Geometry const& geometry,
std::deque<turn_info> turns;
detail::disjoint::disjoint_interrupt_policy policy;
- geometry::self_turns<detail::overlay::assign_null_policy>(geometry, robust_policy, turns, policy);
+ geometry::self_turns<detail::overlay::assign_null_policy>(geometry, strategy, robust_policy, turns, policy);
#ifdef BOOST_GEOMETRY_DEBUG_HAS_SELF_INTERSECTIONS
bool first = true;
@@ -113,7 +121,7 @@ inline bool has_self_intersections(Geometry const& geometry,
#if ! defined(BOOST_GEOMETRY_OVERLAY_NO_THROW)
if (throw_on_self_intersection)
{
- throw overlay_invalid_input_exception();
+ BOOST_THROW_EXCEPTION(overlay_invalid_input_exception());
}
#endif
return true;
@@ -132,11 +140,16 @@ inline bool has_self_intersections(Geometry const& geometry,
typedef typename geometry::rescale_policy_type<point_type>::type
rescale_policy_type;
+ typename strategy::intersection::services::default_strategy
+ <
+ typename cs_tag<Geometry>::type
+ >::type strategy;
+
rescale_policy_type robust_policy
= geometry::get_rescale_policy<rescale_policy_type>(geometry);
- return has_self_intersections(geometry, robust_policy,
- throw_on_self_intersection);
+ return has_self_intersections(geometry, strategy, robust_policy,
+ throw_on_self_intersection);
}
diff --git a/boost/geometry/algorithms/detail/intersection/interface.hpp b/boost/geometry/algorithms/detail/intersection/interface.hpp
index e0955de3d8..0efc9731b5 100644
--- a/boost/geometry/algorithms/detail/intersection/interface.hpp
+++ b/boost/geometry/algorithms/detail/intersection/interface.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2017.
+// Modifications copyright (c) 2014-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -15,12 +15,14 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_INTERFACE_HPP
-// TODO: those headers probably may be removed
-#include <boost/geometry/core/coordinate_dimension.hpp>
-#include <boost/geometry/algorithms/intersects.hpp>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/algorithms/detail/overlay/intersection_insert.hpp>
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
+#include <boost/geometry/strategies/default_strategy.hpp>
+#include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry
@@ -51,10 +53,11 @@ struct intersection
typedef typename boost::range_value<GeometryOut>::type OneOut;
intersection_insert
- <
- Geometry1, Geometry2, OneOut,
- overlay_intersection
- >::apply(geometry1, geometry2, robust_policy, range::back_inserter(geometry_out), strategy);
+ <
+ Geometry1, Geometry2, OneOut,
+ overlay_intersection
+ >::apply(geometry1, geometry2, robust_policy,
+ range::back_inserter(geometry_out), strategy);
return true;
}
@@ -84,11 +87,12 @@ struct intersection
GeometryOut& out,
Strategy const& strategy)
{
- return intersection<
- Geometry2, Geometry1,
- Tag2, Tag1,
- false
- >::apply(g2, g1, robust_policy, out, strategy);
+ return intersection
+ <
+ Geometry2, Geometry1,
+ Tag2, Tag1,
+ false
+ >::apply(g2, g1, robust_policy, out, strategy);
}
};
@@ -96,47 +100,93 @@ struct intersection
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
-
+
+namespace resolve_strategy {
+
+struct intersection
+{
+ template
+ <
+ typename Geometry1,
+ typename Geometry2,
+ typename RobustPolicy,
+ typename GeometryOut,
+ typename Strategy
+ >
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
+ GeometryOut & geometry_out,
+ Strategy const& strategy)
+ {
+ return dispatch::intersection
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, robust_policy, geometry_out,
+ strategy);
+ }
+
+ template
+ <
+ typename Geometry1,
+ typename Geometry2,
+ typename RobustPolicy,
+ typename GeometryOut
+ >
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
+ GeometryOut & geometry_out,
+ default_strategy)
+ {
+ typedef typename strategy::relate::services::default_strategy
+ <
+ Geometry1, Geometry2
+ >::type strategy_type;
+
+ return dispatch::intersection
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, robust_policy, geometry_out,
+ strategy_type());
+ }
+};
+
+} // resolve_strategy
+
+
namespace resolve_variant
{
template <typename Geometry1, typename Geometry2>
struct intersection
{
- template <typename GeometryOut>
- static inline bool
- apply(
- const Geometry1& geometry1,
- const Geometry2& geometry2,
- GeometryOut& geometry_out)
+ template <typename GeometryOut, typename Strategy>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ GeometryOut& geometry_out,
+ Strategy const& strategy)
{
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
typedef typename geometry::rescale_overlay_policy_type
- <
- Geometry1,
- Geometry2
- >::type rescale_policy_type;
+ <
+ Geometry1,
+ Geometry2
+ >::type rescale_policy_type;
rescale_policy_type robust_policy
= geometry::get_rescale_policy<rescale_policy_type>(geometry1,
geometry2);
- typedef intersection_strategies
- <
- typename cs_tag<Geometry1>::type,
- Geometry1,
- Geometry2,
- typename geometry::point_type<Geometry1>::type,
- rescale_policy_type
- > strategy;
-
- return dispatch::intersection
- <
- Geometry1,
- Geometry2
- >::apply(geometry1, geometry2, robust_policy, geometry_out, strategy());
+ return resolve_strategy::intersection::apply(geometry1,
+ geometry2,
+ robust_policy,
+ geometry_out,
+ strategy);
}
};
@@ -144,40 +194,43 @@ struct intersection
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
{
- template <typename GeometryOut>
+ template <typename GeometryOut, typename Strategy>
struct visitor: static_visitor<bool>
{
Geometry2 const& m_geometry2;
GeometryOut& m_geometry_out;
+ Strategy const& m_strategy;
visitor(Geometry2 const& geometry2,
- GeometryOut& geometry_out)
+ GeometryOut& geometry_out,
+ Strategy const& strategy)
: m_geometry2(geometry2)
, m_geometry_out(geometry_out)
+ , m_strategy(strategy)
{}
template <typename Geometry1>
- result_type operator()(Geometry1 const& geometry1) const
+ bool operator()(Geometry1 const& geometry1) const
{
return intersection
- <
- Geometry1,
- Geometry2
- >::template apply
- <
- GeometryOut
- >
- (geometry1, m_geometry2, m_geometry_out);
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, m_geometry2, m_geometry_out, m_strategy);
}
};
- template <typename GeometryOut>
+ template <typename GeometryOut, typename Strategy>
static inline bool
apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
Geometry2 const& geometry2,
- GeometryOut& geometry_out)
+ GeometryOut& geometry_out,
+ Strategy const& strategy)
{
- return boost::apply_visitor(visitor<GeometryOut>(geometry2, geometry_out), geometry1);
+ return boost::apply_visitor(visitor<GeometryOut, Strategy>(geometry2,
+ geometry_out,
+ strategy),
+ geometry1);
}
};
@@ -185,40 +238,43 @@ struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct intersection<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
- template <typename GeometryOut>
+ template <typename GeometryOut, typename Strategy>
struct visitor: static_visitor<bool>
{
Geometry1 const& m_geometry1;
GeometryOut& m_geometry_out;
+ Strategy const& m_strategy;
visitor(Geometry1 const& geometry1,
- GeometryOut& geometry_out)
+ GeometryOut& geometry_out,
+ Strategy const& strategy)
: m_geometry1(geometry1)
, m_geometry_out(geometry_out)
+ , m_strategy(strategy)
{}
template <typename Geometry2>
- result_type operator()(Geometry2 const& geometry2) const
+ bool operator()(Geometry2 const& geometry2) const
{
return intersection
- <
- Geometry1,
- Geometry2
- >::template apply
- <
- GeometryOut
- >
- (m_geometry1, geometry2, m_geometry_out);
+ <
+ Geometry1,
+ Geometry2
+ >::apply(m_geometry1, geometry2, m_geometry_out, m_strategy);
}
};
- template <typename GeometryOut>
+ template <typename GeometryOut, typename Strategy>
static inline bool
apply(Geometry1 const& geometry1,
- const variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry2,
- GeometryOut& geometry_out)
+ variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
+ GeometryOut& geometry_out,
+ Strategy const& strategy)
{
- return boost::apply_visitor(visitor<GeometryOut>(geometry1, geometry_out), geometry2);
+ return boost::apply_visitor(visitor<GeometryOut, Strategy>(geometry1,
+ geometry_out,
+ strategy),
+ geometry2);
}
};
@@ -226,38 +282,39 @@ struct intersection<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
template <BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2)>
struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
{
- template <typename GeometryOut>
+ template <typename GeometryOut, typename Strategy>
struct visitor: static_visitor<bool>
{
GeometryOut& m_geometry_out;
+ Strategy const& m_strategy;
- visitor(GeometryOut& geometry_out)
+ visitor(GeometryOut& geometry_out, Strategy const& strategy)
: m_geometry_out(geometry_out)
+ , m_strategy(strategy)
{}
template <typename Geometry1, typename Geometry2>
- result_type operator()(Geometry1 const& geometry1,
- Geometry2 const& geometry2) const
+ bool operator()(Geometry1 const& geometry1,
+ Geometry2 const& geometry2) const
{
return intersection
- <
- Geometry1,
- Geometry2
- >::template apply
- <
- GeometryOut
- >
- (geometry1, geometry2, m_geometry_out);
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, m_geometry_out, m_strategy);
}
};
- template <typename GeometryOut>
+ template <typename GeometryOut, typename Strategy>
static inline bool
- apply(const variant<BOOST_VARIANT_ENUM_PARAMS(T1)>& geometry1,
- const variant<BOOST_VARIANT_ENUM_PARAMS(T2)>& geometry2,
- GeometryOut& geometry_out)
+ apply(variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
+ variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
+ GeometryOut& geometry_out,
+ Strategy const& strategy)
{
- return boost::apply_visitor(visitor<GeometryOut>(geometry_out), geometry1, geometry2);
+ return boost::apply_visitor(visitor<GeometryOut, Strategy>(geometry_out,
+ strategy),
+ geometry1, geometry2);
}
};
@@ -272,32 +329,66 @@ struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIAN
\tparam Geometry2 \tparam_geometry
\tparam GeometryOut Collection of geometries (e.g. std::vector, std::deque, boost::geometry::multi*) of which
the value_type fulfills a \p_l_or_c concept, or it is the output geometry (e.g. for a box)
+\tparam Strategy \tparam_strategy{Intersection}
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\param geometry_out The output geometry, either a multi_point, multi_polygon,
multi_linestring, or a box (for intersection of two boxes)
+\param strategy \param_strategy{intersection}
+\qbk{distinguish,with strategy}
\qbk{[include reference/algorithms/intersection.qbk]}
*/
template
<
typename Geometry1,
typename Geometry2,
- typename GeometryOut
+ typename GeometryOut,
+ typename Strategy
>
inline bool intersection(Geometry1 const& geometry1,
- Geometry2 const& geometry2,
- GeometryOut& geometry_out)
+ Geometry2 const& geometry2,
+ GeometryOut& geometry_out,
+ Strategy const& strategy)
{
return resolve_variant::intersection
<
- Geometry1,
- Geometry2
- >::template apply
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, geometry_out, strategy);
+}
+
+
+/*!
+\brief \brief_calc2{intersection}
+\ingroup intersection
+\details \details_calc2{intersection, spatial set theoretic intersection}.
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam GeometryOut Collection of geometries (e.g. std::vector, std::deque, boost::geometry::multi*) of which
+ the value_type fulfills a \p_l_or_c concept, or it is the output geometry (e.g. for a box)
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param geometry_out The output geometry, either a multi_point, multi_polygon,
+ multi_linestring, or a box (for intersection of two boxes)
+
+\qbk{[include reference/algorithms/intersection.qbk]}
+*/
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename GeometryOut
+>
+inline bool intersection(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ GeometryOut& geometry_out)
+{
+ return resolve_variant::intersection
<
- GeometryOut
- >
- (geometry1, geometry2, geometry_out);
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, geometry_out, default_strategy());
}
diff --git a/boost/geometry/algorithms/detail/is_simple/always_simple.hpp b/boost/geometry/algorithms/detail/is_simple/always_simple.hpp
index 91e2ef76bd..5cec5e1924 100644
--- a/boost/geometry/algorithms/detail/is_simple/always_simple.hpp
+++ b/boost/geometry/algorithms/detail/is_simple/always_simple.hpp
@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2017, 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
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -27,7 +28,8 @@ namespace detail { namespace is_simple
template <typename Geometry>
struct always_simple
{
- static inline bool apply(Geometry const&)
+ template <typename Strategy>
+ static inline bool apply(Geometry const&, Strategy const&)
{
return true;
}
diff --git a/boost/geometry/algorithms/detail/is_simple/areal.hpp b/boost/geometry/algorithms/detail/is_simple/areal.hpp
index a2322e4831..d4d6db9bce 100644
--- a/boost/geometry/algorithms/detail/is_simple/areal.hpp
+++ b/boost/geometry/algorithms/detail/is_simple/areal.hpp
@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014-2015, Oracle and/or its affiliates.
+// Copyright (c) 2014-2017, 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
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -37,6 +38,12 @@ namespace detail { namespace is_simple
template <typename Ring>
struct is_simple_ring
{
+ template <typename Strategy>
+ static inline bool apply(Ring const& ring, Strategy const&)
+ {
+ return apply(ring);
+ }
+
static inline bool apply(Ring const& ring)
{
simplicity_failure_policy policy;
@@ -69,6 +76,12 @@ private:
}
public:
+ template <typename Strategy>
+ static inline bool apply(Polygon const& polygon, Strategy const&)
+ {
+ return apply(polygon);
+ }
+
static inline bool apply(Polygon const& polygon)
{
return
@@ -119,7 +132,8 @@ struct is_simple<Polygon, polygon_tag>
template <typename MultiPolygon>
struct is_simple<MultiPolygon, multi_polygon_tag>
{
- static inline bool apply(MultiPolygon const& multipolygon)
+ template <typename Strategy>
+ static inline bool apply(MultiPolygon const& multipolygon, Strategy const&)
{
return
detail::check_iterator_range
diff --git a/boost/geometry/algorithms/detail/is_simple/interface.hpp b/boost/geometry/algorithms/detail/is_simple/interface.hpp
index 6d425232b0..af0127dc75 100644
--- a/boost/geometry/algorithms/detail/is_simple/interface.hpp
+++ b/boost/geometry/algorithms/detail/is_simple/interface.hpp
@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2017, 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
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -17,46 +18,106 @@
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/algorithms/dispatch/is_simple.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/strategies/default_strategy.hpp>
+#include <boost/geometry/strategies/intersection.hpp>
namespace boost { namespace geometry
{
+namespace resolve_strategy
+{
+
+struct is_simple
+{
+ template <typename Geometry, typename Strategy>
+ static inline bool apply(Geometry const& geometry,
+ Strategy const& strategy)
+ {
+ return dispatch::is_simple<Geometry>::apply(geometry, strategy);
+ }
+
+ template <typename Geometry>
+ static inline bool apply(Geometry const& geometry,
+ default_strategy)
+ {
+ // NOTE: Currently the strategy is only used for Linear geometries
+ typedef typename strategy::intersection::services::default_strategy
+ <
+ typename cs_tag<Geometry>::type
+ >::type strategy_type;
+
+ return dispatch::is_simple<Geometry>::apply(geometry, strategy_type());
+ }
+};
-namespace resolve_variant {
+} // namespace resolve_strategy
+
+namespace resolve_variant
+{
template <typename Geometry>
struct is_simple
{
- static inline bool apply(Geometry const& geometry)
+ template <typename Strategy>
+ static inline bool apply(Geometry const& geometry, Strategy const& strategy)
{
concepts::check<Geometry const>();
- return dispatch::is_simple<Geometry>::apply(geometry);
+
+ return resolve_strategy::is_simple::apply(geometry, strategy);
}
};
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct is_simple<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
+ template <typename Strategy>
struct visitor : boost::static_visitor<bool>
{
+ Strategy const& m_strategy;
+
+ visitor(Strategy const& strategy)
+ : m_strategy(strategy)
+ {}
+
template <typename Geometry>
bool operator()(Geometry const& geometry) const
{
- return is_simple<Geometry>::apply(geometry);
+ return is_simple<Geometry>::apply(geometry, m_strategy);
}
};
+ template <typename Strategy>
static inline bool
- apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
+ Strategy const& strategy)
{
- return boost::apply_visitor(visitor(), geometry);
+ return boost::apply_visitor(visitor<Strategy>(strategy), geometry);
}
};
} // namespace resolve_variant
+/*!
+\brief \brief_check{is simple}
+\ingroup is_simple
+\tparam Geometry \tparam_geometry
+\tparam Strategy \tparam_strategy{Is_simple}
+\param geometry \param_geometry
+\param strategy \param_strategy{is_simple}
+\return \return_check{is simple}
+
+\qbk{distinguish,with strategy}
+\qbk{[include reference/algorithms/is_simple.qbk]}
+*/
+template <typename Geometry, typename Strategy>
+inline bool is_simple(Geometry const& geometry, Strategy const& strategy)
+{
+ return resolve_variant::is_simple<Geometry>::apply(geometry, strategy);
+}
+
/*!
\brief \brief_check{is simple}
@@ -70,7 +131,7 @@ struct is_simple<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
template <typename Geometry>
inline bool is_simple(Geometry const& geometry)
{
- return resolve_variant::is_simple<Geometry>::apply(geometry);
+ return resolve_variant::is_simple<Geometry>::apply(geometry, default_strategy());
}
diff --git a/boost/geometry/algorithms/detail/is_simple/linear.hpp b/boost/geometry/algorithms/detail/is_simple/linear.hpp
index 16d7b3a803..52b9d9d1c8 100644
--- a/boost/geometry/algorithms/detail/is_simple/linear.hpp
+++ b/boost/geometry/algorithms/detail/is_simple/linear.hpp
@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014-2015, Oracle and/or its affiliates.
+// Copyright (c) 2014-2017, 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
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -48,6 +49,8 @@
#include <boost/geometry/algorithms/dispatch/is_simple.hpp>
+#include <boost/geometry/strategies/intersection.hpp>
+
namespace boost { namespace geometry
{
@@ -186,8 +189,8 @@ private:
};
-template <typename Linear>
-inline bool has_self_intersections(Linear const& linear)
+template <typename Linear, typename Strategy>
+inline bool has_self_intersections(Linear const& linear, Strategy const& strategy)
{
typedef typename point_type<Linear>::type point_type;
@@ -218,6 +221,7 @@ inline bool has_self_intersections(Linear const& linear)
<
turn_policy
>::apply(linear,
+ strategy,
detail::no_rescale_policy(),
turns,
interrupt_policy);
@@ -243,8 +247,19 @@ struct is_simple_linestring
&& ! detail::is_valid::has_spikes
<
Linestring, closed
- >::apply(linestring, policy)
- && ! (CheckSelfIntersections && has_self_intersections(linestring));
+ >::apply(linestring, policy);
+ }
+};
+
+template <typename Linestring>
+struct is_simple_linestring<Linestring, true>
+{
+ template <typename Strategy>
+ static inline bool apply(Linestring const& linestring,
+ Strategy const& strategy)
+ {
+ return is_simple_linestring<Linestring, false>::apply(linestring)
+ && ! has_self_intersections(linestring, strategy);
}
};
@@ -252,7 +267,9 @@ struct is_simple_linestring
template <typename MultiLinestring>
struct is_simple_multilinestring
{
- static inline bool apply(MultiLinestring const& multilinestring)
+ template <typename Strategy>
+ static inline bool apply(MultiLinestring const& multilinestring,
+ Strategy const& strategy)
{
// check each of the linestrings for simplicity
// but do not compute self-intersections yet; these will be
@@ -272,7 +289,7 @@ struct is_simple_multilinestring
return false;
}
- return ! has_self_intersections(multilinestring);
+ return ! has_self_intersections(multilinestring, strategy);
}
};
diff --git a/boost/geometry/algorithms/detail/is_simple/multipoint.hpp b/boost/geometry/algorithms/detail/is_simple/multipoint.hpp
index f9f43d1cdb..61f0bc9130 100644
--- a/boost/geometry/algorithms/detail/is_simple/multipoint.hpp
+++ b/boost/geometry/algorithms/detail/is_simple/multipoint.hpp
@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014-2015, Oracle and/or its affiliates.
+// Copyright (c) 2014-2017, 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
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -38,7 +39,8 @@ namespace detail { namespace is_simple
template <typename MultiPoint>
struct is_simple_multipoint
{
- static inline bool apply(MultiPoint const& multipoint)
+ template <typename Strategy>
+ static inline bool apply(MultiPoint const& multipoint, Strategy const&)
{
if (boost::empty(multipoint))
{
diff --git a/boost/geometry/algorithms/detail/is_valid/box.hpp b/boost/geometry/algorithms/detail/is_valid/box.hpp
index 863ce625fe..69a4d4e78e 100644
--- a/boost/geometry/algorithms/detail/is_valid/box.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/box.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014-2015, Oracle and/or its affiliates.
+// Copyright (c) 2014-2017, 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
@@ -71,8 +71,8 @@ struct has_valid_corners<Box, 0>
template <typename Box>
struct is_valid_box
{
- template <typename VisitPolicy>
- static inline bool apply(Box const& box, VisitPolicy& visitor)
+ template <typename VisitPolicy, typename Strategy>
+ static inline bool apply(Box const& box, VisitPolicy& visitor, Strategy const&)
{
return
! has_invalid_coordinate<Box>::apply(box, visitor)
diff --git a/boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp b/boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp
index 0a81213743..b91dc6a697 100644
--- a/boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp
@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014-2015, Oracle and/or its affiliates.
+// Copyright (c) 2014-2017, 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
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -69,10 +70,11 @@ public:
> turn_type;
// returns true if all turns are valid
- template <typename Turns, typename VisitPolicy>
+ template <typename Turns, typename VisitPolicy, typename Strategy>
static inline bool apply(Geometry const& geometry,
Turns& turns,
- VisitPolicy& visitor)
+ VisitPolicy& visitor,
+ Strategy const& strategy)
{
boost::ignore_unused(visitor);
@@ -85,6 +87,7 @@ public:
> interrupt_policy;
geometry::self_turns<turn_policy>(geometry,
+ strategy,
robust_policy,
turns,
interrupt_policy);
@@ -101,11 +104,11 @@ public:
}
// returns true if all turns are valid
- template <typename VisitPolicy>
- static inline bool apply(Geometry const& geometry, VisitPolicy& visitor)
+ template <typename VisitPolicy, typename Strategy>
+ static inline bool apply(Geometry const& geometry, VisitPolicy& visitor, Strategy const& strategy)
{
std::vector<turn_type> turns;
- return apply(geometry, turns, visitor);
+ return apply(geometry, turns, visitor, strategy);
}
};
diff --git a/boost/geometry/algorithms/detail/is_valid/interface.hpp b/boost/geometry/algorithms/detail/is_valid/interface.hpp
index 5a04a92824..ee013377c4 100644
--- a/boost/geometry/algorithms/detail/is_valid/interface.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/interface.hpp
@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014-2015, Oracle and/or its affiliates.
+// Copyright (c) 2014-2017, 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
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -23,48 +24,88 @@
#include <boost/geometry/policies/is_valid/default_policy.hpp>
#include <boost/geometry/policies/is_valid/failing_reason_policy.hpp>
#include <boost/geometry/policies/is_valid/failure_type_policy.hpp>
+#include <boost/geometry/strategies/default_strategy.hpp>
+#include <boost/geometry/strategies/intersection.hpp>
namespace boost { namespace geometry
{
+
+namespace resolve_strategy
+{
+
+struct is_valid
+{
+ template <typename Geometry, typename VisitPolicy, typename Strategy>
+ static inline bool apply(Geometry const& geometry,
+ VisitPolicy& visitor,
+ Strategy const& strategy)
+ {
+ return dispatch::is_valid<Geometry>::apply(geometry, visitor, strategy);
+ }
+
+ template <typename Geometry, typename VisitPolicy>
+ static inline bool apply(Geometry const& geometry,
+ VisitPolicy& visitor,
+ default_strategy)
+ {
+ // NOTE: Currently the strategy is only used for Areal geometries
+ typedef typename strategy::intersection::services::default_strategy
+ <
+ typename cs_tag<Geometry>::type
+ >::type strategy_type;
+
+ return dispatch::is_valid<Geometry>::apply(geometry, visitor, strategy_type());
+ }
+};
+} // namespace resolve_strategy
-namespace resolve_variant {
+namespace resolve_variant
+{
template <typename Geometry>
struct is_valid
{
- template <typename VisitPolicy>
- static inline bool apply(Geometry const& geometry, VisitPolicy& visitor)
+ template <typename VisitPolicy, typename Strategy>
+ static inline bool apply(Geometry const& geometry,
+ VisitPolicy& visitor,
+ Strategy const& strategy)
{
concepts::check<Geometry const>();
- return dispatch::is_valid<Geometry>::apply(geometry, visitor);
+
+ return resolve_strategy::is_valid::apply(geometry, visitor, strategy);
}
};
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct is_valid<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
- template <typename VisitPolicy>
+ template <typename VisitPolicy, typename Strategy>
struct visitor : boost::static_visitor<bool>
{
- visitor(VisitPolicy& policy) : m_policy(policy) {}
+ visitor(VisitPolicy& policy, Strategy const& strategy)
+ : m_policy(policy)
+ , m_strategy(strategy)
+ {}
template <typename Geometry>
bool operator()(Geometry const& geometry) const
{
- return is_valid<Geometry>::apply(geometry, m_policy);
+ return is_valid<Geometry>::apply(geometry, m_policy, m_strategy);
}
VisitPolicy& m_policy;
+ Strategy const& m_strategy;
};
- template <typename VisitPolicy>
+ template <typename VisitPolicy, typename Strategy>
static inline bool
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
- VisitPolicy& policy_visitor)
+ VisitPolicy& policy_visitor,
+ Strategy const& strategy)
{
- return boost::apply_visitor(visitor<VisitPolicy>(policy_visitor),
+ return boost::apply_visitor(visitor<VisitPolicy, Strategy>(policy_visitor, strategy),
geometry);
}
};
@@ -73,10 +114,12 @@ struct is_valid<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
// Undocumented for now
-template <typename Geometry, typename VisitPolicy>
-inline bool is_valid(Geometry const& geometry, VisitPolicy& visitor)
+template <typename Geometry, typename VisitPolicy, typename Strategy>
+inline bool is_valid(Geometry const& geometry,
+ VisitPolicy& visitor,
+ Strategy const& strategy)
{
- return resolve_variant::is_valid<Geometry>::apply(geometry, visitor);
+ return resolve_variant::is_valid<Geometry>::apply(geometry, visitor, strategy);
}
@@ -84,6 +127,29 @@ inline bool is_valid(Geometry const& geometry, VisitPolicy& visitor)
\brief \brief_check{is valid (in the OGC sense)}
\ingroup is_valid
\tparam Geometry \tparam_geometry
+\tparam Strategy \tparam_strategy{Is_valid}
+\param geometry \param_geometry
+\param strategy \param_strategy{is_valid}
+\return \return_check{is valid (in the OGC sense);
+furthermore, the following geometries are considered valid:
+multi-geometries with no elements,
+linear geometries containing spikes,
+areal geometries with duplicate (consecutive) points}
+
+\qbk{distinguish,with strategy}
+\qbk{[include reference/algorithms/is_valid.qbk]}
+*/
+template <typename Geometry, typename Strategy>
+inline bool is_valid(Geometry const& geometry, Strategy const& strategy)
+{
+ is_valid_default_policy<> visitor;
+ return resolve_variant::is_valid<Geometry>::apply(geometry, visitor, strategy);
+}
+
+/*!
+\brief \brief_check{is valid (in the OGC sense)}
+\ingroup is_valid
+\tparam Geometry \tparam_geometry
\param geometry \param_geometry
\return \return_check{is valid (in the OGC sense);
furthermore, the following geometries are considered valid:
@@ -96,8 +162,7 @@ inline bool is_valid(Geometry const& geometry, VisitPolicy& visitor)
template <typename Geometry>
inline bool is_valid(Geometry const& geometry)
{
- is_valid_default_policy<> policy_visitor;
- return geometry::is_valid(geometry, policy_visitor);
+ return is_valid(geometry, default_strategy());
}
@@ -105,6 +170,33 @@ inline bool is_valid(Geometry const& geometry)
\brief \brief_check{is valid (in the OGC sense)}
\ingroup is_valid
\tparam Geometry \tparam_geometry
+\tparam Strategy \tparam_strategy{Is_valid}
+\param geometry \param_geometry
+\param failure An enumeration value indicating that the geometry is
+ valid or not, and if not valid indicating the reason why
+\param strategy \param_strategy{is_valid}
+\return \return_check{is valid (in the OGC sense);
+ furthermore, the following geometries are considered valid:
+ multi-geometries with no elements,
+ linear geometries containing spikes,
+ areal geometries with duplicate (consecutive) points}
+
+\qbk{distinguish,with failure value and strategy}
+\qbk{[include reference/algorithms/is_valid_with_failure.qbk]}
+*/
+template <typename Geometry, typename Strategy>
+inline bool is_valid(Geometry const& geometry, validity_failure_type& failure, Strategy const& strategy)
+{
+ failure_type_policy<> visitor;
+ bool result = resolve_variant::is_valid<Geometry>::apply(geometry, visitor, strategy);
+ failure = visitor.failure();
+ return result;
+}
+
+/*!
+\brief \brief_check{is valid (in the OGC sense)}
+\ingroup is_valid
+\tparam Geometry \tparam_geometry
\param geometry \param_geometry
\param failure An enumeration value indicating that the geometry is
valid or not, and if not valid indicating the reason why
@@ -120,10 +212,7 @@ inline bool is_valid(Geometry const& geometry)
template <typename Geometry>
inline bool is_valid(Geometry const& geometry, validity_failure_type& failure)
{
- failure_type_policy<> policy_visitor;
- bool result = geometry::is_valid(geometry, policy_visitor);
- failure = policy_visitor.failure();
- return result;
+ return is_valid(geometry, failure, default_strategy());
}
@@ -131,28 +220,52 @@ inline bool is_valid(Geometry const& geometry, validity_failure_type& failure)
\brief \brief_check{is valid (in the OGC sense)}
\ingroup is_valid
\tparam Geometry \tparam_geometry
+\tparam Strategy \tparam_strategy{Is_valid}
\param geometry \param_geometry
\param message A string containing a message stating if the geometry
is valid or not, and if not valid a reason why
+\param strategy \param_strategy{is_valid}
\return \return_check{is valid (in the OGC sense);
furthermore, the following geometries are considered valid:
multi-geometries with no elements,
linear geometries containing spikes,
areal geometries with duplicate (consecutive) points}
-\qbk{distinguish,with message}
+\qbk{distinguish,with message and strategy}
\qbk{[include reference/algorithms/is_valid_with_message.qbk]}
*/
-template <typename Geometry>
-inline bool is_valid(Geometry const& geometry, std::string& message)
+template <typename Geometry, typename Strategy>
+inline bool is_valid(Geometry const& geometry, std::string& message, Strategy const& strategy)
{
std::ostringstream stream;
- failing_reason_policy<> policy_visitor(stream);
- bool result = geometry::is_valid(geometry, policy_visitor);
+ failing_reason_policy<> visitor(stream);
+ bool result = resolve_variant::is_valid<Geometry>::apply(geometry, visitor, strategy);
message = stream.str();
return result;
}
+/*!
+\brief \brief_check{is valid (in the OGC sense)}
+\ingroup is_valid
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry
+\param message A string containing a message stating if the geometry
+ is valid or not, and if not valid a reason why
+\return \return_check{is valid (in the OGC sense);
+ furthermore, the following geometries are considered valid:
+ multi-geometries with no elements,
+ linear geometries containing spikes,
+ areal geometries with duplicate (consecutive) points}
+
+\qbk{distinguish,with message}
+\qbk{[include reference/algorithms/is_valid_with_message.qbk]}
+*/
+template <typename Geometry>
+inline bool is_valid(Geometry const& geometry, std::string& message)
+{
+ return is_valid(geometry, message, default_strategy());
+}
+
}} // namespace boost::geometry
diff --git a/boost/geometry/algorithms/detail/is_valid/linear.hpp b/boost/geometry/algorithms/detail/is_valid/linear.hpp
index a49e077237..6bc6b86cf8 100644
--- a/boost/geometry/algorithms/detail/is_valid/linear.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/linear.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014-2015, Oracle and/or its affiliates.
+// Copyright (c) 2014-2017, 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
@@ -77,6 +77,14 @@ struct is_valid_linestring
}
return ! has_spikes<Linestring, closed>::apply(linestring, visitor);
}
+
+ template <typename VisitPolicy, typename Strategy>
+ static inline bool apply(Linestring const& linestring,
+ VisitPolicy& visitor,
+ Strategy const&)
+ {
+ return apply(linestring, visitor);
+ }
};
@@ -142,9 +150,10 @@ private:
};
public:
- template <typename VisitPolicy>
+ template <typename VisitPolicy, typename Strategy>
static inline bool apply(MultiLinestring const& multilinestring,
- VisitPolicy& visitor)
+ VisitPolicy& visitor,
+ Strategy const&)
{
if (BOOST_GEOMETRY_CONDITION(
AllowEmptyMultiGeometries && boost::empty(multilinestring)))
diff --git a/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp b/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp
index 0025445c2c..84dacc57f1 100644
--- a/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014-2015, Oracle and/or its affiliates.
+// Copyright (c) 2014-2017, 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
@@ -43,6 +43,8 @@
#include <boost/geometry/algorithms/dispatch/is_valid.hpp>
+#include <boost/geometry/strategies/intersection.hpp>
+
namespace boost { namespace geometry
{
@@ -109,10 +111,10 @@ private:
geometry::partition
<
- geometry::model::box<typename point_type<MultiPolygon>::type>,
- typename base::expand_box,
- typename base::overlaps_box
- >::apply(polygon_iterators, item_visitor);
+ geometry::model::box<typename point_type<MultiPolygon>::type>
+ >::apply(polygon_iterators, item_visitor,
+ typename base::expand_box(),
+ typename base::overlaps_box());
if (item_visitor.items_overlap)
{
@@ -235,23 +237,28 @@ private:
}
- template <typename VisitPolicy>
+ template <typename VisitPolicy, typename Strategy>
struct per_polygon
{
- per_polygon(VisitPolicy& policy) : m_policy(policy) {}
+ per_polygon(VisitPolicy& policy, Strategy const& strategy)
+ : m_policy(policy)
+ , m_strategy(strategy)
+ {}
template <typename Polygon>
inline bool apply(Polygon const& polygon) const
{
- return base::apply(polygon, m_policy);
+ return base::apply(polygon, m_policy, m_strategy);
}
VisitPolicy& m_policy;
+ Strategy const& m_strategy;
};
public:
- template <typename VisitPolicy>
+ template <typename VisitPolicy, typename Strategy>
static inline bool apply(MultiPolygon const& multipolygon,
- VisitPolicy& visitor)
+ VisitPolicy& visitor,
+ Strategy const& strategy)
{
typedef debug_validity_phase<MultiPolygon> debug_phase;
@@ -266,11 +273,11 @@ public:
if (! detail::check_iterator_range
<
- per_polygon<VisitPolicy>,
+ per_polygon<VisitPolicy, Strategy>,
false // do not check for empty multipolygon (done above)
>::apply(boost::begin(multipolygon),
boost::end(multipolygon),
- per_polygon<VisitPolicy>(visitor)))
+ per_polygon<VisitPolicy, Strategy>(visitor, strategy)))
{
return false;
}
@@ -283,7 +290,7 @@ public:
std::deque<typename has_valid_turns::turn_type> turns;
bool has_invalid_turns =
- ! has_valid_turns::apply(multipolygon, turns, visitor);
+ ! has_valid_turns::apply(multipolygon, turns, visitor, strategy);
debug_print_turns(turns.begin(), turns.end());
if (has_invalid_turns)
diff --git a/boost/geometry/algorithms/detail/is_valid/pointlike.hpp b/boost/geometry/algorithms/detail/is_valid/pointlike.hpp
index 51035f7a73..f77f7a35eb 100644
--- a/boost/geometry/algorithms/detail/is_valid/pointlike.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/pointlike.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014-2015, Oracle and/or its affiliates.
+// Copyright (c) 2014-2017, 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
@@ -36,8 +36,8 @@ namespace dispatch
template <typename Point>
struct is_valid<Point, point_tag>
{
- template <typename VisitPolicy>
- static inline bool apply(Point const& point, VisitPolicy& visitor)
+ template <typename VisitPolicy, typename Strategy>
+ static inline bool apply(Point const& point, VisitPolicy& visitor, Strategy const&)
{
boost::ignore_unused(visitor);
return ! detail::is_valid::has_invalid_coordinate
@@ -56,9 +56,10 @@ struct is_valid<Point, point_tag>
template <typename MultiPoint, bool AllowEmptyMultiGeometries>
struct is_valid<MultiPoint, multi_point_tag, AllowEmptyMultiGeometries>
{
- template <typename VisitPolicy>
+ template <typename VisitPolicy, typename Strategy>
static inline bool apply(MultiPoint const& multipoint,
- VisitPolicy& visitor)
+ VisitPolicy& visitor,
+ Strategy const&)
{
boost::ignore_unused(multipoint, visitor);
diff --git a/boost/geometry/algorithms/detail/is_valid/polygon.hpp b/boost/geometry/algorithms/detail/is_valid/polygon.hpp
index bbe8e8fc39..f7e22fb8d2 100644
--- a/boost/geometry/algorithms/detail/is_valid/polygon.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/polygon.hpp
@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014-2015, Oracle and/or its affiliates.
+// Copyright (c) 2014-2017, 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
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -74,10 +75,13 @@ class is_valid_polygon
protected:
typedef debug_validity_phase<Polygon> debug_phase;
- template <typename VisitPolicy>
+ template <typename VisitPolicy, typename Strategy>
struct per_ring
{
- per_ring(VisitPolicy& policy) : m_policy(policy) {}
+ per_ring(VisitPolicy& policy, Strategy const& strategy)
+ : m_policy(policy)
+ , m_strategy(strategy)
+ {}
template <typename Ring>
inline bool apply(Ring const& ring) const
@@ -85,30 +89,34 @@ protected:
return detail::is_valid::is_valid_ring
<
Ring, false, true
- >::apply(ring, m_policy);
+ >::apply(ring, m_policy, m_strategy);
}
VisitPolicy& m_policy;
+ Strategy const& m_strategy;
};
- template <typename InteriorRings, typename VisitPolicy>
+ template <typename InteriorRings, typename VisitPolicy, typename Strategy>
static bool has_valid_interior_rings(InteriorRings const& interior_rings,
- VisitPolicy& visitor)
+ VisitPolicy& visitor,
+ Strategy const& strategy)
{
return
detail::check_iterator_range
<
- per_ring<VisitPolicy>,
+ per_ring<VisitPolicy, Strategy>,
true // allow for empty interior ring range
>::apply(boost::begin(interior_rings),
boost::end(interior_rings),
- per_ring<VisitPolicy>(visitor));
+ per_ring<VisitPolicy, Strategy>(visitor, strategy));
}
struct has_valid_rings
{
- template <typename VisitPolicy>
- static inline bool apply(Polygon const& polygon, VisitPolicy& visitor)
+ template <typename VisitPolicy, typename Strategy>
+ static inline bool apply(Polygon const& polygon,
+ VisitPolicy& visitor,
+ Strategy const& strategy)
{
typedef typename ring_type<Polygon>::type ring_type;
@@ -119,7 +127,7 @@ protected:
<
ring_type,
false // do not check self intersections
- >::apply(exterior_ring(polygon), visitor))
+ >::apply(exterior_ring(polygon), visitor, strategy))
{
return false;
}
@@ -128,7 +136,8 @@ protected:
debug_phase::apply(2);
return has_valid_interior_rings(geometry::interior_rings(polygon),
- visitor);
+ visitor,
+ strategy);
}
};
@@ -246,10 +255,8 @@ protected:
geometry::partition
<
- geometry::model::box<typename point_type<Polygon>::type>,
- expand_box,
- overlaps_box
- >::apply(ring_iterators, item_visitor);
+ geometry::model::box<typename point_type<Polygon>::type>
+ >::apply(ring_iterators, item_visitor, expand_box(), overlaps_box());
if (item_visitor.items_overlap)
{
@@ -346,10 +353,12 @@ protected:
};
public:
- template <typename VisitPolicy>
- static inline bool apply(Polygon const& polygon, VisitPolicy& visitor)
+ template <typename VisitPolicy, typename Strategy>
+ static inline bool apply(Polygon const& polygon,
+ VisitPolicy& visitor,
+ Strategy const& strategy)
{
- if (! has_valid_rings::apply(polygon, visitor))
+ if (! has_valid_rings::apply(polygon, visitor, strategy))
{
return false;
}
@@ -366,7 +375,7 @@ public:
std::deque<typename has_valid_turns::turn_type> turns;
bool has_invalid_turns
- = ! has_valid_turns::apply(polygon, turns, visitor);
+ = ! has_valid_turns::apply(polygon, turns, visitor, strategy);
debug_print_turns(turns.begin(), turns.end());
if (has_invalid_turns)
diff --git a/boost/geometry/algorithms/detail/is_valid/ring.hpp b/boost/geometry/algorithms/detail/is_valid/ring.hpp
index 925c03a472..9ab68fdc48 100644
--- a/boost/geometry/algorithms/detail/is_valid/ring.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/ring.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014-2015, Oracle and/or its affiliates.
+// Copyright (c) 2014-2017, 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
@@ -101,26 +101,21 @@ struct ring_area_predicate<ResultType, true>
template <typename Ring, bool IsInteriorRing>
struct is_properly_oriented
{
- typedef typename point_type<Ring>::type point_type;
-
- typedef typename strategy::area::services::default_strategy
- <
- typename cs_tag<point_type>::type,
- point_type
- >::type strategy_type;
+ template <typename VisitPolicy, typename Strategy>
+ static inline bool apply(Ring const& ring, VisitPolicy& visitor,
+ Strategy const& strategy)
+ {
+ boost::ignore_unused(visitor);
- typedef detail::area::ring_area
- <
- order_as_direction<geometry::point_order<Ring>::value>::value,
- geometry::closure<Ring>::value
- > ring_area_type;
+ typedef typename point_type<Ring>::type point_type;
- typedef typename default_area_result<Ring>::type area_result_type;
+ typedef detail::area::ring_area
+ <
+ order_as_direction<geometry::point_order<Ring>::value>::value,
+ geometry::closure<Ring>::value
+ > ring_area_type;
- template <typename VisitPolicy>
- static inline bool apply(Ring const& ring, VisitPolicy& visitor)
- {
- boost::ignore_unused(visitor);
+ typedef typename default_area_result<Ring>::type area_result_type;
typename ring_area_predicate
<
@@ -128,8 +123,11 @@ struct is_properly_oriented
>::type predicate;
// Check area
- area_result_type const zero = area_result_type();
- if (predicate(ring_area_type::apply(ring, strategy_type()), zero))
+ area_result_type const zero = 0;
+ area_result_type const area
+ = ring_area_type::apply(ring,
+ strategy.template get_area_strategy<point_type>());
+ if (predicate(area, zero))
{
return visitor.template apply<no_failure>();
}
@@ -150,8 +148,9 @@ template
>
struct is_valid_ring
{
- template <typename VisitPolicy>
- static inline bool apply(Ring const& ring, VisitPolicy& visitor)
+ template <typename VisitPolicy, typename Strategy>
+ static inline bool apply(Ring const& ring, VisitPolicy& visitor,
+ Strategy const& strategy)
{
// return invalid if any of the following condition holds:
// (a) the ring's point coordinates are not invalid (e.g., NaN)
@@ -198,8 +197,8 @@ struct is_valid_ring
&& ! has_duplicates<Ring, closure>::apply(ring, visitor)
&& ! has_spikes<Ring, closure>::apply(ring, visitor)
&& (! CheckSelfIntersections
- || has_valid_self_turns<Ring>::apply(ring, visitor))
- && is_properly_oriented<Ring, IsInteriorRing>::apply(ring, visitor);
+ || has_valid_self_turns<Ring>::apply(ring, visitor, strategy))
+ && is_properly_oriented<Ring, IsInteriorRing>::apply(ring, visitor, strategy);
}
};
diff --git a/boost/geometry/algorithms/detail/is_valid/segment.hpp b/boost/geometry/algorithms/detail/is_valid/segment.hpp
index f92f73381f..30cbf7afdb 100644
--- a/boost/geometry/algorithms/detail/is_valid/segment.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/segment.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014-2015, Oracle and/or its affiliates.
+// Copyright (c) 2014-2017, 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
@@ -44,8 +44,8 @@ namespace dispatch
template <typename Segment>
struct is_valid<Segment, segment_tag>
{
- template <typename VisitPolicy>
- static inline bool apply(Segment const& segment, VisitPolicy& visitor)
+ template <typename VisitPolicy, typename Strategy>
+ static inline bool apply(Segment const& segment, VisitPolicy& visitor, Strategy const&)
{
boost::ignore_unused(visitor);
diff --git a/boost/geometry/algorithms/detail/not.hpp b/boost/geometry/algorithms/detail/not.hpp
index 43e71e2e37..95cdfa24e6 100644
--- a/boost/geometry/algorithms/detail/not.hpp
+++ b/boost/geometry/algorithms/detail/not.hpp
@@ -4,10 +4,11 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2017.
+// Modifications copyright (c) 2015-2017, 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.
@@ -46,6 +47,14 @@ struct not_
{
return ! Policy::apply(geometry1, geometry2);
}
+
+ template <typename Geometry1, typename Geometry2, typename Strategy>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+ {
+ return ! Policy::apply(geometry1, geometry2, strategy);
+ }
};
diff --git a/boost/geometry/algorithms/detail/overlay/assign_parents.hpp b/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
index 047eb4993e..2408b4b68e 100644
--- a/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
+++ b/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
@@ -2,6 +2,10 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017 Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// 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)
@@ -258,8 +262,9 @@ inline void assign_parents(Geometry1 const& geometry1,
geometry::partition
<
- box_type, ring_info_helper_get_box, ring_info_helper_ovelaps_box
- >::apply(vector, visitor);
+ box_type
+ >::apply(vector, visitor, ring_info_helper_get_box(),
+ ring_info_helper_ovelaps_box());
}
if (check_for_orientation)
diff --git a/boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp b/boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp
index a8171e1482..9beb8ad64f 100644
--- a/boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp
+++ b/boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp
@@ -2,6 +2,10 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// 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)
@@ -106,19 +110,27 @@ class backtrack_check_self_intersections
public :
typedef state state_type;
- template <typename Operation, typename Rings, typename Ring, typename Turns, typename RobustPolicy, typename Visitor>
+ template
+ <
+ typename Operation,
+ typename Rings, typename Ring, typename Turns,
+ typename Strategy,
+ typename RobustPolicy,
+ typename Visitor
+ >
static inline void apply(std::size_t size_at_start,
- Rings& rings, Ring& ring,
- Turns& turns,
- typename boost::range_value<Turns>::type const& turn,
- Operation& operation,
- traverse_error_type traverse_error,
- Geometry1 const& geometry1,
- Geometry2 const& geometry2,
- RobustPolicy const& robust_policy,
- state_type& state,
- Visitor& visitor
- )
+ Rings& rings,
+ Ring& ring,
+ Turns& turns,
+ typename boost::range_value<Turns>::type const& turn,
+ Operation& operation,
+ traverse_error_type traverse_error,
+ Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy,
+ RobustPolicy const& robust_policy,
+ state_type& state,
+ Visitor& visitor)
{
visitor.visit_traverse_reject(turns, turn, operation, traverse_error);
@@ -128,8 +140,8 @@ public :
if (! state.m_checked)
{
state.m_checked = true;
- has_self_intersections(geometry1, robust_policy);
- has_self_intersections(geometry2, robust_policy);
+ has_self_intersections(geometry1, strategy, robust_policy);
+ has_self_intersections(geometry2, strategy, robust_policy);
}
// Make bad output clean
diff --git a/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp b/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp
index b9e48cdbfc..c249ff57ff 100644
--- a/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp
+++ b/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp
@@ -1,5 +1,7 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
+
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Licensed under the Boost Software License version 1.0.
@@ -15,6 +17,7 @@
#include <iterator>
#include <boost/range.hpp>
+#include <boost/throw_exception.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/tag.hpp>
@@ -307,7 +310,7 @@ public:
#if ! defined(BOOST_GEOMETRY_OVERLAY_NO_THROW)
if (enter_count != 0)
{
- throw inconsistent_turns_exception();
+ BOOST_THROW_EXCEPTION(inconsistent_turns_exception());
}
#else
BOOST_GEOMETRY_ASSERT(enter_count == 0);
diff --git a/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp b/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp
index 99281eaecb..94667d0ed0 100644
--- a/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp
@@ -2,6 +2,11 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// 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)
@@ -39,29 +44,33 @@ template
>
struct get_turn_without_info
{
- template <typename RobustPolicy, typename OutputIterator>
+ template <typename Strategy, typename RobustPolicy, typename OutputIterator>
static inline OutputIterator apply(
Point1 const& pi, Point1 const& pj, Point1 const& /*pk*/,
Point2 const& qi, Point2 const& qj, Point2 const& /*qk*/,
bool /*is_p_first*/, bool /*is_p_last*/,
bool /*is_q_first*/, bool /*is_q_last*/,
TurnInfo const& ,
+ Strategy const& strategy,
RobustPolicy const& robust_policy,
OutputIterator out)
{
- typedef intersection_strategies
- <
- typename cs_tag<typename TurnInfo::point_type>::type,
- Point1,
- Point2,
- typename TurnInfo::point_type,
- RobustPolicy
- > si;
+ typedef typename TurnInfo::point_type turn_point_type;
- typedef typename si::segment_intersection_strategy_type strategy;
+ typedef policies::relate::segments_intersection_points
+ <
+ segment_intersection_points
+ <
+ turn_point_type,
+ typename geometry::segment_ratio_type
+ <
+ turn_point_type, RobustPolicy
+ >::type
+ >
+ > policy_type;
typedef model::referring_segment<Point1 const> segment_type1;
- typedef model::referring_segment<Point1 const> segment_type2;
+ typedef model::referring_segment<Point2 const> segment_type2;
segment_type1 p1(pi, pj);
segment_type2 q1(qi, qj);
@@ -75,15 +84,14 @@ struct get_turn_without_info
geometry::recalculate(pj_rob, pj, robust_policy);
geometry::recalculate(qi_rob, qi, robust_policy);
geometry::recalculate(qj_rob, qj, robust_policy);
- typename strategy::return_type result
- = strategy::apply(p1, q1, robust_policy,
- pi_rob, pj_rob, qi_rob, qj_rob);
+ typename policy_type::return_type result
+ = strategy.apply(p1, q1, policy_type(), robust_policy,
+ pi_rob, pj_rob, qi_rob, qj_rob);
- for (std::size_t i = 0; i < result.template get<0>().count; i++)
+ for (std::size_t i = 0; i < result.count; i++)
{
-
TurnInfo tp;
- geometry::convert(result.template get<0>().intersections[i], tp.point);
+ geometry::convert(result.intersections[i], tp.point);
*out++ = tp;
}
@@ -102,12 +110,14 @@ template
typename Geometry1,
typename Geometry2,
typename RobustPolicy,
- typename Turns
+ typename Turns,
+ typename Strategy
>
inline void get_intersection_points(Geometry1 const& geometry1,
Geometry2 const& geometry2,
RobustPolicy const& robust_policy,
- Turns& turns)
+ Turns& turns,
+ Strategy const& strategy)
{
concepts::check_concepts_and_equal_dimensions<Geometry1 const, Geometry2 const>();
@@ -142,6 +152,7 @@ inline void get_intersection_points(Geometry1 const& geometry1,
>::type::apply(
0, geometry1,
1, geometry2,
+ strategy,
robust_policy,
turns, interrupt_policy);
}
diff --git a/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp b/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp
index a4cce3fd32..08bc342186 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp
@@ -1,9 +1,10 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2017.
+// Modifications copyright (c) 2015-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -16,10 +17,10 @@
#include <boost/core/ignore_unused.hpp>
+#include <boost/throw_exception.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/assert.hpp>
-#include <boost/geometry/strategies/intersection_strategies.hpp>
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
@@ -644,7 +645,7 @@ struct collinear : public base_turn_handler
// causes currently cycling include problems
typedef typename geometry::coordinate_type<Point1>::type ctype;
ctype const dx = get<0>(a) - get<0>(b);
- ctype const dy = get<1>(b) - get<1>(b);
+ ctype const dy = get<1>(a) - get<1>(b);
return dx * dx + dy * dy;
}
};
@@ -930,6 +931,7 @@ struct get_turn_info
typename Point1,
typename Point2,
typename TurnInfo,
+ typename IntersectionStrategy,
typename RobustPolicy,
typename OutputIterator
>
@@ -939,13 +941,19 @@ struct get_turn_info
bool /*is_p_first*/, bool /*is_p_last*/,
bool /*is_q_first*/, bool /*is_q_last*/,
TurnInfo const& tp_model,
+ IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
OutputIterator out)
{
- typedef intersection_info<Point1, Point2, typename TurnInfo::point_type, RobustPolicy>
- inters_info;
+ typedef intersection_info
+ <
+ Point1, Point2,
+ typename TurnInfo::point_type,
+ IntersectionStrategy,
+ RobustPolicy
+ > inters_info;
- inters_info inters(pi, pj, pk, qi, qj, qk, robust_policy);
+ inters_info inters(pi, pj, pk, qi, qj, qk, intersection_strategy, robust_policy);
char const method = inters.d_info().how;
@@ -991,9 +999,12 @@ struct get_turn_info
<
typename inters_info::cs_tag,
typename inters_info::robust_point2_type,
- typename inters_info::robust_point1_type
+ typename inters_info::robust_point1_type,
+ typename inters_info::side_strategy_type
> swapped_side_calc(inters.rqi(), inters.rqj(), inters.rqk(),
- inters.rpi(), inters.rpj(), inters.rpk());
+ inters.rpi(), inters.rpj(), inters.rpk(),
+ inters.get_side_strategy());
+
policy::template apply<1>(qi, qj, qk, pi, pj, pk,
tp, inters.i_info(), inters.d_info(),
swapped_side_calc);
@@ -1093,7 +1104,7 @@ struct get_turn_info
std::cout << "TURN: Unknown method: " << method << std::endl;
#endif
#if ! defined(BOOST_GEOMETRY_OVERLAY_NO_THROW)
- throw turn_info_exception(method);
+ BOOST_THROW_EXCEPTION(turn_info_exception(method));
#endif
}
break;
diff --git a/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp b/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp
index 85cdfbc02d..48716634c5 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp
@@ -2,15 +2,15 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014.
-// Modifications copyright (c) 2013-2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2017.
+// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// 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)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_FOR_ENDPOINT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_FOR_ENDPOINT_HPP
@@ -427,8 +427,11 @@ struct get_turn_info_for_endpoint
}
else if ( ip_j2 )
{
- side_calculator<cs_tag, RobustPoint1, RobustPoint2, RobustPoint2>
- side_calc(ri2, ri1, rj1, ri2, rj2, rk2);
+ side_calculator<cs_tag,
+ RobustPoint1, RobustPoint2,
+ typename IntersectionInfo::side_strategy_type,
+ RobustPoint2>
+ side_calc(ri2, ri1, rj1, ri2, rj2, rk2, inters.get_side_strategy());
std::pair<operation_type, operation_type>
operations = operations_of_equal(side_calc);
@@ -478,8 +481,10 @@ struct get_turn_info_for_endpoint
}
else if ( ip_j2 )
{
- side_calculator<cs_tag, RobustPoint1, RobustPoint2, RobustPoint2>
- side_calc(ri2, rj1, ri1, ri2, rj2, rk2);
+ side_calculator<cs_tag, RobustPoint1, RobustPoint2,
+ typename IntersectionInfo::side_strategy_type,
+ RobustPoint2>
+ side_calc(ri2, rj1, ri1, ri2, rj2, rk2, inters.get_side_strategy());
std::pair<operation_type, operation_type>
operations = operations_of_equal(side_calc);
diff --git a/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp b/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp
index 3e7da1d797..5f2cb07faf 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp
@@ -2,15 +2,15 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014, 2015.
-// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017.
+// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// 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)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HELPERS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HELPERS_HPP
@@ -37,32 +37,27 @@ struct turn_operation_linear
};
template <typename TurnPointCSTag, typename PointP, typename PointQ,
+ typename SideStrategy,
typename Pi = PointP, typename Pj = PointP, typename Pk = PointP,
typename Qi = PointQ, typename Qj = PointQ, typename Qk = PointQ
>
struct side_calculator
{
- // This strategy should be the same as side strategy defined in
- // intersection_strategies<> which is used in various places
- // of the library
- typedef typename strategy::side::services::default_strategy
- <
- TurnPointCSTag
- >::type side;
-
inline side_calculator(Pi const& pi, Pj const& pj, Pk const& pk,
- Qi const& qi, Qj const& qj, Qk const& qk)
+ Qi const& qi, Qj const& qj, Qk const& qk,
+ SideStrategy const& side_strategy)
: m_pi(pi), m_pj(pj), m_pk(pk)
, m_qi(qi), m_qj(qj), m_qk(qk)
+ , m_side_strategy(side_strategy)
{}
- inline int pk_wrt_p1() const { return side::apply(m_pi, m_pj, m_pk); }
- inline int pk_wrt_q1() const { return side::apply(m_qi, m_qj, m_pk); }
- inline int qk_wrt_p1() const { return side::apply(m_pi, m_pj, m_qk); }
- inline int qk_wrt_q1() const { return side::apply(m_qi, m_qj, m_qk); }
+ inline int pk_wrt_p1() const { return m_side_strategy.apply(m_pi, m_pj, m_pk); }
+ inline int pk_wrt_q1() const { return m_side_strategy.apply(m_qi, m_qj, m_pk); }
+ inline int qk_wrt_p1() const { return m_side_strategy.apply(m_pi, m_pj, m_qk); }
+ inline int qk_wrt_q1() const { return m_side_strategy.apply(m_qi, m_qj, m_qk); }
- inline int pk_wrt_q2() const { return side::apply(m_qj, m_qk, m_pk); }
- inline int qk_wrt_p2() const { return side::apply(m_pj, m_pk, m_qk); }
+ inline int pk_wrt_q2() const { return m_side_strategy.apply(m_qj, m_qk, m_pk); }
+ inline int qk_wrt_p2() const { return m_side_strategy.apply(m_pj, m_pk, m_qk); }
Pi const& m_pi;
Pj const& m_pj;
@@ -70,6 +65,8 @@ struct side_calculator
Qi const& m_qi;
Qj const& m_qj;
Qk const& m_qk;
+
+ SideStrategy const& m_side_strategy;
};
template <typename Point1, typename Point2, typename RobustPolicy>
@@ -99,7 +96,7 @@ struct robust_points
robust_point2_type m_rqi, m_rqj, m_rqk;
};
-template <typename Point1, typename Point2, typename TurnPoint, typename RobustPolicy>
+template <typename Point1, typename Point2, typename TurnPoint, typename IntersectionStrategy, typename RobustPolicy>
class intersection_info_base
: private robust_points<Point1, Point2, RobustPolicy>
{
@@ -114,14 +111,17 @@ public:
typedef typename cs_tag<TurnPoint>::type cs_tag;
- typedef side_calculator<cs_tag, robust_point1_type, robust_point2_type> side_calculator_type;
+ typedef typename IntersectionStrategy::side_strategy_type side_strategy_type;
+ typedef side_calculator<cs_tag, robust_point1_type, robust_point2_type, side_strategy_type> side_calculator_type;
intersection_info_base(Point1 const& pi, Point1 const& pj, Point1 const& pk,
Point2 const& qi, Point2 const& qj, Point2 const& qk,
+ IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy)
: base(pi, pj, pk, qi, qj, qk, robust_policy)
, m_side_calc(base::m_rpi, base::m_rpj, base::m_rpk,
- base::m_rqi, base::m_rqj, base::m_rqk)
+ base::m_rqi, base::m_rqj, base::m_rqk,
+ intersection_strategy.get_side_strategy())
, m_pi(pi), m_pj(pj), m_pk(pk)
, m_qi(qi), m_qj(qj), m_qk(qk)
{}
@@ -155,8 +155,8 @@ private:
point2_type const& m_qk;
};
-template <typename Point1, typename Point2, typename TurnPoint>
-class intersection_info_base<Point1, Point2, TurnPoint, detail::no_rescale_policy>
+template <typename Point1, typename Point2, typename TurnPoint, typename IntersectionStrategy>
+class intersection_info_base<Point1, Point2, TurnPoint, IntersectionStrategy, detail::no_rescale_policy>
{
public:
typedef Point1 point1_type;
@@ -167,12 +167,15 @@ public:
typedef typename cs_tag<TurnPoint>::type cs_tag;
- typedef side_calculator<cs_tag, Point1, Point2> side_calculator_type;
+ typedef typename IntersectionStrategy::side_strategy_type side_strategy_type;
+ typedef side_calculator<cs_tag, Point1, Point2, side_strategy_type> side_calculator_type;
intersection_info_base(Point1 const& pi, Point1 const& pj, Point1 const& pk,
Point2 const& qi, Point2 const& qj, Point2 const& qk,
+ IntersectionStrategy const& intersection_strategy,
no_rescale_policy const& /*robust_policy*/)
- : m_side_calc(pi, pj, pk, qi, qj, qk)
+ : m_side_calc(pi, pj, pk, qi, qj, qk,
+ intersection_strategy.get_side_strategy())
{}
inline Point1 const& pi() const { return m_side_calc.m_pi; }
@@ -203,40 +206,58 @@ template
typename Point1,
typename Point2,
typename TurnPoint,
+ typename IntersectionStrategy,
typename RobustPolicy
>
class intersection_info
- : public intersection_info_base<Point1, Point2, TurnPoint, RobustPolicy>
+ : public intersection_info_base<Point1, Point2, TurnPoint, IntersectionStrategy, RobustPolicy>
{
- typedef intersection_info_base<Point1, Point2, TurnPoint, RobustPolicy> base;
+ typedef intersection_info_base<Point1, Point2, TurnPoint, IntersectionStrategy, RobustPolicy> base;
+
+public:
+ typedef segment_intersection_points
+ <
+ TurnPoint,
+ typename geometry::segment_ratio_type
+ <
+ TurnPoint, RobustPolicy
+ >::type
+ > intersection_point_type;
- typedef typename intersection_strategies
+ // NOTE: formerly defined in intersection_strategies
+ typedef policies::relate::segments_tupled
<
- typename base::cs_tag,
- Point1,
- Point2,
- TurnPoint,
- RobustPolicy
- >::segment_intersection_strategy_type strategy;
+ policies::relate::segments_intersection_points
+ <
+ intersection_point_type
+ >,
+ policies::relate::segments_direction
+ > intersection_policy_type;
+
+ typedef IntersectionStrategy intersection_strategy_type;
+ typedef typename IntersectionStrategy::side_strategy_type side_strategy_type;
-public:
typedef model::referring_segment<Point1 const> segment_type1;
typedef model::referring_segment<Point2 const> segment_type2;
typedef typename base::side_calculator_type side_calculator_type;
- typedef typename strategy::return_type result_type;
+ typedef typename intersection_policy_type::return_type result_type;
typedef typename boost::tuples::element<0, result_type>::type i_info_type; // intersection_info
typedef typename boost::tuples::element<1, result_type>::type d_info_type; // dir_info
intersection_info(Point1 const& pi, Point1 const& pj, Point1 const& pk,
Point2 const& qi, Point2 const& qj, Point2 const& qk,
+ IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy)
- : base(pi, pj, pk, qi, qj, qk, robust_policy)
- , m_result(strategy::apply(segment_type1(pi, pj),
- segment_type2(qi, qj),
- robust_policy,
- base::rpi(), base::rpj(),
- base::rqi(), base::rqj()))
+ : base(pi, pj, pk, qi, qj, qk, intersection_strategy, robust_policy)
+ , m_result(intersection_strategy.apply(
+ segment_type1(pi, pj),
+ segment_type2(qi, qj),
+ intersection_policy_type(),
+ robust_policy,
+ base::rpi(), base::rpj(),
+ base::rqi(), base::rqj()))
+ , m_intersection_strategy(intersection_strategy)
, m_robust_policy(robust_policy)
{}
@@ -244,6 +265,16 @@ public:
inline i_info_type const& i_info() const { return m_result.template get<0>(); }
inline d_info_type const& d_info() const { return m_result.template get<1>(); }
+ inline intersection_strategy_type const& get_intersection_strategy() const
+ {
+ return m_intersection_strategy;
+ }
+
+ inline side_strategy_type get_side_strategy() const
+ {
+ return m_intersection_strategy.get_side_strategy();
+ }
+
// TODO: it's more like is_spike_ip_p
inline bool is_spike_p() const
{
@@ -307,17 +338,18 @@ private:
{
typedef model::referring_segment<Point const> seg;
- typedef intersection_strategies
- <
- typename base::cs_tag, Point, Point, Point, RobustPolicy
- > si;
-
- typedef typename si::segment_intersection_strategy_type strategy;
-
- typename strategy::return_type result
- = strategy::apply(seg(i, j), seg(j, k), m_robust_policy);
+ // no need to calcualte direction info
+ typedef policies::relate::segments_intersection_points
+ <
+ intersection_point_type
+ > policy_type;
+
+ typename policy_type::return_type const result
+ = m_intersection_strategy.apply(seg(i, j), seg(j, k),
+ policy_type(),
+ m_robust_policy);
- return result.template get<0>().count == 2;
+ return result.count == 2;
}
template <std::size_t OpId>
@@ -344,6 +376,7 @@ private:
}
result_type m_result;
+ IntersectionStrategy const& m_intersection_strategy;
RobustPolicy const& m_robust_policy;
};
diff --git a/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp b/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp
index 121728d822..46c1305cd7 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp
@@ -1,9 +1,10 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013, 2014, 2015.
-// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017.
+// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -14,6 +15,8 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_LA_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_LA_HPP
+#include <boost/throw_exception.hpp>
+
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/util/condition.hpp>
@@ -41,6 +44,7 @@ struct get_turn_info_linear_areal
typename Point1,
typename Point2,
typename TurnInfo,
+ typename IntersectionStrategy,
typename RobustPolicy,
typename OutputIterator
>
@@ -50,13 +54,19 @@ struct get_turn_info_linear_areal
bool is_p_first, bool is_p_last,
bool is_q_first, bool is_q_last,
TurnInfo const& tp_model,
+ IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
OutputIterator out)
{
- typedef intersection_info<Point1, Point2, typename TurnInfo::point_type, RobustPolicy>
- inters_info;
+ typedef intersection_info
+ <
+ Point1, Point2,
+ typename TurnInfo::point_type,
+ IntersectionStrategy,
+ RobustPolicy
+ > inters_info;
- inters_info inters(pi, pj, pk, qi, qj, qk, robust_policy);
+ inters_info inters(pi, pj, pk, qi, qj, qk, intersection_strategy, robust_policy);
char const method = inters.d_info().how;
@@ -108,9 +118,11 @@ struct get_turn_info_linear_areal
<
typename inters_info::cs_tag,
typename inters_info::robust_point2_type,
- typename inters_info::robust_point1_type
+ typename inters_info::robust_point1_type,
+ typename inters_info::side_strategy_type
> swapped_side_calc(inters.rqi(), inters.rqj(), inters.rqk(),
- inters.rpi(), inters.rpj(), inters.rpk());
+ inters.rpi(), inters.rpj(), inters.rpk(),
+ inters.get_side_strategy());
policy::template apply<1>(qi, qj, qk, pi, pj, pk,
tp, inters.i_info(), inters.d_info(),
swapped_side_calc);
@@ -395,7 +407,7 @@ struct get_turn_info_linear_areal
std::cout << "TURN: Unknown method: " << method << std::endl;
#endif
#if ! defined(BOOST_GEOMETRY_OVERLAY_NO_THROW)
- throw turn_info_exception(method);
+ BOOST_THROW_EXCEPTION(turn_info_exception(method));
#endif
}
break;
@@ -747,6 +759,9 @@ struct get_turn_info_linear_areal
}
else
{
+ typedef typename IntersectionInfo::robust_point1_type rp1_type;
+ typedef typename IntersectionInfo::robust_point2_type rp2_type;
+
method_type replaced_method = method_touch_interior;
if ( ip0.is_qj )
@@ -754,11 +769,12 @@ struct get_turn_info_linear_areal
side_calculator
<
typename IntersectionInfo::cs_tag,
- typename IntersectionInfo::robust_point1_type,
- typename IntersectionInfo::robust_point2_type,
- typename IntersectionInfo::robust_point2_type
+ rp1_type, rp2_type,
+ typename IntersectionInfo::side_strategy_type,
+ rp2_type
> side_calc(inters.rqi(), inters.rpi(), inters.rpj(),
- inters.rqi(), inters.rqj(), inters.rqk());
+ inters.rqi(), inters.rqj(), inters.rqk(),
+ inters.get_side_strategy());
std::pair<operation_type, operation_type>
operations = get_info_e::operations_of_equal(side_calc);
@@ -773,16 +789,13 @@ struct get_turn_info_linear_areal
side_calculator
<
typename IntersectionInfo::cs_tag,
- typename IntersectionInfo::robust_point1_type,
- typename IntersectionInfo::robust_point2_type,
- typename IntersectionInfo::robust_point2_type,
- typename IntersectionInfo::robust_point1_type,
- typename IntersectionInfo::robust_point1_type,
- typename IntersectionInfo::robust_point2_type,
- typename IntersectionInfo::robust_point1_type,
- typename IntersectionInfo::robust_point2_type
+ rp1_type, rp2_type,
+ typename IntersectionInfo::side_strategy_type,
+ rp2_type, rp1_type, rp1_type,
+ rp2_type, rp1_type, rp2_type
> side_calc(inters.rqi(), inters.rpi(), inters.rpj(),
- inters.rqi(), inters.rpi(), inters.rqj());
+ inters.rqi(), inters.rpi(), inters.rqj(),
+ inters.get_side_strategy());
std::pair<operation_type, operation_type>
operations = get_info_e::operations_of_equal(side_calc);
@@ -832,9 +845,11 @@ struct get_turn_info_linear_areal
typename IntersectionInfo::cs_tag,
typename IntersectionInfo::robust_point1_type,
typename IntersectionInfo::robust_point2_type,
+ typename IntersectionInfo::side_strategy_type,
typename IntersectionInfo::robust_point2_type
> side_calc(inters.rqi(), inters.rpj(), inters.rpi(),
- inters.rqi(), inters.rqj(), inters.rqk());
+ inters.rqi(), inters.rqj(), inters.rqk(),
+ inters.get_side_strategy());
std::pair<operation_type, operation_type>
operations = get_info_e::operations_of_equal(side_calc);
diff --git a/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp b/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp
index 6bb3a74bb8..58fd4bb5c7 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp
@@ -1,19 +1,22 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013, 2014, 2015.
-// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017.
+// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// 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)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_LL_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_LL_HPP
+#include <boost/throw_exception.hpp>
+
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
@@ -36,6 +39,7 @@ struct get_turn_info_linear_linear
typename Point1,
typename Point2,
typename TurnInfo,
+ typename IntersectionStrategy,
typename RobustPolicy,
typename OutputIterator
>
@@ -45,13 +49,19 @@ struct get_turn_info_linear_linear
bool is_p_first, bool is_p_last,
bool is_q_first, bool is_q_last,
TurnInfo const& tp_model,
+ IntersectionStrategy const& strategy,
RobustPolicy const& robust_policy,
OutputIterator out)
{
- typedef intersection_info<Point1, Point2, typename TurnInfo::point_type, RobustPolicy>
- inters_info;
+ typedef intersection_info
+ <
+ Point1, Point2,
+ typename TurnInfo::point_type,
+ IntersectionStrategy,
+ RobustPolicy
+ > inters_info;
- inters_info inters(pi, pj, pk, qi, qj, qk, robust_policy);
+ inters_info inters(pi, pj, pk, qi, qj, qk, strategy, robust_policy);
char const method = inters.d_info().how;
@@ -103,9 +113,11 @@ struct get_turn_info_linear_linear
<
typename inters_info::cs_tag,
typename inters_info::robust_point2_type,
- typename inters_info::robust_point1_type
+ typename inters_info::robust_point1_type,
+ typename inters_info::side_strategy_type
> swapped_side_calc(inters.rqi(), inters.rqj(), inters.rqk(),
- inters.rpi(), inters.rpj(), inters.rpk());
+ inters.rpi(), inters.rpj(), inters.rpk(),
+ inters.get_side_strategy());
policy::template apply<1>(qi, qj, qk, pi, pj, pk,
tp, inters.i_info(), inters.d_info(),
@@ -463,7 +475,7 @@ struct get_turn_info_linear_linear
std::cout << "TURN: Unknown method: " << method << std::endl;
#endif
#if ! defined(BOOST_GEOMETRY_OVERLAY_NO_THROW)
- throw turn_info_exception(method);
+ BOOST_THROW_EXCEPTION(turn_info_exception(method));
#endif
}
break;
diff --git a/boost/geometry/algorithms/detail/overlay/get_turns.hpp b/boost/geometry/algorithms/detail/overlay/get_turns.hpp
index 1eb18b74d4..4e97a84a37 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turns.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turns.hpp
@@ -3,15 +3,15 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2014, 2016.
-// Modifications copyright (c) 2014, 2016 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2016, 2017.
+// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// 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)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP
@@ -45,7 +45,6 @@
#include <boost/geometry/iterators/ever_circling_iterator.hpp>
-#include <boost/geometry/strategies/cartesian/cart_intersect.hpp>
#include <boost/geometry/strategies/intersection_strategies.hpp>
#include <boost/geometry/strategies/intersection_result.hpp>
@@ -174,11 +173,12 @@ class get_turns_in_sections
public :
// Returns true if terminated, false if interrupted
- template <typename Turns, typename RobustPolicy, typename InterruptPolicy>
+ template <typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline bool apply(
int source_id1, Geometry1 const& geometry1, Section1 const& sec1,
int source_id2, Geometry2 const& geometry2, Section2 const& sec2,
bool skip_larger,
+ IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
Turns& turns,
InterruptPolicy& interrupt_policy)
@@ -295,7 +295,8 @@ public :
TurnPolicy::apply(*prev1, *it1, *nd_next1, *prev2, *it2, *nd_next2,
is_1_first, is_1_last, is_2_first, is_2_last,
- ti, robust_policy, std::back_inserter(turns));
+ ti, intersection_strategy, robust_policy,
+ std::back_inserter(turns));
if (InterruptPolicy::enabled)
{
@@ -381,9 +382,10 @@ template
<
typename Geometry1, typename Geometry2,
bool Reverse1, bool Reverse2,
- typename Turns,
typename TurnPolicy,
+ typename IntersectionStrategy,
typename RobustPolicy,
+ typename Turns,
typename InterruptPolicy
>
struct section_visitor
@@ -392,16 +394,20 @@ struct section_visitor
Geometry1 const& m_geometry1;
int m_source_id2;
Geometry2 const& m_geometry2;
+ IntersectionStrategy const& m_intersection_strategy;
RobustPolicy const& m_rescale_policy;
Turns& m_turns;
InterruptPolicy& m_interrupt_policy;
section_visitor(int id1, Geometry1 const& g1,
- int id2, Geometry2 const& g2,
- RobustPolicy const& robust_policy,
- Turns& turns, InterruptPolicy& ip)
+ int id2, Geometry2 const& g2,
+ IntersectionStrategy const& intersection_strategy,
+ RobustPolicy const& robust_policy,
+ Turns& turns,
+ InterruptPolicy& ip)
: m_source_id1(id1), m_geometry1(g1)
, m_source_id2(id2), m_geometry2(g2)
+ , m_intersection_strategy(intersection_strategy)
, m_rescale_policy(robust_policy)
, m_turns(turns)
, m_interrupt_policy(ip)
@@ -423,6 +429,7 @@ struct section_visitor
m_source_id1, m_geometry1, sec1,
m_source_id2, m_geometry2, sec2,
false,
+ m_intersection_strategy,
m_rescale_policy,
m_turns, m_interrupt_policy);
}
@@ -441,10 +448,11 @@ class get_turns_generic
{
public:
- template <typename RobustPolicy, typename Turns, typename InterruptPolicy>
+ template <typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline void apply(
int source_id1, Geometry1 const& geometry1,
int source_id2, Geometry2 const& geometry2,
+ IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
Turns& turns,
InterruptPolicy& interrupt_policy)
@@ -475,15 +483,19 @@ public:
<
Geometry1, Geometry2,
Reverse1, Reverse2,
- Turns, TurnPolicy, RobustPolicy, InterruptPolicy
- > visitor(source_id1, geometry1, source_id2, geometry2, robust_policy, turns, interrupt_policy);
+ TurnPolicy,
+ IntersectionStrategy, RobustPolicy,
+ Turns, InterruptPolicy
+ > visitor(source_id1, geometry1, source_id2, geometry2,
+ intersection_strategy, robust_policy,
+ turns, interrupt_policy);
geometry::partition
<
- box_type,
- detail::section::get_section_box,
- detail::section::overlaps_section_box
- >::apply(sec1, sec2, visitor);
+ box_type
+ >::apply(sec1, sec2, visitor,
+ detail::section::get_section_box(),
+ detail::section::overlaps_section_box());
}
};
@@ -518,10 +530,11 @@ struct get_turns_cs
>::type iterator_type;
- template <typename RobustPolicy, typename Turns, typename InterruptPolicy>
+ template <typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline void apply(
int source_id1, Range const& range,
int source_id2, Box const& box,
+ IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
Turns& turns,
InterruptPolicy& interrupt_policy,
@@ -593,8 +606,10 @@ struct get_turns_cs
// NOTE: some dummy values could be passed below since this would be called only for Polygons and Boxes
index == 0,
size_type(index) == segments_count1,
+ intersection_strategy,
robust_policy,
- turns, interrupt_policy);
+ turns,
+ interrupt_policy);
// Future performance enhancement:
// return if told by the interrupt policy
}
@@ -622,7 +637,7 @@ private:
else return 0;
}
- template <typename RobustPolicy, typename Turns, typename InterruptPolicy>
+ template <typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline void get_turns_with_box(segment_identifier const& seg_id, int source_id2,
// Points from a range:
point_type const& rp0,
@@ -635,6 +650,7 @@ private:
box_point_type const& bp3,
bool const is_range_first,
bool const is_range_last,
+ IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
// Output
Turns& turns,
@@ -653,25 +669,29 @@ private:
TurnPolicy::apply(rp0, rp1, rp2, bp0, bp1, bp2,
is_range_first, is_range_last,
true, false,
- ti, robust_policy, std::back_inserter(turns));
+ ti, intersection_strategy, robust_policy,
+ std::back_inserter(turns));
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 1);
TurnPolicy::apply(rp0, rp1, rp2, bp1, bp2, bp3,
is_range_first, is_range_last,
false, false,
- ti, robust_policy, std::back_inserter(turns));
+ ti, intersection_strategy, robust_policy,
+ std::back_inserter(turns));
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 2);
TurnPolicy::apply(rp0, rp1, rp2, bp2, bp3, bp0,
is_range_first, is_range_last,
false, false,
- ti, robust_policy, std::back_inserter(turns));
+ ti, intersection_strategy, robust_policy,
+ std::back_inserter(turns));
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 3);
TurnPolicy::apply(rp0, rp1, rp2, bp3, bp0, bp1,
is_range_first, is_range_last,
false, true,
- ti, robust_policy, std::back_inserter(turns));
+ ti, intersection_strategy, robust_policy,
+ std::back_inserter(turns));
if (InterruptPolicy::enabled)
{
@@ -691,12 +711,14 @@ template
>
struct get_turns_polygon_cs
{
- template <typename RobustPolicy, typename Turns, typename InterruptPolicy>
+ template <typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline void apply(
int source_id1, Polygon const& polygon,
int source_id2, Box const& box,
+ IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
- Turns& turns, InterruptPolicy& interrupt_policy,
+ Turns& turns,
+ InterruptPolicy& interrupt_policy,
signed_size_type multi_index = -1)
{
typedef typename geometry::ring_type<Polygon>::type ring_type;
@@ -711,8 +733,10 @@ struct get_turns_polygon_cs
intersector_type::apply(
source_id1, geometry::exterior_ring(polygon),
source_id2, box,
+ intersection_strategy,
robust_policy,
- turns, interrupt_policy,
+ turns,
+ interrupt_policy,
multi_index, -1);
signed_size_type i = 0;
@@ -725,6 +749,7 @@ struct get_turns_polygon_cs
intersector_type::apply(
source_id1, *it,
source_id2, box,
+ intersection_strategy,
robust_policy,
turns, interrupt_policy,
multi_index, i);
@@ -742,12 +767,14 @@ template
>
struct get_turns_multi_polygon_cs
{
- template <typename RobustPolicy, typename Turns, typename InterruptPolicy>
+ template <typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline void apply(
int source_id1, Multi const& multi,
int source_id2, Box const& box,
+ IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
- Turns& turns, InterruptPolicy& interrupt_policy)
+ Turns& turns,
+ InterruptPolicy& interrupt_policy)
{
typedef typename boost::range_iterator
<
@@ -766,7 +793,8 @@ struct get_turns_multi_polygon_cs
Reverse, ReverseBox,
TurnPolicy
>::apply(source_id1, *it, source_id2, box,
- robust_policy, turns, interrupt_policy, i);
+ intersection_strategy, robust_policy,
+ turns, interrupt_policy, i);
}
}
};
@@ -918,13 +946,13 @@ template
>
struct get_turns_reversed
{
- template <typename RobustPolicy, typename Turns, typename InterruptPolicy>
- static inline void apply(
- int source_id1, Geometry1 const& g1,
- int source_id2, Geometry2 const& g2,
- RobustPolicy const& robust_policy,
- Turns& turns,
- InterruptPolicy& interrupt_policy)
+ template <typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
+ static inline void apply(int source_id1, Geometry1 const& g1,
+ int source_id2, Geometry2 const& g2,
+ IntersectionStrategy const& intersection_strategy,
+ RobustPolicy const& robust_policy,
+ Turns& turns,
+ InterruptPolicy& interrupt_policy)
{
get_turns
<
@@ -932,8 +960,9 @@ struct get_turns_reversed
Geometry2, Geometry1,
Reverse2, Reverse1,
TurnPolicy
- >::apply(source_id2, g2, source_id1, g1, robust_policy,
- turns, interrupt_policy);
+ >::apply(source_id2, g2, source_id1, g1,
+ intersection_strategy, robust_policy,
+ turns, interrupt_policy);
}
};
@@ -951,6 +980,7 @@ struct get_turns_reversed
\tparam Turns type of turn-container (e.g. vector of "intersection/turn point"'s)
\param geometry1 \param_geometry
\param geometry2 \param_geometry
+\param intersection_strategy segments intersection strategy
\param robust_policy policy to handle robustness issues
\param turns container which will contain turn points
\param interrupt_policy policy determining if process is stopped
@@ -962,15 +992,17 @@ template
typename AssignPolicy,
typename Geometry1,
typename Geometry2,
+ typename IntersectionStrategy,
typename RobustPolicy,
typename Turns,
typename InterruptPolicy
>
inline void get_turns(Geometry1 const& geometry1,
- Geometry2 const& geometry2,
- RobustPolicy const& robust_policy,
- Turns& turns,
- InterruptPolicy& interrupt_policy)
+ Geometry2 const& geometry2,
+ IntersectionStrategy const& intersection_strategy,
+ RobustPolicy const& robust_policy,
+ Turns& turns,
+ InterruptPolicy& interrupt_policy)
{
concepts::check_concepts_and_equal_dimensions<Geometry1 const, Geometry2 const>();
@@ -996,11 +1028,11 @@ inline void get_turns(Geometry1 const& geometry1,
Reverse1, Reverse2,
TurnPolicy
>
- >::type::apply(
- 0, geometry1,
- 1, geometry2,
- robust_policy,
- turns, interrupt_policy);
+ >::type::apply(0, geometry1,
+ 1, geometry2,
+ intersection_strategy,
+ robust_policy,
+ turns, interrupt_policy);
}
#if defined(_MSC_VER)
diff --git a/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp b/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp
index bb82003a23..3244480f48 100644
--- a/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp
+++ b/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp
@@ -2,10 +2,11 @@
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2014, 2015.
-// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2015, 2017.
+// Modifications copyright (c) 2014-2017 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
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -71,7 +72,7 @@ struct intersection_segment_segment_point
Segment2 const& segment2,
RobustPolicy const& robust_policy,
OutputIterator out,
- Strategy const& )
+ Strategy const& strategy)
{
typedef typename point_type<PointOut>::type point_type;
@@ -106,16 +107,15 @@ struct intersection_segment_segment_point
>::type
> intersection_return_type;
- typedef strategy::intersection::relate_cartesian_segments
+ typedef policies::relate::segments_intersection_points
<
- policies::relate::segments_intersection_points
- <
- intersection_return_type
- >
- > policy;
+ intersection_return_type
+ > policy_type;
- intersection_return_type is = policy::apply(segment1, segment2,
- robust_policy, pi_rob, pj_rob, qi_rob, qj_rob);
+ intersection_return_type
+ is = strategy.apply(segment1, segment2,
+ policy_type(), robust_policy,
+ pi_rob, pj_rob, qi_rob, qj_rob);
for (std::size_t i = 0; i < is.count; i++)
{
@@ -134,13 +134,14 @@ struct intersection_linestring_linestring_point
<
typename Linestring1, typename Linestring2,
typename RobustPolicy,
- typename OutputIterator, typename Strategy
+ typename OutputIterator,
+ typename Strategy
>
static inline OutputIterator apply(Linestring1 const& linestring1,
Linestring2 const& linestring2,
RobustPolicy const& robust_policy,
OutputIterator out,
- Strategy const& )
+ Strategy const& strategy)
{
typedef typename point_type<PointOut>::type point_type;
@@ -151,7 +152,8 @@ struct intersection_linestring_linestring_point
> turn_info;
std::deque<turn_info> turns;
- geometry::get_intersection_points(linestring1, linestring2, robust_policy, turns);
+ geometry::get_intersection_points(linestring1, linestring2,
+ robust_policy, turns, strategy);
for (typename boost::range_iterator<std::deque<turn_info> const>::type
it = boost::begin(turns); it != boost::end(turns); ++it)
@@ -295,7 +297,7 @@ struct intersection_of_linestring_with_areal
static inline OutputIterator apply(LineString const& linestring, Areal const& areal,
RobustPolicy const& robust_policy,
OutputIterator out,
- Strategy const& )
+ Strategy const& strategy)
{
if (boost::size(linestring) == 0)
{
@@ -325,7 +327,7 @@ struct intersection_of_linestring_with_areal
false,
(OverlayType == overlay_intersection ? ReverseAreal : !ReverseAreal),
detail::overlay::assign_null_policy
- >(linestring, areal, robust_policy, turns, policy);
+ >(linestring, areal, strategy, robust_policy, turns, policy);
if (no_crossing_turns_or_empty(turns))
{
@@ -621,7 +623,7 @@ struct intersection_insert
static inline OutputIterator apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
RobustPolicy const& robust_policy,
- OutputIterator out, Strategy const& )
+ OutputIterator out, Strategy const& strategy)
{
typedef detail::overlay::turn_info
@@ -635,7 +637,7 @@ struct intersection_insert
geometry::get_turns
<
false, false, detail::overlay::assign_null_policy
- >(geometry1, geometry2, robust_policy, turns, policy);
+ >(geometry1, geometry2, strategy, robust_policy, turns, policy);
for (typename std::vector<turn_info>::const_iterator it
= turns.begin(); it != turns.end(); ++it)
{
@@ -996,7 +998,11 @@ inline OutputIterator intersection_insert(Geometry1 const& geometry1,
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
- typedef typename Strategy::rescale_policy_type rescale_policy_type;
+ typedef typename geometry::rescale_policy_type
+ <
+ typename geometry::point_type<Geometry1>::type // TODO from both
+ >::type rescale_policy_type;
+
rescale_policy_type robust_policy
= geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
@@ -1037,22 +1043,13 @@ inline OutputIterator intersection_insert(Geometry1 const& geometry1,
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
- typedef typename geometry::rescale_policy_type
- <
- typename geometry::point_type<Geometry1>::type // TODO from both
- >::type rescale_policy_type;
-
- typedef intersection_strategies
+ typedef typename strategy::intersection::services::default_strategy
<
- typename cs_tag<GeometryOut>::type,
- Geometry1,
- Geometry2,
- typename geometry::point_type<GeometryOut>::type,
- rescale_policy_type
- > strategy;
-
+ typename cs_tag<GeometryOut>::type
+ >::type strategy_type;
+
return intersection_insert<GeometryOut>(geometry1, geometry2, out,
- strategy());
+ strategy_type());
}
}} // namespace detail::intersection
diff --git a/boost/geometry/algorithms/detail/overlay/linear_linear.hpp b/boost/geometry/algorithms/detail/overlay/linear_linear.hpp
index 34517f6590..a74bb33ba1 100644
--- a/boost/geometry/algorithms/detail/overlay/linear_linear.hpp
+++ b/boost/geometry/algorithms/detail/overlay/linear_linear.hpp
@@ -1,11 +1,12 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014-2015, Oracle and/or its affiliates.
+// Copyright (c) 2014-2017, Oracle and/or its affiliates.
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_LINEAR_LINEAR_HPP
@@ -158,11 +159,13 @@ protected:
typename Turns,
typename LinearGeometry1,
typename LinearGeometry2,
+ typename IntersectionStrategy,
typename RobustPolicy
>
static inline void compute_turns(Turns& turns,
LinearGeometry1 const& linear1,
LinearGeometry2 const& linear2,
+ IntersectionStrategy const& strategy,
RobustPolicy const& robust_policy)
{
turns.clear();
@@ -180,7 +183,7 @@ protected:
assign_policy
>,
RobustPolicy
- >::apply(turns, linear1, linear2, interrupt_policy, robust_policy);
+ >::apply(turns, linear1, linear2, interrupt_policy, strategy, robust_policy);
}
@@ -237,7 +240,7 @@ public:
Linear2 const& linear2,
RobustPolicy const& robust_policy,
OutputIterator oit,
- Strategy const& )
+ Strategy const& strategy)
{
typedef typename detail::relate::turns::get_turns
<
@@ -255,7 +258,7 @@ public:
typedef std::vector<turn_info> turns_container;
turns_container turns;
- compute_turns(turns, linear1, linear2, robust_policy);
+ compute_turns(turns, linear1, linear2, strategy, robust_policy);
if ( turns.empty() )
{
diff --git a/boost/geometry/algorithms/detail/overlay/overlay.hpp b/boost/geometry/algorithms/detail/overlay/overlay.hpp
index 09c80025a0..f1af2f1949 100644
--- a/boost/geometry/algorithms/detail/overlay/overlay.hpp
+++ b/boost/geometry/algorithms/detail/overlay/overlay.hpp
@@ -3,10 +3,11 @@
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2017.
+// Modifications copyright (c) 2015-2017, 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
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -184,7 +185,7 @@ struct overlay
Geometry1 const& geometry1, Geometry2 const& geometry2,
RobustPolicy const& robust_policy,
OutputIterator out,
- Strategy const& ,
+ Strategy const& strategy,
Visitor& visitor)
{
bool const is_empty1 = geometry::is_empty(geometry1);
@@ -233,7 +234,7 @@ std::cout << "get turns" << std::endl;
<
Reverse1, Reverse2,
detail::overlay::assign_null_policy
- >(geometry1, geometry2, robust_policy, turns, policy);
+ >(geometry1, geometry2, strategy, robust_policy, turns, policy);
visitor.visit_turns(1, turns);
@@ -262,6 +263,7 @@ std::cout << "traverse" << std::endl;
traverse<Reverse1, Reverse2, Geometry1, Geometry2, OverlayType>::apply
(
geometry1, geometry2,
+ strategy,
robust_policy,
turns, rings,
clusters,
diff --git a/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp b/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp
index 156cb54867..a26f54e008 100644
--- a/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp
+++ b/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp
@@ -1,12 +1,13 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2015, Oracle and/or its affiliates.
+// Copyright (c) 2015-2017, 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
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
-// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_POINTLIKE_LINEAR_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_POINTLIKE_LINEAR_HPP
@@ -69,12 +70,12 @@ struct point_linear_point
Linear const& linear,
RobustPolicy const&,
OutputIterator oit,
- Strategy const&)
+ Strategy const& strategy)
{
action_selector_pl_l
<
PointOut, OverlayType
- >::apply(point, Policy::apply(point, linear), oit);
+ >::apply(point, Policy::apply(point, linear, strategy), oit);
return oit;
}
};
@@ -95,7 +96,7 @@ struct multipoint_segment_point
Segment const& segment,
RobustPolicy const&,
OutputIterator oit,
- Strategy const&)
+ Strategy const& strategy)
{
for (typename boost::range_iterator<MultiPoint const>::type
it = boost::begin(multipoint);
@@ -105,7 +106,7 @@ struct multipoint_segment_point
action_selector_pl_l
<
PointOut, OverlayType
- >::apply(*it, Policy::apply(*it, segment), oit);
+ >::apply(*it, Policy::apply(*it, segment, strategy), oit);
}
return oit;
@@ -145,11 +146,14 @@ private:
}
};
- template <typename OutputIterator>
+ template <typename OutputIterator, typename Strategy>
class item_visitor_type
{
public:
- item_visitor_type(OutputIterator& oit) : m_oit(oit) {}
+ item_visitor_type(OutputIterator& oit, Strategy const& strategy)
+ : m_oit(oit)
+ , m_strategy(strategy)
+ {}
template <typename Item1, typename Item2>
inline void apply(Item1 const& item1, Item2 const& item2)
@@ -157,11 +161,12 @@ private:
action_selector_pl_l
<
PointOut, overlay_intersection
- >::apply(item1, Policy::apply(item1, item2), m_oit);
+ >::apply(item1, Policy::apply(item1, item2, m_strategy), m_oit);
}
private:
OutputIterator& m_oit;
+ Strategy const& m_strategy;
};
// structs for partition -- end
@@ -189,12 +194,13 @@ private:
Linear const& m_linear;
};
- template <typename OutputIterator>
+ template <typename OutputIterator, typename Strategy>
static inline OutputIterator get_common_points(MultiPoint const& multipoint,
Linear const& linear,
- OutputIterator oit)
+ OutputIterator oit,
+ Strategy const& strategy)
{
- item_visitor_type<OutputIterator> item_visitor(oit);
+ item_visitor_type<OutputIterator, Strategy> item_visitor(oit, strategy);
segment_range rng(linear);
@@ -203,10 +209,9 @@ private:
geometry::model::box
<
typename boost::range_value<MultiPoint>::type
- >,
- expand_box,
- overlaps_box
- >::apply(multipoint, rng, item_visitor);
+ >
+ >::apply(multipoint, rng, item_visitor,
+ expand_box(), overlaps_box());
return oit;
}
@@ -228,7 +233,8 @@ public:
// compute the common points
get_common_points(multipoint, linear,
- std::back_inserter(common_points));
+ std::back_inserter(common_points),
+ strategy);
return multipoint_multipoint_point
<
diff --git a/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp b/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp
index aedf22e1fb..8540ef98a0 100644
--- a/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp
+++ b/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp
@@ -2,6 +2,11 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// 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)
@@ -61,20 +66,25 @@ template
typename Geometry,
typename Turns,
typename TurnPolicy,
+ typename IntersectionStrategy,
typename RobustPolicy,
typename InterruptPolicy
>
struct self_section_visitor
{
Geometry const& m_geometry;
+ IntersectionStrategy const& m_intersection_strategy;
RobustPolicy const& m_rescale_policy;
Turns& m_turns;
InterruptPolicy& m_interrupt_policy;
inline self_section_visitor(Geometry const& g,
- RobustPolicy const& rp,
- Turns& turns, InterruptPolicy& ip)
+ IntersectionStrategy const& is,
+ RobustPolicy const& rp,
+ Turns& turns,
+ InterruptPolicy& ip)
: m_geometry(g)
+ , m_intersection_strategy(is)
, m_rescale_policy(rp)
, m_turns(turns)
, m_interrupt_policy(ip)
@@ -97,6 +107,7 @@ struct self_section_visitor
0, m_geometry, sec1,
0, m_geometry, sec2,
false,
+ m_intersection_strategy,
m_rescale_policy,
m_turns, m_interrupt_policy);
}
@@ -116,9 +127,10 @@ struct self_section_visitor
template<typename TurnPolicy>
struct get_turns
{
- template <typename Geometry, typename RobustPolicy, typename Turns, typename InterruptPolicy>
+ template <typename Geometry, typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline bool apply(
Geometry const& geometry,
+ IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
Turns& turns,
InterruptPolicy& interrupt_policy)
@@ -142,17 +154,17 @@ struct get_turns
self_section_visitor
<
Geometry,
- Turns, TurnPolicy, RobustPolicy, InterruptPolicy
- > visitor(geometry, robust_policy, turns, interrupt_policy);
+ Turns, TurnPolicy, IntersectionStrategy, RobustPolicy, InterruptPolicy
+ > visitor(geometry, intersection_strategy, robust_policy, turns, interrupt_policy);
try
{
geometry::partition
<
- box_type,
- detail::section::get_section_box,
- detail::section::overlaps_section_box
- >::apply(sec, visitor);
+ box_type
+ >::apply(sec, visitor,
+ detail::section::get_section_box(),
+ detail::section::overlaps_section_box());
}
catch(self_ip_exception const& )
{
@@ -208,9 +220,10 @@ struct self_get_turn_points
TurnPolicy
>
{
- template <typename RobustPolicy, typename Turns, typename InterruptPolicy>
+ template <typename Strategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline bool apply(
Box const& ,
+ Strategy const& ,
RobustPolicy const& ,
Turns& ,
InterruptPolicy& )
@@ -259,6 +272,7 @@ struct self_get_turn_points
\tparam Turns type of intersection container
(e.g. vector of "intersection/turn point"'s)
\param geometry geometry
+ \param strategy strategy to be used
\param robust_policy policy to handle robustness issues
\param turns container which will contain intersection points
\param interrupt_policy policy determining if process is stopped
@@ -268,13 +282,15 @@ template
<
typename AssignPolicy,
typename Geometry,
+ typename IntersectionStrategy,
typename RobustPolicy,
typename Turns,
typename InterruptPolicy
>
inline void self_turns(Geometry const& geometry,
- RobustPolicy const& robust_policy,
- Turns& turns, InterruptPolicy& interrupt_policy)
+ IntersectionStrategy const& strategy,
+ RobustPolicy const& robust_policy,
+ Turns& turns, InterruptPolicy& interrupt_policy)
{
concepts::check<Geometry const>();
@@ -285,7 +301,7 @@ inline void self_turns(Geometry const& geometry,
typename tag<Geometry>::type,
Geometry,
turn_policy
- >::apply(geometry, robust_policy, turns, interrupt_policy);
+ >::apply(geometry, strategy, robust_policy, turns, interrupt_policy);
}
diff --git a/boost/geometry/algorithms/detail/overlay/traversal.hpp b/boost/geometry/algorithms/detail/overlay/traversal.hpp
index 5adc0fcf69..bc828920e9 100644
--- a/boost/geometry/algorithms/detail/overlay/traversal.hpp
+++ b/boost/geometry/algorithms/detail/overlay/traversal.hpp
@@ -140,10 +140,10 @@ struct traversal
{
for (int i = 0; i < 2; i++)
{
- turn_operation_type& op = turn.operations[i];
- if (op.visited.none())
+ turn_operation_type& turn_op = turn.operations[i];
+ if (turn_op.visited.none())
{
- op.visited.set_visited();
+ turn_op.visited.set_visited();
}
}
}
diff --git a/boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp b/boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp
index e0dfee19a8..9ab82a77c1 100644
--- a/boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp
+++ b/boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp
@@ -2,6 +2,10 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// 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)
@@ -38,6 +42,7 @@ template
typename Geometry2,
typename Turns,
typename Clusters,
+ typename IntersectionStrategy,
typename RobustPolicy,
typename Visitor,
typename Backtrack
@@ -56,12 +61,14 @@ struct traversal_ring_creator
inline traversal_ring_creator(Geometry1 const& geometry1, Geometry2 const& geometry2,
Turns& turns, Clusters const& clusters,
+ IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy, Visitor& visitor)
: m_trav(geometry1, geometry2, turns, clusters, robust_policy,visitor)
, m_geometry1(geometry1)
, m_geometry2(geometry2)
, m_turns(turns)
, m_clusters(clusters)
+ , m_intersection_strategy(intersection_strategy)
, m_robust_policy(robust_policy)
, m_visitor(visitor)
{
@@ -280,7 +287,8 @@ struct traversal_ring_creator
rings, ring, m_turns, start_turn,
m_turns[turn_index].operations[op_index],
traverse_error,
- m_geometry1, m_geometry2, m_robust_policy,
+ m_geometry1, m_geometry2,
+ m_intersection_strategy, m_robust_policy,
state, m_visitor);
}
}
@@ -314,6 +322,7 @@ private:
Geometry2 const& m_geometry2;
Turns& m_turns;
Clusters const& m_clusters;
+ IntersectionStrategy const& m_intersection_strategy;
RobustPolicy const& m_robust_policy;
Visitor& m_visitor;
};
diff --git a/boost/geometry/algorithms/detail/overlay/traverse.hpp b/boost/geometry/algorithms/detail/overlay/traverse.hpp
index f01e50eb03..058f6c9458 100644
--- a/boost/geometry/algorithms/detail/overlay/traverse.hpp
+++ b/boost/geometry/algorithms/detail/overlay/traverse.hpp
@@ -58,6 +58,7 @@ class traverse
public :
template
<
+ typename IntersectionStrategy,
typename RobustPolicy,
typename Turns,
typename Rings,
@@ -66,6 +67,7 @@ public :
>
static inline void apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
+ IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
Turns& turns, Rings& rings,
Clusters& clusters,
@@ -88,10 +90,11 @@ public :
Reverse1, Reverse2, OverlayType,
Geometry1, Geometry2,
Turns, Clusters,
+ IntersectionStrategy,
RobustPolicy, Visitor,
Backtrack
> trav(geometry1, geometry2, turns, clusters,
- robust_policy, visitor);
+ intersection_strategy, robust_policy, visitor);
std::size_t finalized_ring_size = boost::size(rings);
diff --git a/boost/geometry/algorithms/detail/partition.hpp b/boost/geometry/algorithms/detail/partition.hpp
index 8b19add479..12c6a54661 100644
--- a/boost/geometry/algorithms/detail/partition.hpp
+++ b/boost/geometry/algorithms/detail/partition.hpp
@@ -2,10 +2,11 @@
// Copyright (c) 2011-2015 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2017.
+// Modifications copyright (c) 2015-2017 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
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -47,13 +48,14 @@ inline void divide_box(Box const& box, Box& lower_box, Box& upper_box)
// Divide forward_range into three subsets: lower, upper and oversized
// (not-fitting)
// (lower == left or bottom, upper == right or top)
-template <typename OverlapsPolicy, typename Box, typename IteratorVector>
+template <typename Box, typename IteratorVector, typename OverlapsPolicy>
inline void divide_into_subsets(Box const& lower_box,
- Box const& upper_box,
- IteratorVector const& input,
- IteratorVector& lower,
- IteratorVector& upper,
- IteratorVector& exceeding)
+ Box const& upper_box,
+ IteratorVector const& input,
+ IteratorVector& lower,
+ IteratorVector& upper,
+ IteratorVector& exceeding,
+ OverlapsPolicy const& overlaps_policy)
{
typedef typename boost::range_iterator
<
@@ -62,8 +64,8 @@ inline void divide_into_subsets(Box const& lower_box,
for(it_type it = boost::begin(input); it != boost::end(input); ++it)
{
- bool const lower_overlapping = OverlapsPolicy::apply(lower_box, **it);
- bool const upper_overlapping = OverlapsPolicy::apply(upper_box, **it);
+ bool const lower_overlapping = overlaps_policy.apply(lower_box, **it);
+ bool const upper_overlapping = overlaps_policy.apply(upper_box, **it);
if (lower_overlapping && upper_overlapping)
{
@@ -87,23 +89,24 @@ inline void divide_into_subsets(Box const& lower_box,
template
<
- typename ExpandPolicy,
typename Box,
- typename IteratorVector
+ typename IteratorVector,
+ typename ExpandPolicy
>
-inline void expand_with_elements(Box& total, IteratorVector const& input)
+inline void expand_with_elements(Box& total, IteratorVector const& input,
+ ExpandPolicy const& expand_policy)
{
typedef typename boost::range_iterator<IteratorVector const>::type it_type;
for(it_type it = boost::begin(input); it != boost::end(input); ++it)
{
- ExpandPolicy::apply(total, **it);
+ expand_policy.apply(total, **it);
}
}
// Match forward_range with itself
-template <typename Policy, typename IteratorVector>
-inline void handle_one(IteratorVector const& input, Policy& policy)
+template <typename IteratorVector, typename VisitPolicy>
+inline void handle_one(IteratorVector const& input, VisitPolicy& visitor)
{
if (boost::size(input) == 0)
{
@@ -118,7 +121,7 @@ inline void handle_one(IteratorVector const& input, Policy& policy)
it_type it2 = it1;
for (++it2; it2 != boost::end(input); ++it2)
{
- policy.apply(**it1, **it2);
+ visitor.apply(**it1, **it2);
}
}
}
@@ -126,13 +129,13 @@ inline void handle_one(IteratorVector const& input, Policy& policy)
// Match forward range 1 with forward range 2
template
<
- typename Policy,
typename IteratorVector1,
- typename IteratorVector2
+ typename IteratorVector2,
+ typename VisitPolicy
>
inline void handle_two(IteratorVector1 const& input1,
- IteratorVector2 const& input2,
- Policy& policy)
+ IteratorVector2 const& input2,
+ VisitPolicy& visitor)
{
typedef typename boost::range_iterator
<
@@ -157,14 +160,14 @@ inline void handle_two(IteratorVector1 const& input1,
it2 != boost::end(input2);
++it2)
{
- policy.apply(**it1, **it2);
+ visitor.apply(**it1, **it2);
}
}
}
template <typename IteratorVector>
inline bool recurse_ok(IteratorVector const& input,
- std::size_t min_elements, std::size_t level)
+ std::size_t min_elements, std::size_t level)
{
return boost::size(input) >= min_elements
&& level < 100;
@@ -172,8 +175,8 @@ inline bool recurse_ok(IteratorVector const& input,
template <typename IteratorVector1, typename IteratorVector2>
inline bool recurse_ok(IteratorVector1 const& input1,
- IteratorVector2 const& input2,
- std::size_t min_elements, std::size_t level)
+ IteratorVector2 const& input2,
+ std::size_t min_elements, std::size_t level)
{
return boost::size(input1) >= min_elements
&& recurse_ok(input2, min_elements, level);
@@ -186,103 +189,114 @@ template
typename IteratorVector3
>
inline bool recurse_ok(IteratorVector1 const& input1,
- IteratorVector2 const& input2,
- IteratorVector3 const& input3,
- std::size_t min_elements, std::size_t level)
+ IteratorVector2 const& input2,
+ IteratorVector3 const& input3,
+ std::size_t min_elements, std::size_t level)
{
return boost::size(input1) >= min_elements
&& recurse_ok(input2, input3, min_elements, level);
}
-template
-<
- int Dimension,
- typename Box,
- typename OverlapsPolicy1,
- typename OverlapsPolicy2,
- typename ExpandPolicy1,
- typename ExpandPolicy2,
- typename VisitBoxPolicy
->
+
+template <int Dimension, typename Box>
class partition_two_ranges;
-template
-<
- int Dimension,
- typename Box,
- typename OverlapsPolicy,
- typename ExpandPolicy,
- typename VisitBoxPolicy
->
+template <int Dimension, typename Box>
class partition_one_range
{
- template <typename IteratorVector>
- static inline Box get_new_box(IteratorVector const& input)
+ template <typename IteratorVector, typename ExpandPolicy>
+ static inline Box get_new_box(IteratorVector const& input,
+ ExpandPolicy const& expand_policy)
{
Box box;
geometry::assign_inverse(box);
- expand_with_elements<ExpandPolicy>(box, input);
+ expand_with_elements(box, input, expand_policy);
return box;
}
- template <typename Policy, typename IteratorVector>
+ template
+ <
+ typename IteratorVector,
+ typename VisitPolicy,
+ typename ExpandPolicy,
+ typename OverlapsPolicy,
+ typename VisitBoxPolicy
+ >
static inline void next_level(Box const& box,
- IteratorVector const& input,
- std::size_t level, std::size_t min_elements,
- Policy& policy, VisitBoxPolicy& box_policy)
+ IteratorVector const& input,
+ std::size_t level, std::size_t min_elements,
+ VisitPolicy& visitor,
+ ExpandPolicy const& expand_policy,
+ OverlapsPolicy const& overlaps_policy,
+ VisitBoxPolicy& box_policy)
{
if (recurse_ok(input, min_elements, level))
{
partition_one_range
- <
- 1 - Dimension,
- Box,
- OverlapsPolicy,
- ExpandPolicy,
- VisitBoxPolicy
- >::apply(box, input, level + 1, min_elements, policy, box_policy);
+ <
+ 1 - Dimension,
+ Box
+ >::apply(box, input, level + 1, min_elements,
+ visitor, expand_policy, overlaps_policy, box_policy);
}
else
{
- handle_one(input, policy);
+ handle_one(input, visitor);
}
}
// Function to switch to two forward ranges if there are
// geometries exceeding the separation line
- template <typename Policy, typename IteratorVector>
+ template
+ <
+ typename IteratorVector,
+ typename VisitPolicy,
+ typename ExpandPolicy,
+ typename OverlapsPolicy,
+ typename VisitBoxPolicy
+ >
static inline void next_level2(Box const& box,
IteratorVector const& input1,
IteratorVector const& input2,
std::size_t level, std::size_t min_elements,
- Policy& policy, VisitBoxPolicy& box_policy)
+ VisitPolicy& visitor,
+ ExpandPolicy const& expand_policy,
+ OverlapsPolicy const& overlaps_policy,
+ VisitBoxPolicy& box_policy)
{
if (recurse_ok(input1, input2, min_elements, level))
{
partition_two_ranges
- <
- 1 - Dimension,
- Box,
- OverlapsPolicy, OverlapsPolicy,
- ExpandPolicy, ExpandPolicy,
- VisitBoxPolicy
- >::apply(box, input1, input2, level + 1, min_elements,
- policy, box_policy);
+ <
+ 1 - Dimension, Box
+ >::apply(box, input1, input2, level + 1, min_elements,
+ visitor, expand_policy, overlaps_policy,
+ expand_policy, overlaps_policy, box_policy);
}
else
{
- handle_two(input1, input2, policy);
+ handle_two(input1, input2, visitor);
}
}
public :
- template <typename Policy, typename IteratorVector>
+ template
+ <
+ typename IteratorVector,
+ typename VisitPolicy,
+ typename ExpandPolicy,
+ typename OverlapsPolicy,
+ typename VisitBoxPolicy
+ >
static inline void apply(Box const& box,
- IteratorVector const& input,
- std::size_t level,
- std::size_t min_elements,
- Policy& policy, VisitBoxPolicy& box_policy)
+ IteratorVector const& input,
+ std::size_t level,
+ std::size_t min_elements,
+ VisitPolicy& visitor,
+ ExpandPolicy const& expand_policy,
+ OverlapsPolicy const& overlaps_policy,
+ VisitBoxPolicy& box_policy)
{
box_policy.apply(box, level);
@@ -290,101 +304,121 @@ public :
divide_box<Dimension>(box, lower_box, upper_box);
IteratorVector lower, upper, exceeding;
- divide_into_subsets<OverlapsPolicy>(lower_box, upper_box,
- input, lower, upper, exceeding);
+ divide_into_subsets(lower_box, upper_box,
+ input, lower, upper, exceeding,
+ overlaps_policy);
if (boost::size(exceeding) > 0)
{
// Get the box of exceeding-only
- Box exceeding_box = get_new_box(exceeding);
+ Box exceeding_box = get_new_box(exceeding, expand_policy);
// Recursively do exceeding elements only, in next dimension they
// will probably be less exceeding within the new box
next_level(exceeding_box, exceeding, level, min_elements,
- policy, box_policy);
+ visitor, expand_policy, overlaps_policy, box_policy);
// Switch to two forward ranges, combine exceeding with
// lower resp upper, but not lower/lower, upper/upper
next_level2(exceeding_box, exceeding, lower, level, min_elements,
- policy, box_policy);
+ visitor, expand_policy, overlaps_policy, box_policy);
next_level2(exceeding_box, exceeding, upper, level, min_elements,
- policy, box_policy);
+ visitor, expand_policy, overlaps_policy, box_policy);
}
// Recursively call operation both parts
- next_level(lower_box, lower, level, min_elements, policy, box_policy);
- next_level(upper_box, upper, level, min_elements, policy, box_policy);
+ next_level(lower_box, lower, level, min_elements,
+ visitor, expand_policy, overlaps_policy, box_policy);
+ next_level(upper_box, upper, level, min_elements,
+ visitor, expand_policy, overlaps_policy, box_policy);
}
};
template
<
int Dimension,
- typename Box,
- typename OverlapsPolicy1,
- typename OverlapsPolicy2,
- typename ExpandPolicy1,
- typename ExpandPolicy2,
- typename VisitBoxPolicy
+ typename Box
>
class partition_two_ranges
{
template
<
- typename Policy,
typename IteratorVector1,
- typename IteratorVector2
+ typename IteratorVector2,
+ typename VisitPolicy,
+ typename ExpandPolicy1,
+ typename OverlapsPolicy1,
+ typename ExpandPolicy2,
+ typename OverlapsPolicy2,
+ typename VisitBoxPolicy
>
static inline void next_level(Box const& box,
IteratorVector1 const& input1,
IteratorVector2 const& input2,
std::size_t level, std::size_t min_elements,
- Policy& policy, VisitBoxPolicy& box_policy)
+ VisitPolicy& visitor,
+ ExpandPolicy1 const& expand_policy1,
+ OverlapsPolicy1 const& overlaps_policy1,
+ ExpandPolicy2 const& expand_policy2,
+ OverlapsPolicy2 const& overlaps_policy2,
+ VisitBoxPolicy& box_policy)
{
partition_two_ranges
<
- 1 - Dimension,
- Box,
- OverlapsPolicy1,
- OverlapsPolicy2,
- ExpandPolicy1,
- ExpandPolicy2,
- VisitBoxPolicy
+ 1 - Dimension, Box
>::apply(box, input1, input2, level + 1, min_elements,
- policy, box_policy);
+ visitor, expand_policy1, overlaps_policy1,
+ expand_policy2, overlaps_policy2, box_policy);
}
- template <typename ExpandPolicy, typename IteratorVector>
- static inline Box get_new_box(IteratorVector const& input)
+ template <typename IteratorVector, typename ExpandPolicy>
+ static inline Box get_new_box(IteratorVector const& input,
+ ExpandPolicy const& expand_policy)
{
Box box;
geometry::assign_inverse(box);
- expand_with_elements<ExpandPolicy>(box, input);
+ expand_with_elements(box, input, expand_policy);
return box;
}
- template <typename IteratorVector1, typename IteratorVector2>
+ template
+ <
+ typename IteratorVector1, typename IteratorVector2,
+ typename ExpandPolicy1, typename ExpandPolicy2
+ >
static inline Box get_new_box(IteratorVector1 const& input1,
- IteratorVector2 const& input2)
+ IteratorVector2 const& input2,
+ ExpandPolicy1 const& expand_policy1,
+ ExpandPolicy2 const& expand_policy2)
{
- Box box = get_new_box<ExpandPolicy1>(input1);
- expand_with_elements<ExpandPolicy2>(box, input2);
+ Box box = get_new_box(input1, expand_policy1);
+ expand_with_elements(box, input2, expand_policy2);
return box;
}
public :
template
<
- typename Policy,
typename IteratorVector1,
- typename IteratorVector2
+ typename IteratorVector2,
+ typename VisitPolicy,
+ typename ExpandPolicy1,
+ typename OverlapsPolicy1,
+ typename ExpandPolicy2,
+ typename OverlapsPolicy2,
+ typename VisitBoxPolicy
>
static inline void apply(Box const& box,
IteratorVector1 const& input1,
IteratorVector2 const& input2,
std::size_t level,
std::size_t min_elements,
- Policy& policy, VisitBoxPolicy& box_policy)
+ VisitPolicy& visitor,
+ ExpandPolicy1 const& expand_policy1,
+ OverlapsPolicy1 const& overlaps_policy1,
+ ExpandPolicy2 const& expand_policy2,
+ OverlapsPolicy2 const& overlaps_policy2,
+ VisitBoxPolicy& box_policy)
{
box_policy.apply(box, level);
@@ -393,10 +427,12 @@ public :
IteratorVector1 lower1, upper1, exceeding1;
IteratorVector2 lower2, upper2, exceeding2;
- divide_into_subsets<OverlapsPolicy1>(lower_box, upper_box,
- input1, lower1, upper1, exceeding1);
- divide_into_subsets<OverlapsPolicy2>(lower_box, upper_box,
- input2, lower2, upper2, exceeding2);
+ divide_into_subsets(lower_box, upper_box,
+ input1, lower1, upper1, exceeding1,
+ overlaps_policy1);
+ divide_into_subsets(lower_box, upper_box,
+ input2, lower2, upper2, exceeding2,
+ overlaps_policy2);
if (boost::size(exceeding1) > 0)
{
@@ -404,13 +440,15 @@ public :
if (recurse_ok(exceeding1, exceeding2, min_elements, level))
{
- Box exceeding_box = get_new_box(exceeding1, exceeding2);
+ Box exceeding_box = get_new_box(exceeding1, exceeding2,
+ expand_policy1, expand_policy2);
next_level(exceeding_box, exceeding1, exceeding2, level,
- min_elements, policy, box_policy);
+ min_elements, visitor, expand_policy1, overlaps_policy1,
+ expand_policy2, overlaps_policy2, box_policy);
}
else
{
- handle_two(exceeding1, exceeding2, policy);
+ handle_two(exceeding1, exceeding2, visitor);
}
// All exceeding from 1 with lower and upper of 2:
@@ -419,16 +457,18 @@ public :
// the same combinations again and again)
if (recurse_ok(lower2, upper2, exceeding1, min_elements, level))
{
- Box exceeding_box = get_new_box<ExpandPolicy1>(exceeding1);
+ Box exceeding_box = get_new_box(exceeding1, expand_policy1);
next_level(exceeding_box, exceeding1, lower2, level,
- min_elements, policy, box_policy);
+ min_elements, visitor, expand_policy1, overlaps_policy1,
+ expand_policy2, overlaps_policy2, box_policy);
next_level(exceeding_box, exceeding1, upper2, level,
- min_elements, policy, box_policy);
+ min_elements, visitor, expand_policy1, overlaps_policy1,
+ expand_policy2, overlaps_policy2, box_policy);
}
else
{
- handle_two(exceeding1, lower2, policy);
- handle_two(exceeding1, upper2, policy);
+ handle_two(exceeding1, lower2, visitor);
+ handle_two(exceeding1, upper2, visitor);
}
}
@@ -437,36 +477,40 @@ public :
// All exceeding from 2 with lower and upper of 1:
if (recurse_ok(lower1, upper1, exceeding2, min_elements, level))
{
- Box exceeding_box = get_new_box<ExpandPolicy2>(exceeding2);
+ Box exceeding_box = get_new_box(exceeding2, expand_policy2);
next_level(exceeding_box, lower1, exceeding2, level,
- min_elements, policy, box_policy);
+ min_elements, visitor, expand_policy1, overlaps_policy1,
+ expand_policy2, overlaps_policy2, box_policy);
next_level(exceeding_box, upper1, exceeding2, level,
- min_elements, policy, box_policy);
+ min_elements, visitor, expand_policy1, overlaps_policy1,
+ expand_policy2, overlaps_policy2, box_policy);
}
else
{
- handle_two(lower1, exceeding2, policy);
- handle_two(upper1, exceeding2, policy);
+ handle_two(lower1, exceeding2, visitor);
+ handle_two(upper1, exceeding2, visitor);
}
}
if (recurse_ok(lower1, lower2, min_elements, level))
{
next_level(lower_box, lower1, lower2, level,
- min_elements, policy, box_policy);
+ min_elements, visitor, expand_policy1, overlaps_policy1,
+ expand_policy2, overlaps_policy2, box_policy);
}
else
{
- handle_two(lower1, lower2, policy);
+ handle_two(lower1, lower2, visitor);
}
if (recurse_ok(upper1, upper2, min_elements, level))
{
next_level(upper_box, upper1, upper2, level,
- min_elements, policy, box_policy);
+ min_elements, visitor, expand_policy1, overlaps_policy1,
+ expand_policy2, overlaps_policy2, box_policy);
}
else
{
- handle_two(upper1, upper2, policy);
+ handle_two(upper1, upper2, visitor);
}
}
};
@@ -493,46 +537,86 @@ struct include_all_policy
template
<
typename Box,
- typename ExpandPolicy1,
- typename OverlapsPolicy1,
- typename ExpandPolicy2 = ExpandPolicy1,
- typename OverlapsPolicy2 = OverlapsPolicy1,
typename IncludePolicy1 = detail::partition::include_all_policy,
- typename IncludePolicy2 = detail::partition::include_all_policy,
- typename VisitBoxPolicy = detail::partition::visit_no_policy
+ typename IncludePolicy2 = detail::partition::include_all_policy
>
class partition
{
+ static const std::size_t default_min_elements = 16;
+
template
<
- typename ExpandPolicy,
typename IncludePolicy,
typename ForwardRange,
- typename IteratorVector
+ typename IteratorVector,
+ typename ExpandPolicy
>
static inline void expand_to_range(ForwardRange const& forward_range,
- Box& total, IteratorVector& iterator_vector)
+ Box& total,
+ IteratorVector& iterator_vector,
+ ExpandPolicy const& expand_policy)
{
- for(typename boost::range_iterator<ForwardRange const>::type it
- = boost::begin(forward_range);
+ for(typename boost::range_iterator<ForwardRange const>::type
+ it = boost::begin(forward_range);
it != boost::end(forward_range);
++it)
{
if (IncludePolicy::apply(*it))
{
- ExpandPolicy::apply(total, *it);
+ expand_policy.apply(total, *it);
iterator_vector.push_back(it);
}
}
}
-public :
- template <typename ForwardRange, typename VisitPolicy>
+public:
+ template
+ <
+ typename ForwardRange,
+ typename VisitPolicy,
+ typename ExpandPolicy,
+ typename OverlapsPolicy
+ >
static inline void apply(ForwardRange const& forward_range,
- VisitPolicy& visitor,
- std::size_t min_elements = 16,
- VisitBoxPolicy box_visitor = detail::partition::visit_no_policy()
- )
+ VisitPolicy& visitor,
+ ExpandPolicy const& expand_policy,
+ OverlapsPolicy const& overlaps_policy)
+ {
+ apply(forward_range, visitor, expand_policy, overlaps_policy,
+ default_min_elements, detail::partition::visit_no_policy());
+ }
+
+ template
+ <
+ typename ForwardRange,
+ typename VisitPolicy,
+ typename ExpandPolicy,
+ typename OverlapsPolicy
+ >
+ static inline void apply(ForwardRange const& forward_range,
+ VisitPolicy& visitor,
+ ExpandPolicy const& expand_policy,
+ OverlapsPolicy const& overlaps_policy,
+ std::size_t min_elements)
+ {
+ apply(forward_range, visitor, expand_policy, overlaps_policy,
+ min_elements, detail::partition::visit_no_policy());
+ }
+
+ template
+ <
+ typename ForwardRange,
+ typename VisitPolicy,
+ typename ExpandPolicy,
+ typename OverlapsPolicy,
+ typename VisitBoxPolicy
+ >
+ static inline void apply(ForwardRange const& forward_range,
+ VisitPolicy& visitor,
+ ExpandPolicy const& expand_policy,
+ OverlapsPolicy const& overlaps_policy,
+ std::size_t min_elements,
+ VisitBoxPolicy box_visitor)
{
typedef typename boost::range_iterator
<
@@ -544,17 +628,14 @@ public :
std::vector<iterator_type> iterator_vector;
Box total;
assign_inverse(total);
- expand_to_range<ExpandPolicy1, IncludePolicy1>(forward_range,
- total, iterator_vector);
+ expand_to_range<IncludePolicy1>(forward_range, total,
+ iterator_vector, expand_policy);
detail::partition::partition_one_range
<
- 0, Box,
- OverlapsPolicy1,
- ExpandPolicy1,
- VisitBoxPolicy
+ 0, Box
>::apply(total, iterator_vector, 0, min_elements,
- visitor, box_visitor);
+ visitor, expand_policy, overlaps_policy, box_visitor);
}
else
{
@@ -575,15 +656,88 @@ public :
<
typename ForwardRange1,
typename ForwardRange2,
- typename VisitPolicy
+ typename VisitPolicy,
+ typename ExpandPolicy1,
+ typename OverlapsPolicy1
+ >
+ static inline void apply(ForwardRange1 const& forward_range1,
+ ForwardRange2 const& forward_range2,
+ VisitPolicy& visitor,
+ ExpandPolicy1 const& expand_policy1,
+ OverlapsPolicy1 const& overlaps_policy1)
+ {
+ apply(forward_range1, forward_range2, visitor,
+ expand_policy1, overlaps_policy1, expand_policy1, overlaps_policy1,
+ default_min_elements, detail::partition::visit_no_policy());
+ }
+
+ template
+ <
+ typename ForwardRange1,
+ typename ForwardRange2,
+ typename VisitPolicy,
+ typename ExpandPolicy1,
+ typename OverlapsPolicy1,
+ typename ExpandPolicy2,
+ typename OverlapsPolicy2
+ >
+ static inline void apply(ForwardRange1 const& forward_range1,
+ ForwardRange2 const& forward_range2,
+ VisitPolicy& visitor,
+ ExpandPolicy1 const& expand_policy1,
+ OverlapsPolicy1 const& overlaps_policy1,
+ ExpandPolicy2 const& expand_policy2,
+ OverlapsPolicy2 const& overlaps_policy2)
+ {
+ apply(forward_range1, forward_range2, visitor,
+ expand_policy1, overlaps_policy1, expand_policy2, overlaps_policy2,
+ default_min_elements, detail::partition::visit_no_policy());
+ }
+
+ template
+ <
+ typename ForwardRange1,
+ typename ForwardRange2,
+ typename VisitPolicy,
+ typename ExpandPolicy1,
+ typename OverlapsPolicy1,
+ typename ExpandPolicy2,
+ typename OverlapsPolicy2
+ >
+ static inline void apply(ForwardRange1 const& forward_range1,
+ ForwardRange2 const& forward_range2,
+ VisitPolicy& visitor,
+ ExpandPolicy1 const& expand_policy1,
+ OverlapsPolicy1 const& overlaps_policy1,
+ ExpandPolicy2 const& expand_policy2,
+ OverlapsPolicy2 const& overlaps_policy2,
+ std::size_t min_elements)
+ {
+ apply(forward_range1, forward_range2, visitor,
+ expand_policy1, overlaps_policy1, expand_policy2, overlaps_policy1,
+ min_elements, detail::partition::visit_no_policy());
+ }
+
+ template
+ <
+ typename ForwardRange1,
+ typename ForwardRange2,
+ typename VisitPolicy,
+ typename ExpandPolicy1,
+ typename OverlapsPolicy1,
+ typename ExpandPolicy2,
+ typename OverlapsPolicy2,
+ typename VisitBoxPolicy
>
static inline void apply(ForwardRange1 const& forward_range1,
- ForwardRange2 const& forward_range2,
- VisitPolicy& visitor,
- std::size_t min_elements = 16,
- VisitBoxPolicy box_visitor
- = detail::partition::visit_no_policy()
- )
+ ForwardRange2 const& forward_range2,
+ VisitPolicy& visitor,
+ ExpandPolicy1 const& expand_policy1,
+ OverlapsPolicy1 const& overlaps_policy1,
+ ExpandPolicy2 const& expand_policy2,
+ OverlapsPolicy2 const& overlaps_policy2,
+ std::size_t min_elements,
+ VisitBoxPolicy box_visitor)
{
typedef typename boost::range_iterator
<
@@ -602,17 +756,18 @@ public :
std::vector<iterator_type2> iterator_vector2;
Box total;
assign_inverse(total);
- expand_to_range<ExpandPolicy1, IncludePolicy1>(forward_range1,
- total, iterator_vector1);
- expand_to_range<ExpandPolicy2, IncludePolicy2>(forward_range2,
- total, iterator_vector2);
+ expand_to_range<IncludePolicy1>(forward_range1, total,
+ iterator_vector1, expand_policy1);
+ expand_to_range<IncludePolicy2>(forward_range2, total,
+ iterator_vector2, expand_policy2);
detail::partition::partition_two_ranges
<
- 0, Box, OverlapsPolicy1, OverlapsPolicy2,
- ExpandPolicy1, ExpandPolicy2, VisitBoxPolicy
+ 0, Box
>::apply(total, iterator_vector1, iterator_vector2,
- 0, min_elements, visitor, box_visitor);
+ 0, min_elements, visitor, expand_policy1,
+ overlaps_policy1, expand_policy2, overlaps_policy2,
+ box_visitor);
}
else
{
diff --git a/boost/geometry/algorithms/detail/relate/areal_areal.hpp b/boost/geometry/algorithms/detail/relate/areal_areal.hpp
index a74954326b..800fbb2e96 100644
--- a/boost/geometry/algorithms/detail/relate/areal_areal.hpp
+++ b/boost/geometry/algorithms/detail/relate/areal_areal.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014, 2015.
-// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017.
+// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -40,12 +40,21 @@ namespace detail { namespace relate {
// Use the rtree in this case!
// may be used to set EI and EB for an Areal geometry for which no turns were generated
-template <typename OtherAreal, typename Result, bool TransposeResult>
+template
+<
+ typename OtherAreal,
+ typename Result,
+ typename PointInArealStrategy,
+ bool TransposeResult
+>
class no_turns_aa_pred
{
public:
- no_turns_aa_pred(OtherAreal const& other_areal, Result & res)
+ no_turns_aa_pred(OtherAreal const& other_areal,
+ Result & res,
+ PointInArealStrategy const& point_in_areal_strategy)
: m_result(res)
+ , m_point_in_areal_strategy(point_in_areal_strategy)
, m_other_areal(other_areal)
, m_flags(0)
{
@@ -68,6 +77,8 @@ public:
template <typename Areal>
bool operator()(Areal const& areal)
{
+ using detail::within::point_in_geometry;
+
// if those flags are set nothing will change
if ( m_flags == 3 )
{
@@ -87,7 +98,9 @@ public:
// check if the areal is inside the other_areal
// TODO: This is O(N)
// Run in a loop O(NM) - optimize!
- int const pig = detail::within::point_in_geometry(pt, m_other_areal);
+ int const pig = point_in_geometry(pt,
+ m_other_areal,
+ m_point_in_areal_strategy);
//BOOST_GEOMETRY_ASSERT( pig != 0 );
// inside
@@ -119,7 +132,9 @@ public:
// TODO: O(N)
// Optimize!
- int const hpig = detail::within::point_in_geometry(range::front(range_ref), m_other_areal);
+ int const hpig = point_in_geometry(range::front(range_ref),
+ m_other_areal,
+ m_point_in_areal_strategy);
// hole outside
if ( hpig < 0 )
@@ -155,7 +170,9 @@ public:
// TODO: O(N)
// Optimize!
- int const hpig = detail::within::point_in_geometry(range::front(range_ref), m_other_areal);
+ int const hpig = point_in_geometry(range::front(range_ref),
+ m_other_areal,
+ m_point_in_areal_strategy);
// hole inside
if ( hpig > 0 )
@@ -174,6 +191,7 @@ public:
private:
Result & m_result;
+ PointInArealStrategy const& m_point_in_areal_strategy;
OtherAreal const& m_other_areal;
int m_flags;
};
@@ -191,8 +209,10 @@ struct areal_areal
typedef typename geometry::point_type<Geometry1>::type point1_type;
typedef typename geometry::point_type<Geometry2>::type point2_type;
- template <typename Result>
- static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Result & result)
+ template <typename Result, typename IntersectionStrategy>
+ static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
+ Result & result,
+ IntersectionStrategy const& intersection_strategy)
{
// TODO: If Areal geometry may have infinite size, change the following line:
@@ -208,16 +228,31 @@ struct areal_areal
interrupt_policy_areal_areal<Result> interrupt_policy(geometry1, geometry2, result);
- turns::get_turns<Geometry1, Geometry2>::apply(turns, geometry1, geometry2, interrupt_policy);
+ turns::get_turns<Geometry1, Geometry2>::apply(turns, geometry1, geometry2, interrupt_policy, intersection_strategy);
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
- no_turns_aa_pred<Geometry2, Result, false> pred1(geometry2, result);
+ typedef typename IntersectionStrategy::template point_in_geometry_strategy
+ <
+ Geometry1, Geometry2
+ >::type point_in_areal_strategy12_type;
+ point_in_areal_strategy12_type point_in_areal_strategy12
+ = intersection_strategy.template get_point_in_geometry_strategy<Geometry1, Geometry2>();
+ typedef typename IntersectionStrategy::template point_in_geometry_strategy
+ <
+ Geometry2, Geometry1
+ >::type point_in_areal_strategy21_type;
+ point_in_areal_strategy21_type point_in_areal_strategy21
+ = intersection_strategy.template get_point_in_geometry_strategy<Geometry2, Geometry1>();
+
+ no_turns_aa_pred<Geometry2, Result, point_in_areal_strategy12_type, false>
+ pred1(geometry2, result, point_in_areal_strategy12);
for_each_disjoint_geometry_if<0, Geometry1>::apply(turns.begin(), turns.end(), geometry1, pred1);
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
- no_turns_aa_pred<Geometry1, Result, true> pred2(geometry1, result);
+ no_turns_aa_pred<Geometry1, Result, point_in_areal_strategy21_type, true>
+ pred2(geometry1, result, point_in_areal_strategy21);
for_each_disjoint_geometry_if<1, Geometry2>::apply(turns.begin(), turns.end(), geometry2, pred2);
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
@@ -256,7 +291,8 @@ struct areal_areal
{
// analyse rings for which turns were not generated
// or only i/i or u/u was generated
- uncertain_rings_analyser<0, Result, Geometry1, Geometry2> rings_analyser(result, geometry1, geometry2);
+ uncertain_rings_analyser<0, Result, Geometry1, Geometry2, point_in_areal_strategy12_type>
+ rings_analyser(result, geometry1, geometry2, point_in_areal_strategy12);
analyse_uncertain_rings<0>::apply(rings_analyser, turns.begin(), turns.end());
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
@@ -295,7 +331,8 @@ struct areal_areal
{
// analyse rings for which turns were not generated
// or only i/i or u/u was generated
- uncertain_rings_analyser<1, Result, Geometry2, Geometry1> rings_analyser(result, geometry2, geometry1);
+ uncertain_rings_analyser<1, Result, Geometry2, Geometry1, point_in_areal_strategy21_type>
+ rings_analyser(result, geometry2, geometry1, point_in_areal_strategy21);
analyse_uncertain_rings<1>::apply(rings_analyser, turns.begin(), turns.end());
//if ( result.interrupt )
@@ -565,7 +602,14 @@ struct areal_areal
analyser.apply(res);
}
- template <std::size_t OpId, typename Result, typename Geometry, typename OtherGeometry>
+ template
+ <
+ std::size_t OpId,
+ typename Result,
+ typename Geometry,
+ typename OtherGeometry,
+ typename PointInArealStrategy
+ >
class uncertain_rings_analyser
{
static const bool transpose_result = OpId != 0;
@@ -574,10 +618,13 @@ struct areal_areal
public:
inline uncertain_rings_analyser(Result & result,
Geometry const& geom,
- OtherGeometry const& other_geom)
- : geometry(geom), other_geometry(other_geom)
+ OtherGeometry const& other_geom,
+ PointInArealStrategy const& point_in_areal_strategy)
+ : geometry(geom)
+ , other_geometry(other_geom)
, interrupt(result.interrupt) // just in case, could be false as well
, m_result(result)
+ , m_point_in_areal_strategy(point_in_areal_strategy)
, m_flags(0)
{
// check which relations must be analysed
@@ -624,7 +671,10 @@ struct areal_areal
// TODO: optimize! e.g. use spatial index
// O(N) - running it in a loop gives O(NM)
- int const pig = detail::within::point_in_geometry(range::front(range_ref), other_geometry);
+ using detail::within::point_in_geometry;
+ int const pig = point_in_geometry(range::front(range_ref),
+ other_geometry,
+ m_point_in_areal_strategy);
//BOOST_GEOMETRY_ASSERT(pig != 0);
if ( pig > 0 )
@@ -713,6 +763,7 @@ struct areal_areal
private:
Result & m_result;
+ PointInArealStrategy const& m_point_in_areal_strategy;
int m_flags;
};
diff --git a/boost/geometry/algorithms/detail/relate/implementation.hpp b/boost/geometry/algorithms/detail/relate/implementation.hpp
index a6f1545ed1..3bd0f806c1 100644
--- a/boost/geometry/algorithms/detail/relate/implementation.hpp
+++ b/boost/geometry/algorithms/detail/relate/implementation.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014, 2015.
-// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017.
+// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -25,6 +25,9 @@
#include <boost/geometry/algorithms/detail/relate/linear_areal.hpp>
#include <boost/geometry/algorithms/detail/relate/areal_areal.hpp>
+#include <boost/geometry/strategies/intersection.hpp>
+#include <boost/geometry/strategies/within.hpp>
+
namespace boost { namespace geometry {
diff --git a/boost/geometry/algorithms/detail/relate/interface.hpp b/boost/geometry/algorithms/detail/relate/interface.hpp
index 95d452931c..3575fe2bc4 100644
--- a/boost/geometry/algorithms/detail/relate/interface.hpp
+++ b/boost/geometry/algorithms/detail/relate/interface.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014, 2015.
-// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017.
+// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -29,6 +29,7 @@
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
+#include <boost/geometry/strategies/relate.hpp>
namespace boost { namespace geometry {
@@ -186,18 +187,59 @@ struct result_handler_type<Geometry1, Geometry2, StaticSequence, true>
> type;
};
+
}} // namespace detail::relate
#endif // DOXYGEN_NO_DETAIL
+namespace resolve_strategy {
+
+struct relate
+{
+ template <typename Geometry1, typename Geometry2, typename ResultHandler, typename Strategy>
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ ResultHandler & handler,
+ Strategy const& strategy)
+ {
+ dispatch::relate
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, handler, strategy);
+ }
+
+ template <typename Geometry1, typename Geometry2, typename ResultHandler>
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ ResultHandler & handler,
+ default_strategy)
+ {
+ typedef typename strategy::relate::services::default_strategy
+ <
+ Geometry1,
+ Geometry2
+ >::type strategy_type;
+
+ dispatch::relate
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, handler, strategy_type());
+ }
+};
+
+} // resolve_strategy
+
namespace resolve_variant {
template <typename Geometry1, typename Geometry2>
struct relate
{
- template <typename Mask>
+ template <typename Mask, typename Strategy>
static inline bool apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
- Mask const& mask)
+ Mask const& mask,
+ Strategy const& strategy)
{
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
@@ -210,11 +252,7 @@ struct relate
Mask
>::type handler(mask);
- dispatch::relate
- <
- Geometry1,
- Geometry2
- >::apply(geometry1, geometry2, handler);
+ resolve_strategy::relate::apply(geometry1, geometry2, handler, strategy);
return handler.result();
}
@@ -223,60 +261,64 @@ struct relate
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
struct relate<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
{
- template <typename Mask>
+ template <typename Mask, typename Strategy>
struct visitor : boost::static_visitor<bool>
{
Geometry2 const& m_geometry2;
Mask const& m_mask;
+ Strategy const& m_strategy;
- visitor(Geometry2 const& geometry2, Mask const& mask)
- : m_geometry2(geometry2), m_mask(mask) {}
+ visitor(Geometry2 const& geometry2, Mask const& mask, Strategy const& strategy)
+ : m_geometry2(geometry2), m_mask(mask), m_strategy(strategy) {}
template <typename Geometry1>
bool operator()(Geometry1 const& geometry1) const
{
return relate<Geometry1, Geometry2>
- ::apply(geometry1, m_geometry2, m_mask);
+ ::apply(geometry1, m_geometry2, m_mask, m_strategy);
}
};
- template <typename Mask>
+ template <typename Mask, typename Strategy>
static inline bool
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
Geometry2 const& geometry2,
- Mask const& mask)
+ Mask const& mask,
+ Strategy const& strategy)
{
- return boost::apply_visitor(visitor<Mask>(geometry2, mask), geometry1);
+ return boost::apply_visitor(visitor<Mask, Strategy>(geometry2, mask, strategy), geometry1);
}
};
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct relate<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
- template <typename Mask>
+ template <typename Mask, typename Strategy>
struct visitor : boost::static_visitor<bool>
{
Geometry1 const& m_geometry1;
Mask const& m_mask;
+ Strategy const& m_strategy;
- visitor(Geometry1 const& geometry1, Mask const& mask)
- : m_geometry1(geometry1), m_mask(mask) {}
+ visitor(Geometry1 const& geometry1, Mask const& mask, Strategy const& strategy)
+ : m_geometry1(geometry1), m_mask(mask), m_strategy(strategy) {}
template <typename Geometry2>
bool operator()(Geometry2 const& geometry2) const
{
return relate<Geometry1, Geometry2>
- ::apply(m_geometry1, geometry2, m_mask);
+ ::apply(m_geometry1, geometry2, m_mask, m_strategy);
}
};
- template <typename Mask>
+ template <typename Mask, typename Strategy>
static inline bool
apply(Geometry1 const& geometry1,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
- Mask const& mask)
+ Mask const& mask,
+ Strategy const& strategy)
{
- return boost::apply_visitor(visitor<Mask>(geometry1, mask), geometry2);
+ return boost::apply_visitor(visitor<Mask, Strategy>(geometry1, mask, strategy), geometry2);
}
};
@@ -289,30 +331,32 @@ struct relate<
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
>
{
- template <typename Mask>
+ template <typename Mask, typename Strategy>
struct visitor : boost::static_visitor<bool>
{
Mask const& m_mask;
+ Strategy const& m_strategy;
- visitor(Mask const& mask)
- : m_mask(mask) {}
+ visitor(Mask const& mask, Strategy const& strategy)
+ : m_mask(mask), m_strategy(strategy) {}
template <typename Geometry1, typename Geometry2>
bool operator()(Geometry1 const& geometry1,
Geometry2 const& geometry2) const
{
return relate<Geometry1, Geometry2>
- ::apply(geometry1, geometry2, m_mask);
+ ::apply(geometry1, geometry2, m_mask, m_strategy);
}
};
- template <typename Mask>
+ template <typename Mask, typename Strategy>
static inline bool
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
- Mask const& mask)
+ Mask const& mask,
+ Strategy const& strategy)
{
- return boost::apply_visitor(visitor<Mask>(mask), geometry1, geometry2);
+ return boost::apply_visitor(visitor<Mask, Strategy>(mask, strategy), geometry1, geometry2);
}
};
@@ -324,6 +368,35 @@ struct relate<
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry
\tparam Mask An intersection model Mask type.
+\tparam Strategy \tparam_strategy{Relate}
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param mask An intersection model mask object.
+\param strategy \param_strategy{relate}
+\return true if the relation is compatible with the mask, false otherwise.
+
+\qbk{distinguish,with strategy}
+\qbk{[include reference/algorithms/relate.qbk]}
+ */
+template <typename Geometry1, typename Geometry2, typename Mask, typename Strategy>
+inline bool relate(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Mask const& mask,
+ Strategy const& strategy)
+{
+ return resolve_variant::relate
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, mask, strategy);
+}
+
+/*!
+\brief Checks relation between a pair of geometries defined by a mask.
+\ingroup relate
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam Mask An intersection model Mask type.
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\param mask An intersection model mask object.
@@ -340,7 +413,7 @@ inline bool relate(Geometry1 const& geometry1,
<
Geometry1,
Geometry2
- >::apply(geometry1, geometry2, mask);
+ >::apply(geometry1, geometry2, mask, default_strategy());
}
}} // namespace boost::geometry
diff --git a/boost/geometry/algorithms/detail/relate/linear_areal.hpp b/boost/geometry/algorithms/detail/relate/linear_areal.hpp
index 58ba7bd1af..f1b4fdf81a 100644
--- a/boost/geometry/algorithms/detail/relate/linear_areal.hpp
+++ b/boost/geometry/algorithms/detail/relate/linear_areal.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014, 2015.
-// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017.
+// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -46,15 +46,24 @@ namespace detail { namespace relate {
// Use the rtree in this case!
// may be used to set IE and BE for a Linear geometry for which no turns were generated
-template <typename Geometry2, typename Result, typename BoundaryChecker, bool TransposeResult>
+template
+<
+ typename Geometry2,
+ typename Result,
+ typename PointInArealStrategy,
+ typename BoundaryChecker,
+ bool TransposeResult
+>
class no_turns_la_linestring_pred
{
public:
no_turns_la_linestring_pred(Geometry2 const& geometry2,
Result & res,
+ PointInArealStrategy const& point_in_areal_strategy,
BoundaryChecker const& boundary_checker)
: m_geometry2(geometry2)
, m_result(res)
+ , m_point_in_areal_strategy(point_in_areal_strategy)
, m_boundary_checker(boundary_checker)
, m_interrupt_flags(0)
{
@@ -98,7 +107,9 @@ public:
return false;
}
- int const pig = detail::within::point_in_geometry(range::front(linestring), m_geometry2);
+ int const pig = detail::within::point_in_geometry(range::front(linestring),
+ m_geometry2,
+ m_point_in_areal_strategy);
//BOOST_GEOMETRY_ASSERT_MSG(pig != 0, "There should be no IPs");
if ( pig > 0 )
@@ -138,6 +149,7 @@ public:
private:
Geometry2 const& m_geometry2;
Result & m_result;
+ PointInArealStrategy const& m_point_in_areal_strategy;
BoundaryChecker const& m_boundary_checker;
unsigned m_interrupt_flags;
};
@@ -225,8 +237,10 @@ struct linear_areal
>
{};
- template <typename Result>
- static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Result & result)
+ template <typename Result, typename IntersectionStrategy>
+ static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
+ Result & result,
+ IntersectionStrategy const& intersection_strategy)
{
// TODO: If Areal geometry may have infinite size, change the following line:
@@ -242,7 +256,7 @@ struct linear_areal
interrupt_policy_linear_areal<Geometry2, Result> interrupt_policy(geometry2, result);
- turns::get_turns<Geometry1, Geometry2>::apply(turns, geometry1, geometry2, interrupt_policy);
+ turns::get_turns<Geometry1, Geometry2>::apply(turns, geometry1, geometry2, interrupt_policy, intersection_strategy);
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
@@ -251,9 +265,13 @@ struct linear_areal
<
Geometry2,
Result,
+ typename IntersectionStrategy::template point_in_geometry_strategy<Geometry1, Geometry2>::type,
boundary_checker<Geometry1>,
TransposeResult
- > pred1(geometry2, result, boundary_checker1);
+ > pred1(geometry2,
+ result,
+ intersection_strategy.template get_point_in_geometry_strategy<Geometry1, Geometry2>(),
+ boundary_checker1);
for_each_disjoint_geometry_if<0, Geometry1>::apply(turns.begin(), turns.end(), geometry1, pred1);
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
@@ -279,7 +297,8 @@ struct linear_areal
analyse_each_turn(result, analyser,
turns.begin(), turns.end(),
geometry1, geometry2,
- boundary_checker1);
+ boundary_checker1,
+ intersection_strategy.get_side_strategy());
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
@@ -615,11 +634,13 @@ struct linear_areal
typename TurnIt,
typename Geometry,
typename OtherGeometry,
- typename BoundaryChecker>
+ typename BoundaryChecker,
+ typename SideStrategy>
void apply(Result & res, TurnIt it,
Geometry const& geometry,
OtherGeometry const& other_geometry,
- BoundaryChecker const& boundary_checker)
+ BoundaryChecker const& boundary_checker,
+ SideStrategy const& side_strategy)
{
overlay::operation_type op = it->operations[op_id].operation;
@@ -856,7 +877,8 @@ struct linear_areal
bool const from_inside = first_point
&& calculate_from_inside(geometry,
other_geometry,
- *it);
+ *it,
+ side_strategy);
if ( from_inside )
update<interior, interior, '1', TransposeResult>(res);
@@ -956,7 +978,8 @@ struct linear_areal
bool const first_from_inside = first_point
&& calculate_from_inside(geometry,
other_geometry,
- *it);
+ *it,
+ side_strategy);
if ( first_from_inside )
{
update<interior, interior, '1', TransposeResult>(res);
@@ -1144,10 +1167,11 @@ struct linear_areal
// check if the passed turn's segment of Linear geometry arrived
// from the inside or the outside of the Areal geometry
- template <typename Turn>
+ template <typename Turn, typename SideStrategy>
static inline bool calculate_from_inside(Geometry1 const& geometry1,
Geometry2 const& geometry2,
- Turn const& turn)
+ Turn const& turn,
+ SideStrategy const& side_strategy)
{
typedef typename cs_tag<typename Turn::point_type>::type cs_tag;
@@ -1194,16 +1218,18 @@ struct linear_areal
boost::end(range2));
// Will this sequence of points be always correct?
- overlay::side_calculator<cs_tag, point1_type, point2_type> side_calc(qi_conv, new_pj, pi, qi, qj, *qk_it);
+ overlay::side_calculator<cs_tag, point1_type, point2_type, SideStrategy>
+ side_calc(qi_conv, new_pj, pi, qi, qj, *qk_it, side_strategy);
return calculate_from_inside_sides(side_calc);
}
else
{
- point1_type new_qj;
+ point2_type new_qj;
geometry::convert(turn.point, new_qj);
- overlay::side_calculator<cs_tag, point1_type, point2_type> side_calc(qi_conv, new_pj, pi, qi, new_qj, qj);
+ overlay::side_calculator<cs_tag, point1_type, point2_type, SideStrategy>
+ side_calc(qi_conv, new_pj, pi, qi, new_qj, qj, side_strategy);
return calculate_from_inside_sides(side_calc);
}
@@ -1270,13 +1296,15 @@ struct linear_areal
typename Analyser,
typename Geometry,
typename OtherGeometry,
- typename BoundaryChecker>
+ typename BoundaryChecker,
+ typename SideStrategy>
static inline void analyse_each_turn(Result & res,
Analyser & analyser,
TurnIt first, TurnIt last,
Geometry const& geometry,
OtherGeometry const& other_geometry,
- BoundaryChecker const& boundary_checker)
+ BoundaryChecker const& boundary_checker,
+ SideStrategy const& side_strategy)
{
if ( first == last )
return;
@@ -1285,7 +1313,8 @@ struct linear_areal
{
analyser.apply(res, it,
geometry, other_geometry,
- boundary_checker);
+ boundary_checker,
+ side_strategy);
if ( BOOST_GEOMETRY_CONDITION( res.interrupt ) )
return;
@@ -1420,10 +1449,12 @@ struct areal_linear
static const bool interruption_enabled = linear_areal_type::interruption_enabled;
- template <typename Result>
- static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Result & result)
+ template <typename Result, typename IntersectionStrategy>
+ static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
+ Result & result,
+ IntersectionStrategy const& intersection_strategy)
{
- linear_areal_type::apply(geometry2, geometry1, result);
+ linear_areal_type::apply(geometry2, geometry1, result, intersection_strategy);
}
};
diff --git a/boost/geometry/algorithms/detail/relate/linear_linear.hpp b/boost/geometry/algorithms/detail/relate/linear_linear.hpp
index 7a3f373e03..520f2bd775 100644
--- a/boost/geometry/algorithms/detail/relate/linear_linear.hpp
+++ b/boost/geometry/algorithms/detail/relate/linear_linear.hpp
@@ -2,15 +2,15 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014, 2015.
-// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017.
+// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// 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)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LINEAR_LINEAR_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LINEAR_LINEAR_HPP
@@ -119,8 +119,10 @@ struct linear_linear
typedef typename geometry::point_type<Geometry1>::type point1_type;
typedef typename geometry::point_type<Geometry2>::type point2_type;
- template <typename Result>
- static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Result & result)
+ template <typename Result, typename IntersectionStrategy>
+ static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
+ Result & result,
+ IntersectionStrategy const& intersection_strategy)
{
// The result should be FFFFFFFFF
relate::set<exterior, exterior, result_dimension<Geometry1>::value>(result);// FFFFFFFFd, d in [1,9] or T
@@ -138,7 +140,7 @@ struct linear_linear
Geometry1,
Geometry2,
detail::get_turns::get_turn_info_type<Geometry1, Geometry2, turns::assign_policy<true> >
- >::apply(turns, geometry1, geometry2, interrupt_policy);
+ >::apply(turns, geometry1, geometry2, interrupt_policy, intersection_strategy);
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
diff --git a/boost/geometry/algorithms/detail/relate/point_geometry.hpp b/boost/geometry/algorithms/detail/relate/point_geometry.hpp
index be08016a16..a0c6c0d49b 100644
--- a/boost/geometry/algorithms/detail/relate/point_geometry.hpp
+++ b/boost/geometry/algorithms/detail/relate/point_geometry.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014, 2015.
-// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017.
+// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -37,10 +37,10 @@ struct point_geometry
static const bool interruption_enabled = true;
- template <typename Result>
- static inline void apply(Point const& point, Geometry const& geometry, Result & result)
+ template <typename Result, typename Strategy>
+ static inline void apply(Point const& point, Geometry const& geometry, Result & result, Strategy const& strategy)
{
- int pig = detail::within::point_in_geometry(point, geometry);
+ int pig = detail::within::point_in_geometry(point, geometry, strategy);
if ( pig > 0 ) // within
{
@@ -95,10 +95,10 @@ struct geometry_point
static const bool interruption_enabled = true;
- template <typename Result>
- static inline void apply(Geometry const& geometry, Point const& point, Result & result)
+ template <typename Result, typename Strategy>
+ static inline void apply(Geometry const& geometry, Point const& point, Result & result, Strategy const& strategy)
{
- point_geometry<Point, Geometry, true>::apply(point, geometry, result);
+ point_geometry<Point, Geometry, true>::apply(point, geometry, result, strategy);
}
};
diff --git a/boost/geometry/algorithms/detail/relate/point_point.hpp b/boost/geometry/algorithms/detail/relate/point_point.hpp
index e55be08225..b41d346f0b 100644
--- a/boost/geometry/algorithms/detail/relate/point_point.hpp
+++ b/boost/geometry/algorithms/detail/relate/point_point.hpp
@@ -2,15 +2,15 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014.
-// Modifications copyright (c) 2013, 2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2017.
+// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// 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)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_POINT_POINT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_POINT_POINT_HPP
@@ -35,8 +35,10 @@ struct point_point
{
static const bool interruption_enabled = false;
- template <typename Result>
- static inline void apply(Point1 const& point1, Point2 const& point2, Result & result)
+ template <typename Result, typename Strategy>
+ static inline void apply(Point1 const& point1, Point2 const& point2,
+ Result & result,
+ Strategy const& /*strategy*/)
{
bool equal = detail::equals::equals_point_point(point1, point2);
if ( equal )
@@ -86,8 +88,10 @@ struct point_multipoint
{
static const bool interruption_enabled = false;
- template <typename Result>
- static inline void apply(Point const& point, MultiPoint const& multi_point, Result & result)
+ template <typename Result, typename Strategy>
+ static inline void apply(Point const& point, MultiPoint const& multi_point,
+ Result & result,
+ Strategy const& /*strategy*/)
{
if ( boost::empty(multi_point) )
{
@@ -122,10 +126,12 @@ struct multipoint_point
{
static const bool interruption_enabled = false;
- template <typename Result>
- static inline void apply(MultiPoint const& multi_point, Point const& point, Result & result)
+ template <typename Result, typename Strategy>
+ static inline void apply(MultiPoint const& multi_point, Point const& point,
+ Result & result,
+ Strategy const& strategy)
{
- point_multipoint<Point, MultiPoint, true>::apply(point, multi_point, result);
+ point_multipoint<Point, MultiPoint, true>::apply(point, multi_point, result, strategy);
}
};
@@ -134,8 +140,10 @@ struct multipoint_multipoint
{
static const bool interruption_enabled = true;
- template <typename Result>
- static inline void apply(MultiPoint1 const& multi_point1, MultiPoint2 const& multi_point2, Result & result)
+ template <typename Result, typename Strategy>
+ static inline void apply(MultiPoint1 const& multi_point1, MultiPoint2 const& multi_point2,
+ Result & result,
+ Strategy const& /*strategy*/)
{
{
// TODO: throw on empty input?
diff --git a/boost/geometry/algorithms/detail/relate/relate_impl.hpp b/boost/geometry/algorithms/detail/relate/relate_impl.hpp
index e8e422993d..2ec2361c03 100644
--- a/boost/geometry/algorithms/detail/relate/relate_impl.hpp
+++ b/boost/geometry/algorithms/detail/relate/relate_impl.hpp
@@ -57,7 +57,8 @@ struct relate_impl
implemented_tag
>::type
{
- static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
+ template <typename Strategy>
+ static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
{
typename detail::relate::result_handler_type
<
@@ -66,7 +67,7 @@ struct relate_impl
typename StaticMaskTrait<Geometry1, Geometry2>::type
>::type handler;
- dispatch::relate<Geometry1, Geometry2>::apply(g1, g2, handler);
+ dispatch::relate<Geometry1, Geometry2>::apply(g1, g2, handler, strategy);
return handler.result();
}
diff --git a/boost/geometry/algorithms/detail/relate/result.hpp b/boost/geometry/algorithms/detail/relate/result.hpp
index a92badf65b..07287dc625 100644
--- a/boost/geometry/algorithms/detail/relate/result.hpp
+++ b/boost/geometry/algorithms/detail/relate/result.hpp
@@ -1,6 +1,7 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2013-2016.
// Modifications copyright (c) 2013-2016 Oracle and/or its affiliates.
@@ -24,6 +25,7 @@
#include <boost/mpl/is_sequence.hpp>
#include <boost/mpl/next.hpp>
#include <boost/static_assert.hpp>
+#include <boost/throw_exception.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/type_traits/integral_constant.hpp>
@@ -266,7 +268,7 @@ private:
|| ( c >= '0' && c <= '9' );
if ( !is_valid )
{
- throw geometry::invalid_input_exception();
+ BOOST_THROW_EXCEPTION(geometry::invalid_input_exception());
}
}
diff --git a/boost/geometry/algorithms/detail/relate/turns.hpp b/boost/geometry/algorithms/detail/relate/turns.hpp
index 09d74dec3a..6fa05eaf21 100644
--- a/boost/geometry/algorithms/detail/relate/turns.hpp
+++ b/boost/geometry/algorithms/detail/relate/turns.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014, 2015.
-// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017.
+// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -75,28 +75,35 @@ struct get_turns
{
detail::get_turns::no_interrupt_policy interrupt_policy;
- apply(turns, geometry1, geometry2, interrupt_policy);
+ typename strategy::intersection::services::default_strategy
+ <
+ typename cs_tag<Geometry1>::type
+ >::type intersection_strategy;
+
+ apply(turns, geometry1, geometry2, interrupt_policy, intersection_strategy);
}
- template <typename Turns, typename InterruptPolicy>
+ template <typename Turns, typename InterruptPolicy, typename IntersectionStrategy>
static inline void apply(Turns & turns,
Geometry1 const& geometry1,
Geometry2 const& geometry2,
- InterruptPolicy & interrupt_policy)
+ InterruptPolicy & interrupt_policy,
+ IntersectionStrategy const& intersection_strategy)
{
RobustPolicy robust_policy = geometry::get_rescale_policy
<
RobustPolicy
>(geometry1, geometry2);
- apply(turns, geometry1, geometry2, interrupt_policy, robust_policy);
+ apply(turns, geometry1, geometry2, interrupt_policy, intersection_strategy, robust_policy);
}
- template <typename Turns, typename InterruptPolicy>
+ template <typename Turns, typename InterruptPolicy, typename IntersectionStrategy>
static inline void apply(Turns & turns,
Geometry1 const& geometry1,
Geometry2 const& geometry2,
InterruptPolicy & interrupt_policy,
+ IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy)
{
static const bool reverse1 = detail::overlay::do_reverse
@@ -119,7 +126,8 @@ struct get_turns
reverse2,
GetTurnPolicy
>::apply(0, geometry1, 1, geometry2,
- robust_policy, turns, interrupt_policy);
+ intersection_strategy, robust_policy,
+ turns, interrupt_policy);
}
};
diff --git a/boost/geometry/algorithms/detail/relation/interface.hpp b/boost/geometry/algorithms/detail/relation/interface.hpp
index e9a9474551..83d27ed72f 100644
--- a/boost/geometry/algorithms/detail/relation/interface.hpp
+++ b/boost/geometry/algorithms/detail/relation/interface.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014, 2015.
-// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017.
+// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -35,16 +35,16 @@ struct result_handler_type<Geometry1, Geometry2, geometry::de9im::matrix, false>
}} // namespace detail::relate
#endif // DOXYGEN_NO_DETAIL
-
namespace resolve_variant
{
template <typename Geometry1, typename Geometry2>
struct relation
{
- template <typename Matrix>
+ template <typename Matrix, typename Strategy>
static inline Matrix apply(Geometry1 const& geometry1,
- Geometry2 const& geometry2)
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
{
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
@@ -57,11 +57,7 @@ struct relation
Matrix
>::type handler;
- dispatch::relate
- <
- Geometry1,
- Geometry2
- >::apply(geometry1, geometry2, handler);
+ resolve_strategy::relate::apply(geometry1, geometry2, handler, strategy);
return handler.result();
}
@@ -70,56 +66,60 @@ struct relation
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
struct relation<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
{
- template <typename Matrix>
+ template <typename Matrix, typename Strategy>
struct visitor : boost::static_visitor<Matrix>
{
Geometry2 const& m_geometry2;
+ Strategy const& m_strategy;
- visitor(Geometry2 const& geometry2)
- : m_geometry2(geometry2) {}
+ visitor(Geometry2 const& geometry2, Strategy const& strategy)
+ : m_geometry2(geometry2), m_strategy(strategy) {}
template <typename Geometry1>
Matrix operator()(Geometry1 const& geometry1) const
{
return relation<Geometry1, Geometry2>
- ::template apply<Matrix>(geometry1, m_geometry2);
+ ::template apply<Matrix>(geometry1, m_geometry2, m_strategy);
}
};
- template <typename Matrix>
+ template <typename Matrix, typename Strategy>
static inline Matrix
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
- Geometry2 const& geometry2)
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
{
- return boost::apply_visitor(visitor<Matrix>(geometry2), geometry1);
+ return boost::apply_visitor(visitor<Matrix, Strategy>(geometry2, strategy), geometry1);
}
};
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct relation<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
- template <typename Matrix>
+ template <typename Matrix, typename Strategy>
struct visitor : boost::static_visitor<Matrix>
{
Geometry1 const& m_geometry1;
+ Strategy const& m_strategy;
- visitor(Geometry1 const& geometry1)
- : m_geometry1(geometry1) {}
+ visitor(Geometry1 const& geometry1, Strategy const& strategy)
+ : m_geometry1(geometry1), m_strategy(strategy) {}
template <typename Geometry2>
Matrix operator()(Geometry2 const& geometry2) const
{
return relation<Geometry1, Geometry2>
- ::template apply<Matrix>(m_geometry1, geometry2);
+ ::template apply<Matrix>(m_geometry1, geometry2, m_strategy);
}
};
- template <typename Matrix>
+ template <typename Matrix, typename Strategy>
static inline Matrix
apply(Geometry1 const& geometry1,
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2)
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
+ Strategy const& strategy)
{
- return boost::apply_visitor(visitor<Matrix>(geometry1), geometry2);
+ return boost::apply_visitor(visitor<Matrix, Strategy>(geometry1, strategy), geometry2);
}
};
@@ -134,24 +134,30 @@ struct relation
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
>
{
- template <typename Matrix>
+ template <typename Matrix, typename Strategy>
struct visitor : boost::static_visitor<Matrix>
{
+ Strategy const& m_strategy;
+
+ visitor(Strategy const& strategy)
+ : m_strategy(strategy) {}
+
template <typename Geometry1, typename Geometry2>
Matrix operator()(Geometry1 const& geometry1,
Geometry2 const& geometry2) const
{
return relation<Geometry1, Geometry2>
- ::template apply<Matrix>(geometry1, geometry2);
+ ::template apply<Matrix>(geometry1, geometry2, m_strategy);
}
};
- template <typename Matrix>
+ template <typename Matrix, typename Strategy>
static inline Matrix
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2)
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
+ Strategy const& strategy)
{
- return boost::apply_visitor(visitor<Matrix>(), geometry1, geometry2);
+ return boost::apply_visitor(visitor<Matrix, Strategy>(strategy), geometry1, geometry2);
}
};
@@ -163,6 +169,33 @@ struct relation
\ingroup relation
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry
+\tparam Strategy \tparam_strategy{Relation}
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param strategy \param_strategy{relation}
+\return The DE-9IM matrix expressing the relation between geometries.
+
+\qbk{distinguish,with strategy}
+\qbk{[include reference/algorithms/relation.qbk]}
+ */
+template <typename Geometry1, typename Geometry2, typename Strategy>
+inline de9im::matrix relation(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+{
+ return resolve_variant::relation
+ <
+ Geometry1,
+ Geometry2
+ >::template apply<de9im::matrix>(geometry1, geometry2, strategy);
+}
+
+
+/*!
+\brief Calculates the relation between a pair of geometries as defined in DE-9IM.
+\ingroup relation
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\return The DE-9IM matrix expressing the relation between geometries.
@@ -177,7 +210,7 @@ inline de9im::matrix relation(Geometry1 const& geometry1,
<
Geometry1,
Geometry2
- >::template apply<de9im::matrix>(geometry1, geometry2);
+ >::template apply<de9im::matrix>(geometry1, geometry2, default_strategy());
}
diff --git a/boost/geometry/algorithms/detail/throw_on_empty_input.hpp b/boost/geometry/algorithms/detail/throw_on_empty_input.hpp
index 2f82e1a8bd..3d45a46d16 100644
--- a/boost/geometry/algorithms/detail/throw_on_empty_input.hpp
+++ b/boost/geometry/algorithms/detail/throw_on_empty_input.hpp
@@ -3,6 +3,7 @@
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
@@ -16,9 +17,13 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_THROW_ON_EMPTY_INPUT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_THROW_ON_EMPTY_INPUT_HPP
+
#include <boost/geometry/core/exception.hpp>
#include <boost/geometry/algorithms/is_empty.hpp>
+#include <boost/throw_exception.hpp>
+
+
// BSG 2012-02-06: we use this currently only for distance.
// For other scalar results area,length,perimeter it is commented on purpose.
// Reason is that for distance there is no other choice. distance of two
@@ -46,7 +51,7 @@ inline void throw_on_empty_input(Geometry const& geometry)
#if ! defined(BOOST_GEOMETRY_EMPTY_INPUT_NO_THROW)
if (geometry::is_empty(geometry))
{
- throw empty_input_exception();
+ BOOST_THROW_EXCEPTION(empty_input_exception());
}
#else
boost::ignore_unused(geometry);
diff --git a/boost/geometry/algorithms/detail/within/point_in_geometry.hpp b/boost/geometry/algorithms/detail/within/point_in_geometry.hpp
index a73364c333..a24f4d21e2 100644
--- a/boost/geometry/algorithms/detail/within/point_in_geometry.hpp
+++ b/boost/geometry/algorithms/detail/within/point_in_geometry.hpp
@@ -5,8 +5,10 @@
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013, 2014, 2015.
-// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017.
+// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
+
+// 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.
@@ -15,8 +17,6 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_POINT_IN_GEOMETRY_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_POINT_IN_GEOMETRY_HPP
@@ -35,8 +35,7 @@
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/strategies/concepts/within_concept.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
-#include <boost/geometry/strategies/within.hpp>
-#include <boost/geometry/strategies/covered_by.hpp>
+#include <boost/geometry/strategies/relate.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/views/detail/normalized_view.hpp>
@@ -46,6 +45,7 @@ namespace boost { namespace geometry {
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace within {
+
// TODO: is this needed?
inline int check_result_type(int result)
{
@@ -83,50 +83,11 @@ int point_in_range(Point const& point, Range const& range, Strategy const& strat
template <typename Geometry, typename Point, typename Range>
inline int point_in_range(Point const& point, Range const& range)
{
- typedef typename point_type<Point>::type point_type1;
- typedef typename point_type<Geometry>::type point_type2;
-
- typedef typename strategy::within::services::default_strategy
+ typedef typename strategy::point_in_geometry::services::default_strategy
<
- typename tag<Point>::type,
- typename tag<Geometry>::type,
- typename tag<Point>::type,
- typename tag_cast<typename tag<Geometry>::type, areal_tag>::type,
- typename tag_cast
- <
- typename cs_tag<point_type1>::type, spherical_tag
- >::type,
- typename tag_cast
- <
- typename cs_tag<point_type2>::type, spherical_tag
- >::type,
- Point,
- Geometry
+ Point, Geometry
>::type strategy_type;
- typedef typename strategy::covered_by::services::default_strategy
- <
- typename tag<Point>::type,
- typename tag<Geometry>::type,
- typename tag<Point>::type,
- typename tag_cast<typename tag<Geometry>::type, areal_tag>::type,
- typename tag_cast
- <
- typename cs_tag<point_type1>::type, spherical_tag
- >::type,
- typename tag_cast
- <
- typename cs_tag<point_type2>::type, spherical_tag
- >::type,
- Point,
- Geometry
- >::type strategy_type2;
-
- static const bool same_strategies = boost::is_same<strategy_type, strategy_type2>::value;
- BOOST_MPL_ASSERT_MSG((same_strategies),
- DEFAULT_WITHIN_AND_COVERED_BY_STRATEGIES_NOT_COMPATIBLE,
- (strategy_type, strategy_type2));
-
return point_in_range(point, range, strategy_type());
}
@@ -414,50 +375,11 @@ inline int point_in_geometry(Point const& point, Geometry const& geometry, Strat
template <typename Point, typename Geometry>
inline int point_in_geometry(Point const& point, Geometry const& geometry)
{
- typedef typename point_type<Point>::type point_type1;
- typedef typename point_type<Geometry>::type point_type2;
-
- typedef typename strategy::within::services::default_strategy
+ typedef typename strategy::point_in_geometry::services::default_strategy
<
- typename tag<Point>::type,
- typename tag<Geometry>::type,
- typename tag<Point>::type,
- typename tag_cast<typename tag<Geometry>::type, areal_tag>::type,
- typename tag_cast
- <
- typename cs_tag<point_type1>::type, spherical_tag
- >::type,
- typename tag_cast
- <
- typename cs_tag<point_type2>::type, spherical_tag
- >::type,
- Point,
- Geometry
+ Point, Geometry
>::type strategy_type;
- typedef typename strategy::covered_by::services::default_strategy
- <
- typename tag<Point>::type,
- typename tag<Geometry>::type,
- typename tag<Point>::type,
- typename tag_cast<typename tag<Geometry>::type, areal_tag>::type,
- typename tag_cast
- <
- typename cs_tag<point_type1>::type, spherical_tag
- >::type,
- typename tag_cast
- <
- typename cs_tag<point_type2>::type, spherical_tag
- >::type,
- Point,
- Geometry
- >::type strategy_type2;
-
- static const bool same_strategies = boost::is_same<strategy_type, strategy_type2>::value;
- BOOST_MPL_ASSERT_MSG((same_strategies),
- DEFAULT_WITHIN_AND_COVERED_BY_STRATEGIES_NOT_COMPATIBLE,
- (strategy_type, strategy_type2));
-
return point_in_geometry(point, geometry, strategy_type());
}
diff --git a/boost/geometry/algorithms/difference.hpp b/boost/geometry/algorithms/difference.hpp
index f7ca48cbe6..c11ceca243 100644
--- a/boost/geometry/algorithms/difference.hpp
+++ b/boost/geometry/algorithms/difference.hpp
@@ -2,6 +2,11 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// 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)
@@ -9,10 +14,16 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP
-#include <algorithm>
+
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/algorithms/detail/overlay/intersection_insert.hpp>
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
+#include <boost/geometry/strategies/default_strategy.hpp>
+#include <boost/geometry/util/range.hpp>
+
namespace boost { namespace geometry
{
@@ -49,10 +60,10 @@ template
typename Strategy
>
inline OutputIterator difference_insert(Geometry1 const& geometry1,
- Geometry2 const& geometry2,
- RobustPolicy const& robust_policy,
- OutputIterator out,
- Strategy const& strategy)
+ Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
+ OutputIterator out,
+ Strategy const& strategy)
{
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
@@ -93,25 +104,18 @@ template
typename OutputIterator
>
inline OutputIterator difference_insert(Geometry1 const& geometry1,
- Geometry2 const& geometry2,
- RobustPolicy const& robust_policy,
- OutputIterator out)
+ Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
+ OutputIterator out)
{
- concepts::check<Geometry1 const>();
- concepts::check<Geometry2 const>();
- concepts::check<GeometryOut>();
-
- typedef intersection_strategies
+ typedef typename strategy::relate::services::default_strategy
<
- typename cs_tag<GeometryOut>::type,
Geometry1,
- Geometry2,
- typename geometry::point_type<GeometryOut>::type,
- RobustPolicy
- > strategy;
+ Geometry2
+ >::type strategy_type;
return difference_insert<GeometryOut>(geometry1, geometry2,
- robust_policy, out, strategy());
+ robust_policy, out, strategy_type());
}
@@ -119,6 +123,215 @@ inline OutputIterator difference_insert(Geometry1 const& geometry1,
#endif // DOXYGEN_NO_DETAIL
+namespace resolve_strategy {
+
+struct difference
+{
+ template
+ <
+ typename Geometry1,
+ typename Geometry2,
+ typename RobustPolicy,
+ typename Collection,
+ typename Strategy
+ >
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
+ Collection & output_collection,
+ Strategy const& strategy)
+ {
+ typedef typename boost::range_value<Collection>::type geometry_out;
+
+ detail::difference::difference_insert<geometry_out>(
+ geometry1, geometry2, robust_policy,
+ range::back_inserter(output_collection),
+ strategy);
+ }
+
+ template
+ <
+ typename Geometry1,
+ typename Geometry2,
+ typename RobustPolicy,
+ typename Collection
+ >
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
+ Collection & output_collection,
+ default_strategy)
+ {
+ typedef typename boost::range_value<Collection>::type geometry_out;
+
+ detail::difference::difference_insert<geometry_out>(
+ geometry1, geometry2, robust_policy,
+ range::back_inserter(output_collection));
+ }
+};
+
+} // resolve_strategy
+
+
+namespace resolve_variant
+{
+
+template <typename Geometry1, typename Geometry2>
+struct difference
+{
+ template <typename Collection, typename Strategy>
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
+ {
+ typedef typename geometry::rescale_overlay_policy_type
+ <
+ Geometry1,
+ Geometry2
+ >::type rescale_policy_type;
+
+ rescale_policy_type robust_policy
+ = geometry::get_rescale_policy<rescale_policy_type>(geometry1,
+ geometry2);
+
+ resolve_strategy::difference::apply(geometry1, geometry2,
+ robust_policy,
+ output_collection,
+ strategy);
+ }
+};
+
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
+struct difference<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
+{
+ template <typename Collection, typename Strategy>
+ struct visitor: static_visitor<>
+ {
+ Geometry2 const& m_geometry2;
+ Collection& m_output_collection;
+ Strategy const& m_strategy;
+
+ visitor(Geometry2 const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
+ : m_geometry2(geometry2)
+ , m_output_collection(output_collection)
+ , m_strategy(strategy)
+ {}
+
+ template <typename Geometry1>
+ void operator()(Geometry1 const& geometry1) const
+ {
+ difference
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, m_geometry2, m_output_collection, m_strategy);
+ }
+ };
+
+ template <typename Collection, typename Strategy>
+ static inline void
+ apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
+ Geometry2 const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
+ {
+ boost::apply_visitor(visitor<Collection, Strategy>(geometry2,
+ output_collection,
+ strategy),
+ geometry1);
+ }
+};
+
+
+template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct difference<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ template <typename Collection, typename Strategy>
+ struct visitor: static_visitor<>
+ {
+ Geometry1 const& m_geometry1;
+ Collection& m_output_collection;
+ Strategy const& m_strategy;
+
+ visitor(Geometry1 const& geometry1,
+ Collection& output_collection,
+ Strategy const& strategy)
+ : m_geometry1(geometry1)
+ , m_output_collection(output_collection)
+ , m_strategy(strategy)
+ {}
+
+ template <typename Geometry2>
+ void operator()(Geometry2 const& geometry2) const
+ {
+ difference
+ <
+ Geometry1,
+ Geometry2
+ >::apply(m_geometry1, geometry2, m_output_collection, m_strategy);
+ }
+ };
+
+ template <typename Collection, typename Strategy>
+ static inline void
+ apply(Geometry1 const& geometry1,
+ variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
+ {
+ boost::apply_visitor(visitor<Collection, Strategy>(geometry1,
+ output_collection,
+ strategy),
+ geometry2);
+ }
+};
+
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2)>
+struct difference<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
+{
+ template <typename Collection, typename Strategy>
+ struct visitor: static_visitor<>
+ {
+ Collection& m_output_collection;
+ Strategy const& m_strategy;
+
+ visitor(Collection& output_collection, Strategy const& strategy)
+ : m_output_collection(output_collection)
+ , m_strategy(strategy)
+ {}
+
+ template <typename Geometry1, typename Geometry2>
+ void operator()(Geometry1 const& geometry1,
+ Geometry2 const& geometry2) const
+ {
+ difference
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, m_output_collection, m_strategy);
+ }
+ };
+
+ template <typename Collection, typename Strategy>
+ static inline void
+ apply(variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
+ variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
+ {
+ boost::apply_visitor(visitor<Collection, Strategy>(output_collection,
+ strategy),
+ geometry1, geometry2);
+ }
+};
+
+} // namespace resolve_variant
+
/*!
\brief_calc2{difference}
@@ -127,39 +340,63 @@ inline OutputIterator difference_insert(Geometry1 const& geometry1,
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry
\tparam Collection \tparam_output_collection
+\tparam Strategy \tparam_strategy{Difference}
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\param output_collection the output collection
+\param strategy \param_strategy{difference}
+\qbk{distinguish,with strategy}
\qbk{[include reference/algorithms/difference.qbk]}
*/
template
<
typename Geometry1,
typename Geometry2,
- typename Collection
+ typename Collection,
+ typename Strategy
>
inline void difference(Geometry1 const& geometry1,
- Geometry2 const& geometry2, Collection& output_collection)
+ Geometry2 const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
{
- concepts::check<Geometry1 const>();
- concepts::check<Geometry2 const>();
-
- typedef typename boost::range_value<Collection>::type geometry_out;
- concepts::check<geometry_out>();
-
- typedef typename geometry::rescale_overlay_policy_type
+ resolve_variant::difference
<
Geometry1,
Geometry2
- >::type rescale_policy_type;
+ >::apply(geometry1, geometry2, output_collection, strategy);
+}
- rescale_policy_type robust_policy
- = geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
- detail::difference::difference_insert<geometry_out>(
- geometry1, geometry2, robust_policy,
- range::back_inserter(output_collection));
+/*!
+\brief_calc2{difference}
+\ingroup difference
+\details \details_calc2{difference, spatial set theoretic difference}.
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam Collection \tparam_output_collection
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param output_collection the output collection
+
+\qbk{[include reference/algorithms/difference.qbk]}
+*/
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename Collection
+>
+inline void difference(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Collection& output_collection)
+{
+ resolve_variant::difference
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, output_collection, default_strategy());
}
diff --git a/boost/geometry/algorithms/dispatch/disjoint.hpp b/boost/geometry/algorithms/dispatch/disjoint.hpp
index 627bcff83c..78015f1a55 100644
--- a/boost/geometry/algorithms/dispatch/disjoint.hpp
+++ b/boost/geometry/algorithms/dispatch/disjoint.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013-2014.
-// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013-2017.
+// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -60,6 +60,29 @@ struct disjoint
: not_implemented<Geometry1, Geometry2>
{};
+
+// If reversal is needed, perform it
+template
+<
+ typename Geometry1, typename Geometry2,
+ std::size_t DimensionCount,
+ typename Tag1, typename Tag2
+>
+struct disjoint<Geometry1, Geometry2, DimensionCount, Tag1, Tag2, true>
+{
+ template <typename Strategy>
+ static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
+ {
+ return disjoint
+ <
+ Geometry2, Geometry1,
+ DimensionCount,
+ Tag2, Tag1
+ >::apply(g2, g1, strategy);
+ }
+};
+
+
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
diff --git a/boost/geometry/algorithms/equals.hpp b/boost/geometry/algorithms/equals.hpp
index d04d5c7f3a..1479ea66fa 100644
--- a/boost/geometry/algorithms/equals.hpp
+++ b/boost/geometry/algorithms/equals.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2014, 2015, 2016.
-// Modifications copyright (c) 2014-2016 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2015, 2016, 2017.
+// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -26,6 +26,7 @@
#include <vector>
#include <boost/range.hpp>
+#include <boost/type_traits/is_base_of.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/static_visitor.hpp>
@@ -40,7 +41,6 @@
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
-#include <boost/geometry/algorithms/detail/not.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
// For trivial checks
@@ -70,25 +70,44 @@ template
std::size_t Dimension,
std::size_t DimensionCount
>
+struct point_point
+{
+ template <typename Point1, typename Point2, typename Strategy>
+ static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& strategy)
+ {
+ return ! detail::disjoint::point_point
+ <
+ Point1, Point2,
+ Dimension, DimensionCount
+ >::apply(point1, point2, strategy);
+ }
+};
+
+
+template
+<
+ std::size_t Dimension,
+ std::size_t DimensionCount
+>
struct box_box
{
- template <typename Box1, typename Box2>
- static inline bool apply(Box1 const& box1, Box2 const& box2)
+ template <typename Box1, typename Box2, typename Strategy>
+ static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
{
if (!geometry::math::equals(get<min_corner, Dimension>(box1), get<min_corner, Dimension>(box2))
|| !geometry::math::equals(get<max_corner, Dimension>(box1), get<max_corner, Dimension>(box2)))
{
return false;
}
- return box_box<Dimension + 1, DimensionCount>::apply(box1, box2);
+ return box_box<Dimension + 1, DimensionCount>::apply(box1, box2, strategy);
}
};
template <std::size_t DimensionCount>
struct box_box<DimensionCount, DimensionCount>
{
- template <typename Box1, typename Box2>
- static inline bool apply(Box1 const& , Box2 const& )
+ template <typename Box1, typename Box2, typename Strategy>
+ static inline bool apply(Box1 const& , Box2 const& , Strategy const& )
{
return true;
}
@@ -97,8 +116,8 @@ struct box_box<DimensionCount, DimensionCount>
struct segment_segment
{
- template <typename Segment1, typename Segment2>
- static inline bool apply(Segment1 const& segment1, Segment2 const& segment2)
+ template <typename Segment1, typename Segment2, typename Strategy>
+ static inline bool apply(Segment1 const& segment1, Segment2 const& segment2, Strategy const& )
{
return equals::equals_point_point(
indexed_point_view<Segment1 const, 0>(segment1),
@@ -119,55 +138,75 @@ struct segment_segment
struct area_check
{
- template <typename Geometry1, typename Geometry2>
- static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
+ template <typename Geometry1, typename Geometry2, typename Strategy>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
{
return geometry::math::equals(
- geometry::area(geometry1),
- geometry::area(geometry2));
+ geometry::area(geometry1,
+ strategy.template get_area_strategy<Geometry1>()),
+ geometry::area(geometry2,
+ strategy.template get_area_strategy<Geometry2>()));
}
};
struct length_check
{
- template <typename Geometry1, typename Geometry2>
- static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
+ template <typename Geometry1, typename Geometry2, typename Strategy>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
{
return geometry::math::equals(
- geometry::length(geometry1),
- geometry::length(geometry2));
+ geometry::length(geometry1,
+ strategy.template get_distance_strategy<Geometry1>()),
+ geometry::length(geometry2,
+ strategy.template get_distance_strategy<Geometry2>()));
}
};
+template <typename Geometry1, typename Geometry2, typename IntersectionStrategy>
+struct collected_vector
+{
+ typedef typename geometry::select_most_precise
+ <
+ typename select_coordinate_type
+ <
+ Geometry1, Geometry2
+ >::type,
+ double
+ >::type calculation_type;
+
+ typedef geometry::collected_vector
+ <
+ calculation_type,
+ Geometry1,
+ typename IntersectionStrategy::side_strategy_type
+ > type;
+};
+
template <typename TrivialCheck>
struct equals_by_collection
{
- template <typename Geometry1, typename Geometry2>
- static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
+ template <typename Geometry1, typename Geometry2, typename Strategy>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
{
- if (! TrivialCheck::apply(geometry1, geometry2))
+ if (! TrivialCheck::apply(geometry1, geometry2, strategy))
{
return false;
}
- typedef typename geometry::select_most_precise
- <
- typename select_coordinate_type
- <
- Geometry1, Geometry2
- >::type,
- double
- >::type calculation_type;
-
- typedef geometry::collected_vector
+ typedef typename collected_vector
<
- calculation_type,
- Geometry1
- > collected_vector;
+ Geometry1, Geometry2, Strategy
+ >::type collected_vector_type;
- std::vector<collected_vector> c1, c2;
+ std::vector<collected_vector_type> c1, c2;
geometry::collect_vectors(c1, geometry1);
geometry::collect_vectors(c2, geometry2);
@@ -195,6 +234,53 @@ struct equals_by_relate
>
{};
+// If collect_vectors which is a SideStrategy-dispatched optimization
+// is implemented in a way consistent with the Intersection/Side Strategy
+// then collect_vectors is used, otherwise relate is used.
+// NOTE: the result could be coneptually different for invalid
+// geometries in different coordinate systems because collect_vectors
+// and relate treat invalid geometries differently.
+template<typename TrivialCheck>
+struct equals_by_collection_or_relate
+{
+ template <typename Geometry1, typename Geometry2, typename Strategy>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+ {
+ typedef typename boost::is_base_of
+ <
+ nyi::not_implemented_tag,
+ typename collected_vector
+ <
+ Geometry1, Geometry2, Strategy
+ >::type
+ >::type enable_relate_type;
+
+ return apply(geometry1, geometry2, strategy, enable_relate_type());
+ }
+
+private:
+ template <typename Geometry1, typename Geometry2, typename Strategy>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy,
+ boost::false_type /*enable_relate*/)
+ {
+ return equals_by_collection<TrivialCheck>::apply(geometry1, geometry2, strategy);
+ }
+
+ template <typename Geometry1, typename Geometry2, typename Strategy>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy,
+ boost::true_type /*enable_relate*/)
+ {
+ return equals_by_relate<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
+ }
+};
+
+
}} // namespace detail::equals
#endif // DOXYGEN_NO_DETAIL
@@ -226,7 +312,8 @@ template
struct equals<Geometry1, Geometry2, Tag1, Tag2, DimensionCount, true>
: equals<Geometry2, Geometry1, Tag2, Tag1, DimensionCount, false>
{
- static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
+ template <typename Strategy>
+ static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
{
return equals
<
@@ -234,19 +321,30 @@ struct equals<Geometry1, Geometry2, Tag1, Tag2, DimensionCount, true>
Tag2, Tag1,
DimensionCount,
false
- >::apply(g2, g1);
+ >::apply(g2, g1, strategy);
}
};
template <typename P1, typename P2, std::size_t DimensionCount, bool Reverse>
struct equals<P1, P2, point_tag, point_tag, DimensionCount, Reverse>
- : geometry::detail::not_
- <
- detail::disjoint::point_point<P1, P2, 0, DimensionCount>
- >
+ : detail::equals::point_point<0, DimensionCount>
+{};
+
+template <typename MultiPoint1, typename MultiPoint2, std::size_t DimensionCount, bool Reverse>
+struct equals<MultiPoint1, MultiPoint2, multi_point_tag, multi_point_tag, DimensionCount, Reverse>
+ : detail::equals::equals_by_relate<MultiPoint1, MultiPoint2>
{};
+template <typename MultiPoint, typename Point, std::size_t DimensionCount, bool Reverse>
+struct equals<MultiPoint, Point, multi_point_tag, point_tag, DimensionCount, Reverse>
+ : detail::equals::equals_by_relate<MultiPoint, Point>
+{};
+
+template <typename MultiPoint, typename Point, std::size_t DimensionCount, bool Reverse>
+struct equals<Point, MultiPoint, point_tag, multi_point_tag, DimensionCount, Reverse>
+ : detail::equals::equals_by_relate<Point, MultiPoint>
+{};
template <typename Box1, typename Box2, std::size_t DimensionCount, bool Reverse>
struct equals<Box1, Box2, box_tag, box_tag, DimensionCount, Reverse>
@@ -256,19 +354,19 @@ struct equals<Box1, Box2, box_tag, box_tag, DimensionCount, Reverse>
template <typename Ring1, typename Ring2, bool Reverse>
struct equals<Ring1, Ring2, ring_tag, ring_tag, 2, Reverse>
- : detail::equals::equals_by_collection<detail::equals::area_check>
+ : detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
{};
template <typename Polygon1, typename Polygon2, bool Reverse>
struct equals<Polygon1, Polygon2, polygon_tag, polygon_tag, 2, Reverse>
- : detail::equals::equals_by_collection<detail::equals::area_check>
+ : detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
{};
template <typename Polygon, typename Ring, bool Reverse>
struct equals<Polygon, Ring, polygon_tag, ring_tag, 2, Reverse>
- : detail::equals::equals_by_collection<detail::equals::area_check>
+ : detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
{};
@@ -290,7 +388,6 @@ struct equals<Segment1, Segment2, segment_tag, segment_tag, DimensionCount, Reve
template <typename LineString1, typename LineString2, bool Reverse>
struct equals<LineString1, LineString2, linestring_tag, linestring_tag, 2, Reverse>
- //: detail::equals::equals_by_collection<detail::equals::length_check>
: detail::equals::equals_by_relate<LineString1, LineString2>
{};
@@ -313,7 +410,7 @@ struct equals
2,
Reverse
>
- : detail::equals::equals_by_collection<detail::equals::area_check>
+ : detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
{};
@@ -325,7 +422,7 @@ struct equals
2,
Reverse
>
- : detail::equals::equals_by_collection<detail::equals::area_check>
+ : detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
{};
template <typename MultiPolygon, typename Ring, bool Reverse>
@@ -336,7 +433,7 @@ struct equals
2,
Reverse
>
- : detail::equals::equals_by_collection<detail::equals::area_check>
+ : detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
{};
@@ -344,80 +441,129 @@ struct equals
#endif // DOXYGEN_NO_DISPATCH
+namespace resolve_strategy
+{
+
+struct equals
+{
+ template <typename Geometry1, typename Geometry2, typename Strategy>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+ {
+ return dispatch::equals
+ <
+ Geometry1, Geometry2
+ >::apply(geometry1, geometry2, strategy);
+ }
+
+ template <typename Geometry1, typename Geometry2>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ default_strategy)
+ {
+ typedef typename strategy::relate::services::default_strategy
+ <
+ Geometry1,
+ Geometry2
+ >::type strategy_type;
+
+ return dispatch::equals
+ <
+ Geometry1, Geometry2
+ >::apply(geometry1, geometry2, strategy_type());
+ }
+};
+
+} // namespace resolve_strategy
+
+
namespace resolve_variant {
template <typename Geometry1, typename Geometry2>
struct equals
{
+ template <typename Strategy>
static inline bool apply(Geometry1 const& geometry1,
- Geometry2 const& geometry2)
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
{
concepts::check_concepts_and_equal_dimensions
- <
- Geometry1 const,
- Geometry2 const
- >();
+ <
+ Geometry1 const,
+ Geometry2 const
+ >();
- return dispatch::equals<Geometry1, Geometry2>
- ::apply(geometry1, geometry2);
+ return resolve_strategy::equals
+ ::apply(geometry1, geometry2, strategy);
}
};
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
struct equals<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
{
+ template <typename Strategy>
struct visitor: static_visitor<bool>
{
Geometry2 const& m_geometry2;
+ Strategy const& m_strategy;
- visitor(Geometry2 const& geometry2)
+ visitor(Geometry2 const& geometry2, Strategy const& strategy)
: m_geometry2(geometry2)
+ , m_strategy(strategy)
{}
template <typename Geometry1>
inline bool operator()(Geometry1 const& geometry1) const
{
return equals<Geometry1, Geometry2>
- ::apply(geometry1, m_geometry2);
+ ::apply(geometry1, m_geometry2, m_strategy);
}
};
+ template <typename Strategy>
static inline bool apply(
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
- Geometry2 const& geometry2
+ Geometry2 const& geometry2,
+ Strategy const& strategy
)
{
- return boost::apply_visitor(visitor(geometry2), geometry1);
+ return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
}
};
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct equals<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
+ template <typename Strategy>
struct visitor: static_visitor<bool>
{
Geometry1 const& m_geometry1;
+ Strategy const& m_strategy;
- visitor(Geometry1 const& geometry1)
+ visitor(Geometry1 const& geometry1, Strategy const& strategy)
: m_geometry1(geometry1)
+ , m_strategy(strategy)
{}
template <typename Geometry2>
inline bool operator()(Geometry2 const& geometry2) const
{
return equals<Geometry1, Geometry2>
- ::apply(m_geometry1, geometry2);
+ ::apply(m_geometry1, geometry2, m_strategy);
}
};
+ template <typename Strategy>
static inline bool apply(
Geometry1 const& geometry1,
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
+ Strategy const& strategy
)
{
- return boost::apply_visitor(visitor(geometry1), geometry2);
+ return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
}
};
@@ -430,24 +576,33 @@ struct equals<
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
>
{
+ template <typename Strategy>
struct visitor: static_visitor<bool>
{
+ Strategy const& m_strategy;
+
+ visitor(Strategy const& strategy)
+ : m_strategy(strategy)
+ {}
+
template <typename Geometry1, typename Geometry2>
inline bool operator()(Geometry1 const& geometry1,
Geometry2 const& geometry2) const
{
return equals<Geometry1, Geometry2>
- ::apply(geometry1, geometry2);
+ ::apply(geometry1, geometry2, m_strategy);
}
};
+ template <typename Strategy>
static inline bool apply(
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
+ Strategy const& strategy
)
{
- return boost::apply_visitor(visitor(), geometry1, geometry2);
+ return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
}
};
@@ -464,18 +619,48 @@ struct equals<
\ingroup equals
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry
+\tparam Strategy \tparam_strategy{Equals}
\param geometry1 \param_geometry
\param geometry2 \param_geometry
+\param strategy \param_strategy{equals}
\return \return_check2{are spatially equal}
+\qbk{distinguish,with strategy}
\qbk{[include reference/algorithms/equals.qbk]}
+ */
+template <typename Geometry1, typename Geometry2, typename Strategy>
+inline bool equals(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+{
+ return resolve_variant::equals
+ <
+ Geometry1, Geometry2
+ >::apply(geometry1, geometry2, strategy);
+}
+
+/*!
+\brief \brief_check{are spatially equal}
+\details \details_check12{equals, is spatially equal}. Spatially equal means
+ that the same point set is included. A box can therefore be spatially equal
+ to a ring or a polygon, or a linestring can be spatially equal to a
+ multi-linestring or a segment. This only works theoretically, not all
+ combinations are implemented yet.
+\ingroup equals
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\return \return_check2{are spatially equal}
+
+\qbk{[include reference/algorithms/equals.qbk]}
*/
template <typename Geometry1, typename Geometry2>
inline bool equals(Geometry1 const& geometry1, Geometry2 const& geometry2)
{
return resolve_variant::equals<Geometry1, Geometry2>
- ::apply(geometry1, geometry2);
+ ::apply(geometry1, geometry2, default_strategy());
}
diff --git a/boost/geometry/algorithms/intersects.hpp b/boost/geometry/algorithms/intersects.hpp
index 5349db76bb..12ae169f12 100644
--- a/boost/geometry/algorithms/intersects.hpp
+++ b/boost/geometry/algorithms/intersects.hpp
@@ -4,10 +4,11 @@
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2013-2014.
-// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013-2017.
+// Modifications copyright (c) 2013-2017, 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.
@@ -29,6 +30,8 @@
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
#include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
+#include <boost/geometry/strategies/relate.hpp>
+
namespace boost { namespace geometry
{
@@ -52,6 +55,10 @@ inline bool intersects(Geometry const& geometry)
concepts::check<Geometry const>();
typedef typename geometry::point_type<Geometry>::type point_type;
+ typedef typename strategy::relate::services::default_strategy
+ <
+ Geometry, Geometry
+ >::type strategy_type;
typedef detail::no_rescale_policy rescale_policy_type;
typedef detail::overlay::turn_info
@@ -67,13 +74,14 @@ inline bool intersects(Geometry const& geometry)
detail::overlay::assign_null_policy
> turn_policy;
+ strategy_type strategy;
rescale_policy_type robust_policy;
detail::disjoint::disjoint_interrupt_policy policy;
detail::self_get_turn_points::get_turns
<
turn_policy
- >::apply(geometry, robust_policy, turns, policy);
+ >::apply(geometry, strategy, robust_policy, turns, policy);
return policy.has_intersections;
}
@@ -83,6 +91,32 @@ inline bool intersects(Geometry const& geometry)
\ingroup intersects
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry
+\tparam Strategy \tparam_strategy{Intersects}
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param strategy \param_strategy{intersects}
+\return \return_check2{intersect each other}
+
+\qbk{distinguish,with strategy}
+\qbk{[include reference/algorithms/intersects.qbk]}
+ */
+template <typename Geometry1, typename Geometry2, typename Strategy>
+inline bool intersects(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+{
+ concepts::check<Geometry1 const>();
+ concepts::check<Geometry2 const>();
+
+ return ! geometry::disjoint(geometry1, geometry2, strategy);
+}
+
+
+/*!
+\brief \brief_check2{have at least one intersection}
+\ingroup intersects
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\return \return_check2{intersect each other}
diff --git a/boost/geometry/algorithms/overlaps.hpp b/boost/geometry/algorithms/overlaps.hpp
index 32738c294c..bedf17599b 100644
--- a/boost/geometry/algorithms/overlaps.hpp
+++ b/boost/geometry/algorithms/overlaps.hpp
@@ -4,8 +4,8 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2014, 2015.
-// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2015, 2017.
+// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -113,8 +113,8 @@ struct box_box_loop<DimensionCount, DimensionCount>
struct box_box
{
- template <typename Box1, typename Box2>
- static inline bool apply(Box1 const& b1, Box2 const& b2)
+ template <typename Box1, typename Box2, typename Strategy>
+ static inline bool apply(Box1 const& b1, Box2 const& b2, Strategy const& /*strategy*/)
{
bool overlaps = true;
bool within1 = true;
@@ -137,7 +137,6 @@ struct box_box
}} // namespace detail::overlaps
#endif // DOXYGEN_NO_DETAIL
-//struct not_implemented_for_this_geometry_type : public boost::false_type {};
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
@@ -175,6 +174,35 @@ struct overlaps<Box1, Box2, box_tag, box_tag>
\ingroup overlaps
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry
+\tparam Strategy \tparam_strategy{Overlaps}
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param strategy \param_strategy{overlaps}
+\return \return_check2{overlap}
+
+\qbk{distinguish,with strategy}
+\qbk{[include reference/algorithms/overlaps.qbk]}
+*/
+template <typename Geometry1, typename Geometry2, typename Strategy>
+inline bool overlaps(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+{
+ concepts::check<Geometry1 const>();
+ concepts::check<Geometry2 const>();
+
+ return dispatch::overlaps
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, strategy);
+}
+
+/*!
+\brief \brief_check2{overlap}
+\ingroup overlaps
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\return \return_check2{overlap}
@@ -187,11 +215,17 @@ inline bool overlaps(Geometry1 const& geometry1, Geometry2 const& geometry2)
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
+ typedef typename strategy::relate::services::default_strategy
+ <
+ Geometry1,
+ Geometry2
+ >::type strategy_type;
+
return dispatch::overlaps
<
Geometry1,
Geometry2
- >::apply(geometry1, geometry2);
+ >::apply(geometry1, geometry2, strategy_type());
}
}} // namespace boost::geometry
diff --git a/boost/geometry/algorithms/sym_difference.hpp b/boost/geometry/algorithms/sym_difference.hpp
index 33f94c9321..725230cd5b 100644
--- a/boost/geometry/algorithms/sym_difference.hpp
+++ b/boost/geometry/algorithms/sym_difference.hpp
@@ -2,10 +2,11 @@
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2017.
+// Modifications copyright (c) 2015-2017 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
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -14,13 +15,21 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP
+
#include <algorithm>
#include <iterator>
#include <vector>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
+
#include <boost/geometry/algorithms/intersection.hpp>
#include <boost/geometry/algorithms/union.hpp>
#include <boost/geometry/geometries/multi_polygon.hpp>
+#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
+#include <boost/geometry/strategies/default_strategy.hpp>
+#include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry
@@ -276,14 +285,10 @@ inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
concepts::check<Geometry2 const>();
concepts::check<GeometryOut>();
- typedef intersection_strategies
+ typedef typename strategy::intersection::services::default_strategy
<
- typename cs_tag<GeometryOut>::type,
- Geometry1,
- Geometry2,
- typename geometry::point_type<GeometryOut>::type,
- RobustPolicy
- > strategy_type;
+ typename cs_tag<GeometryOut>::type
+ >::type strategy_type;
return sym_difference_insert<GeometryOut>(geometry1, geometry2, robust_policy, out, strategy_type());
}
@@ -292,6 +297,216 @@ inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
#endif // DOXYGEN_NO_DETAIL
+namespace resolve_strategy {
+
+struct sym_difference
+{
+ template
+ <
+ typename Geometry1,
+ typename Geometry2,
+ typename RobustPolicy,
+ typename Collection,
+ typename Strategy
+ >
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
+ Collection & output_collection,
+ Strategy const& strategy)
+ {
+ typedef typename boost::range_value<Collection>::type geometry_out;
+
+ detail::sym_difference::sym_difference_insert<geometry_out>(
+ geometry1, geometry2, robust_policy,
+ range::back_inserter(output_collection),
+ strategy);
+ }
+
+ template
+ <
+ typename Geometry1,
+ typename Geometry2,
+ typename RobustPolicy,
+ typename Collection
+ >
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
+ Collection & output_collection,
+ default_strategy)
+ {
+ typedef typename boost::range_value<Collection>::type geometry_out;
+
+ detail::sym_difference::sym_difference_insert<geometry_out>(
+ geometry1, geometry2, robust_policy,
+ range::back_inserter(output_collection));
+ }
+};
+
+} // resolve_strategy
+
+
+namespace resolve_variant
+{
+
+template <typename Geometry1, typename Geometry2>
+struct sym_difference
+{
+ template <typename Collection, typename Strategy>
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
+ {
+ typedef typename geometry::rescale_overlay_policy_type
+ <
+ Geometry1,
+ Geometry2
+ >::type rescale_policy_type;
+
+ rescale_policy_type robust_policy
+ = geometry::get_rescale_policy<rescale_policy_type>(geometry1,
+ geometry2);
+
+ resolve_strategy::sym_difference::apply(geometry1, geometry2,
+ robust_policy,
+ output_collection,
+ strategy);
+ }
+};
+
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
+struct sym_difference<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
+{
+ template <typename Collection, typename Strategy>
+ struct visitor: static_visitor<>
+ {
+ Geometry2 const& m_geometry2;
+ Collection& m_output_collection;
+ Strategy const& m_strategy;
+
+ visitor(Geometry2 const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
+ : m_geometry2(geometry2)
+ , m_output_collection(output_collection)
+ , m_strategy(strategy)
+ {}
+
+ template <typename Geometry1>
+ void operator()(Geometry1 const& geometry1) const
+ {
+ sym_difference
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, m_geometry2, m_output_collection, m_strategy);
+ }
+ };
+
+ template <typename Collection, typename Strategy>
+ static inline void
+ apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
+ Geometry2 const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
+ {
+ boost::apply_visitor(visitor<Collection, Strategy>(geometry2,
+ output_collection,
+ strategy),
+ geometry1);
+ }
+};
+
+
+template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct sym_difference<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ template <typename Collection, typename Strategy>
+ struct visitor: static_visitor<>
+ {
+ Geometry1 const& m_geometry1;
+ Collection& m_output_collection;
+ Strategy const& m_strategy;
+
+ visitor(Geometry1 const& geometry1,
+ Collection& output_collection,
+ Strategy const& strategy)
+ : m_geometry1(geometry1)
+ , m_output_collection(output_collection)
+ , m_strategy(strategy)
+ {}
+
+ template <typename Geometry2>
+ void operator()(Geometry2 const& geometry2) const
+ {
+ sym_difference
+ <
+ Geometry1,
+ Geometry2
+ >::apply(m_geometry1, geometry2, m_output_collection, m_strategy);
+ }
+ };
+
+ template <typename Collection, typename Strategy>
+ static inline void
+ apply(Geometry1 const& geometry1,
+ variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
+ {
+ boost::apply_visitor(visitor<Collection, Strategy>(geometry1,
+ output_collection,
+ strategy),
+ geometry2);
+ }
+};
+
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2)>
+struct sym_difference<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
+{
+ template <typename Collection, typename Strategy>
+ struct visitor: static_visitor<>
+ {
+ Collection& m_output_collection;
+ Strategy const& m_strategy;
+
+ visitor(Collection& output_collection, Strategy const& strategy)
+ : m_output_collection(output_collection)
+ , m_strategy(strategy)
+ {}
+
+ template <typename Geometry1, typename Geometry2>
+ void operator()(Geometry1 const& geometry1,
+ Geometry2 const& geometry2) const
+ {
+ sym_difference
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, m_output_collection, m_strategy);
+ }
+ };
+
+ template <typename Collection, typename Strategy>
+ static inline void
+ apply(variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
+ variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
+ {
+ boost::apply_visitor(visitor<Collection, Strategy>(output_collection,
+ strategy),
+ geometry1, geometry2);
+ }
+};
+
+} // namespace resolve_variant
+
+
/*!
\brief \brief_calc2{symmetric difference}
\ingroup sym_difference
@@ -300,39 +515,64 @@ inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
\tparam Geometry2 \tparam_geometry
\tparam Collection output collection, either a multi-geometry,
or a std::vector<Geometry> / std::deque<Geometry> etc
+\tparam Strategy \tparam_strategy{Sym_difference}
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\param output_collection the output collection
+\param strategy \param_strategy{sym_difference}
+\qbk{distinguish,with strategy}
\qbk{[include reference/algorithms/sym_difference.qbk]}
*/
template
<
typename Geometry1,
typename Geometry2,
- typename Collection
+ typename Collection,
+ typename Strategy
>
inline void sym_difference(Geometry1 const& geometry1,
- Geometry2 const& geometry2, Collection& output_collection)
+ Geometry2 const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
{
- concepts::check<Geometry1 const>();
- concepts::check<Geometry2 const>();
-
- typedef typename boost::range_value<Collection>::type geometry_out;
- concepts::check<geometry_out>();
-
- typedef typename geometry::rescale_overlay_policy_type
+ resolve_variant::sym_difference
<
Geometry1,
Geometry2
- >::type rescale_policy_type;
+ >::apply(geometry1, geometry2, output_collection, strategy);
+}
- rescale_policy_type robust_policy
- = geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
- detail::sym_difference::sym_difference_insert<geometry_out>(
- geometry1, geometry2, robust_policy,
- range::back_inserter(output_collection));
+/*!
+\brief \brief_calc2{symmetric difference}
+\ingroup sym_difference
+\details \details_calc2{symmetric difference, spatial set theoretic symmetric difference (XOR)}.
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam Collection output collection, either a multi-geometry,
+ or a std::vector<Geometry> / std::deque<Geometry> etc
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param output_collection the output collection
+
+\qbk{[include reference/algorithms/sym_difference.qbk]}
+*/
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename Collection
+>
+inline void sym_difference(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Collection& output_collection)
+{
+ resolve_variant::sym_difference
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, output_collection, default_strategy());
}
diff --git a/boost/geometry/algorithms/touches.hpp b/boost/geometry/algorithms/touches.hpp
index 6384cc2a88..49e104d258 100644
--- a/boost/geometry/algorithms/touches.hpp
+++ b/boost/geometry/algorithms/touches.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013, 2014, 2015.
-// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017.
+// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -104,8 +104,8 @@ struct box_box_loop<DimensionCount, DimensionCount>
struct box_box
{
- template <typename Box1, typename Box2>
- static inline bool apply(Box1 const& b1, Box2 const& b2)
+ template <typename Box1, typename Box2, typename Strategy>
+ static inline bool apply(Box1 const& b1, Box2 const& b2, Strategy const& /*strategy*/)
{
BOOST_STATIC_ASSERT((boost::is_same
<
@@ -205,15 +205,17 @@ struct areal_interrupt_policy
}
};
-template<typename Geometry>
+template<typename Geometry, typename PointInRingStrategy>
struct check_each_ring_for_within
{
bool has_within;
Geometry const& m_geometry;
+ PointInRingStrategy const& m_strategy;
- inline check_each_ring_for_within(Geometry const& g)
+ inline check_each_ring_for_within(Geometry const& g, PointInRingStrategy const& strategy)
: has_within(false)
, m_geometry(g)
+ , m_strategy(strategy)
{}
template <typename Range>
@@ -221,18 +223,31 @@ struct check_each_ring_for_within
{
typename geometry::point_type<Range>::type p;
geometry::point_on_border(p, range);
- if ( !has_within && geometry::within(p, m_geometry) )
+ if ( !has_within && geometry::within(p, m_geometry, m_strategy) )
{
has_within = true;
}
}
};
-template <typename FirstGeometry, typename SecondGeometry>
+template <typename FirstGeometry, typename SecondGeometry, typename IntersectionStrategy>
inline bool rings_containing(FirstGeometry const& geometry1,
- SecondGeometry const& geometry2)
+ SecondGeometry const& geometry2,
+ IntersectionStrategy const& strategy)
{
- check_each_ring_for_within<FirstGeometry> checker(geometry1);
+ // NOTE: This strategy could be defined inside IntersectionStrategy
+ typedef typename IntersectionStrategy::template point_in_geometry_strategy
+ <
+ FirstGeometry, SecondGeometry
+ >::type point_in_ring_strategy_type;
+
+ point_in_ring_strategy_type point_in_ring_strategy
+ = strategy.template get_point_in_geometry_strategy<FirstGeometry, SecondGeometry>();
+
+ check_each_ring_for_within
+ <
+ FirstGeometry, point_in_ring_strategy_type
+ > checker(geometry1, point_in_ring_strategy);
geometry::detail::for_each_range(geometry2, checker);
return checker.has_within;
}
@@ -240,8 +255,10 @@ inline bool rings_containing(FirstGeometry const& geometry1,
template <typename Geometry1, typename Geometry2>
struct areal_areal
{
- static inline
- bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
+ template <typename IntersectionStrategy>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ IntersectionStrategy const& strategy)
{
typedef detail::no_rescale_policy rescale_policy_type;
typedef typename geometry::point_type<Geometry1>::type point_type;
@@ -259,11 +276,11 @@ struct areal_areal
detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
detail::overlay::assign_null_policy
- >(geometry1, geometry2, robust_policy, turns, policy);
+ >(geometry1, geometry2, strategy, robust_policy, turns, policy);
return policy.result()
- && ! geometry::detail::touches::rings_containing(geometry1, geometry2)
- && ! geometry::detail::touches::rings_containing(geometry2, geometry1);
+ && ! geometry::detail::touches::rings_containing(geometry1, geometry2, strategy)
+ && ! geometry::detail::touches::rings_containing(geometry2, geometry1, strategy);
}
};
@@ -271,10 +288,10 @@ struct areal_areal
struct use_point_in_geometry
{
- template <typename Point, typename Geometry>
- static inline bool apply(Point const& point, Geometry const& geometry)
+ template <typename Point, typename Geometry, typename Strategy>
+ static inline bool apply(Point const& point, Geometry const& geometry, Strategy const& strategy)
{
- return detail::within::point_in_geometry(point, geometry) == 0;
+ return detail::within::point_in_geometry(point, geometry, strategy) == 0;
}
};
@@ -288,7 +305,8 @@ namespace dispatch {
template
<
- typename Geometry1, typename Geometry2,
+ typename Geometry1,
+ typename Geometry2,
typename Tag1 = typename tag<Geometry1>::type,
typename Tag2 = typename tag<Geometry2>::type,
typename CastedTag1 = typename tag_cast<Tag1, pointlike_tag, linear_tag, areal_tag>::type,
@@ -309,18 +327,30 @@ template
struct touches<Geometry1, Geometry2, Tag1, Tag2, CastedTag1, CastedTag2, true>
: touches<Geometry2, Geometry1, Tag2, Tag1, CastedTag2, CastedTag1, false>
{
- static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
+ template <typename Strategy>
+ static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
{
- return touches<Geometry2, Geometry1>::apply(g2, g1);
+ return touches<Geometry2, Geometry1>::apply(g2, g1, strategy);
}
};
// P/P
-template <typename Geometry1, typename Geometry2, typename Tag1, typename Tag2>
-struct touches<Geometry1, Geometry2, Tag1, Tag2, pointlike_tag, pointlike_tag, false>
+template <typename Geometry1, typename Geometry2, typename Tag2>
+struct touches<Geometry1, Geometry2, point_tag, Tag2, pointlike_tag, pointlike_tag, false>
{
- static inline bool apply(Geometry1 const& , Geometry2 const& )
+ template <typename Strategy>
+ static inline bool apply(Geometry1 const& , Geometry2 const& , Strategy const&)
+ {
+ return false;
+ }
+};
+
+template <typename Geometry1, typename Geometry2, typename Tag2>
+struct touches<Geometry1, Geometry2, multi_point_tag, Tag2, pointlike_tag, pointlike_tag, false>
+{
+ template <typename Strategy>
+ static inline bool apply(Geometry1 const&, Geometry2 const&, Strategy const&)
{
return false;
}
@@ -403,66 +433,115 @@ struct touches<Areal1, Areal2, ring_tag, ring_tag, areal_tag, areal_tag, false>
#endif // DOXYGEN_NO_DISPATCH
+namespace resolve_strategy
+{
+
+struct touches
+{
+ template <typename Geometry1, typename Geometry2, typename Strategy>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+ {
+ return dispatch::touches
+ <
+ Geometry1, Geometry2
+ >::apply(geometry1, geometry2, strategy);
+ }
+
+ template <typename Geometry1, typename Geometry2>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ default_strategy)
+ {
+ typedef typename strategy::relate::services::default_strategy
+ <
+ Geometry1,
+ Geometry2
+ >::type strategy_type;
+
+ return dispatch::touches
+ <
+ Geometry1, Geometry2
+ >::apply(geometry1, geometry2, strategy_type());
+ }
+};
+
+} // namespace resolve_strategy
+
+
namespace resolve_variant {
template <typename Geometry1, typename Geometry2>
struct touches
{
- static bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
+ template <typename Strategy>
+ static bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
{
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
- return dispatch::touches<Geometry1, Geometry2>
- ::apply(geometry1, geometry2);
+ return resolve_strategy::touches::apply(geometry1, geometry2, strategy);
}
};
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
struct touches<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
{
+ template <typename Strategy>
struct visitor: boost::static_visitor<bool>
{
Geometry2 const& m_geometry2;
+ Strategy const& m_strategy;
- visitor(Geometry2 const& geometry2): m_geometry2(geometry2) {}
+ visitor(Geometry2 const& geometry2, Strategy const& strategy)
+ : m_geometry2(geometry2)
+ , m_strategy(strategy)
+ {}
template <typename Geometry1>
bool operator()(Geometry1 const& geometry1) const
{
- return touches<Geometry1, Geometry2>::apply(geometry1, m_geometry2);
+ return touches<Geometry1, Geometry2>::apply(geometry1, m_geometry2, m_strategy);
}
};
- static inline bool
- apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
- Geometry2 const& geometry2)
+ template <typename Strategy>
+ static inline bool apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
{
- return boost::apply_visitor(visitor(geometry2), geometry1);
+ return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
}
};
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct touches<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
+ template <typename Strategy>
struct visitor: boost::static_visitor<bool>
{
Geometry1 const& m_geometry1;
+ Strategy const& m_strategy;
- visitor(Geometry1 const& geometry1): m_geometry1(geometry1) {}
+ visitor(Geometry1 const& geometry1, Strategy const& strategy)
+ : m_geometry1(geometry1)
+ , m_strategy(strategy)
+ {}
template <typename Geometry2>
bool operator()(Geometry2 const& geometry2) const
{
- return touches<Geometry1, Geometry2>::apply(m_geometry1, geometry2);
+ return touches<Geometry1, Geometry2>::apply(m_geometry1, geometry2, m_strategy);
}
};
- static inline bool
- apply(Geometry1 const& geometry1,
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2)
+ template <typename Strategy>
+ static inline bool apply(Geometry1 const& geometry1,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
+ Strategy const& strategy)
{
- return boost::apply_visitor(visitor(geometry1), geometry2);
+ return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
}
};
@@ -471,21 +550,29 @@ template <BOOST_VARIANT_ENUM_PARAMS(typename T1),
struct touches<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
{
+ template <typename Strategy>
struct visitor: boost::static_visitor<bool>
{
+ Strategy const& m_strategy;
+
+ visitor(Strategy const& strategy)
+ : m_strategy(strategy)
+ {}
+
template <typename Geometry1, typename Geometry2>
bool operator()(Geometry1 const& geometry1,
Geometry2 const& geometry2) const
{
- return touches<Geometry1, Geometry2>::apply(geometry1, geometry2);
+ return touches<Geometry1, Geometry2>::apply(geometry1, geometry2, m_strategy);
}
};
- static inline bool
- apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2)
+ template <typename Strategy>
+ static inline bool 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(), geometry1, geometry2);
+ return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
}
};
@@ -496,6 +583,10 @@ struct self_touches
{
concepts::check<Geometry const>();
+ typedef typename strategy::relate::services::default_strategy
+ <
+ Geometry, Geometry
+ >::type strategy_type;
typedef detail::no_rescale_policy rescale_policy_type;
typedef typename geometry::point_type<Geometry>::type point_type;
typedef detail::overlay::turn_info
@@ -511,11 +602,12 @@ struct self_touches
std::deque<turn_info> turns;
detail::touches::areal_interrupt_policy policy;
+ strategy_type strategy;
rescale_policy_type robust_policy;
detail::self_get_turn_points::get_turns
<
policy_type
- >::apply(geometry, robust_policy, turns, policy);
+ >::apply(geometry, strategy, robust_policy, turns, policy);
return policy.result();
}
@@ -578,7 +670,35 @@ inline bool touches(Geometry const& geometry)
template <typename Geometry1, typename Geometry2>
inline bool touches(Geometry1 const& geometry1, Geometry2 const& geometry2)
{
- return resolve_variant::touches<Geometry1, Geometry2>::apply(geometry1, geometry2);
+ return resolve_variant::touches
+ <
+ Geometry1, Geometry2
+ >::apply(geometry1, geometry2, default_strategy());
+}
+
+/*!
+\brief \brief_check2{have at least one touching point (tangent - non overlapping)}
+\ingroup touches
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam Strategy \tparam_strategy{Touches}
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param strategy \param_strategy{touches}
+\return \return_check2{touch each other}
+
+\qbk{distinguish,with strategy}
+\qbk{[include reference/algorithms/touches.qbk]}
+ */
+template <typename Geometry1, typename Geometry2, typename Strategy>
+inline bool touches(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+{
+ return resolve_variant::touches
+ <
+ Geometry1, Geometry2
+ >::apply(geometry1, geometry2, strategy);
}
diff --git a/boost/geometry/algorithms/union.hpp b/boost/geometry/algorithms/union.hpp
index f0e55ec981..d3a2daf66e 100644
--- a/boost/geometry/algorithms/union.hpp
+++ b/boost/geometry/algorithms/union.hpp
@@ -2,10 +2,11 @@
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2017.
+// Modifications copyright (c) 2014-2017 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
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -24,6 +25,8 @@
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
+#include <boost/geometry/strategies/default_strategy.hpp>
+#include <boost/geometry/util/range.hpp>
#include <boost/geometry/algorithms/detail/overlay/linear_linear.hpp>
#include <boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp>
@@ -214,14 +217,10 @@ inline OutputIterator union_insert(Geometry1 const& geometry1,
Geometry2
>::type rescale_policy_type;
- typedef intersection_strategies
+ typename strategy::intersection::services::default_strategy
<
- typename cs_tag<GeometryOut>::type,
- Geometry1,
- Geometry2,
- typename geometry::point_type<GeometryOut>::type,
- rescale_policy_type
- > strategy;
+ typename cs_tag<GeometryOut>::type
+ >::type strategy;
rescale_policy_type robust_policy
= geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
@@ -229,7 +228,7 @@ inline OutputIterator union_insert(Geometry1 const& geometry1,
return dispatch::union_insert
<
Geometry1, Geometry2, GeometryOut
- >::apply(geometry1, geometry2, robust_policy, out, strategy());
+ >::apply(geometry1, geometry2, robust_policy, out, strategy);
}
@@ -237,6 +236,228 @@ inline OutputIterator union_insert(Geometry1 const& geometry1,
#endif // DOXYGEN_NO_DETAIL
+namespace resolve_strategy {
+
+struct union_
+{
+ template
+ <
+ typename Geometry1,
+ typename Geometry2,
+ typename RobustPolicy,
+ typename Collection,
+ typename Strategy
+ >
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
+ Collection & output_collection,
+ Strategy const& strategy)
+ {
+ typedef typename boost::range_value<Collection>::type geometry_out;
+
+ dispatch::union_insert
+ <
+ Geometry1, Geometry2, geometry_out
+ >::apply(geometry1, geometry2, robust_policy,
+ range::back_inserter(output_collection),
+ strategy);
+ }
+
+ template
+ <
+ typename Geometry1,
+ typename Geometry2,
+ typename RobustPolicy,
+ typename Collection
+ >
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
+ Collection & output_collection,
+ default_strategy)
+ {
+ typedef typename boost::range_value<Collection>::type geometry_out;
+
+ typedef typename strategy::intersection::services::default_strategy
+ <
+ typename cs_tag<geometry_out>::type
+ >::type strategy_type;
+
+ dispatch::union_insert
+ <
+ Geometry1, Geometry2, geometry_out
+ >::apply(geometry1, geometry2, robust_policy,
+ range::back_inserter(output_collection),
+ strategy_type());
+ }
+};
+
+} // resolve_strategy
+
+
+namespace resolve_variant
+{
+
+template <typename Geometry1, typename Geometry2>
+struct union_
+{
+ template <typename Collection, typename Strategy>
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
+ {
+ concepts::check<Geometry1 const>();
+ concepts::check<Geometry2 const>();
+ concepts::check<typename boost::range_value<Collection>::type>();
+
+ typedef typename geometry::rescale_overlay_policy_type
+ <
+ Geometry1,
+ Geometry2
+ >::type rescale_policy_type;
+
+ rescale_policy_type robust_policy
+ = geometry::get_rescale_policy<rescale_policy_type>(geometry1,
+ geometry2);
+
+ resolve_strategy::union_::apply(geometry1, geometry2,
+ robust_policy,
+ output_collection,
+ strategy);
+ }
+};
+
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
+struct union_<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
+{
+ template <typename Collection, typename Strategy>
+ struct visitor: static_visitor<>
+ {
+ Geometry2 const& m_geometry2;
+ Collection& m_output_collection;
+ Strategy const& m_strategy;
+
+ visitor(Geometry2 const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
+ : m_geometry2(geometry2)
+ , m_output_collection(output_collection)
+ , m_strategy(strategy)
+ {}
+
+ template <typename Geometry1>
+ void operator()(Geometry1 const& geometry1) const
+ {
+ union_
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, m_geometry2, m_output_collection, m_strategy);
+ }
+ };
+
+ template <typename Collection, typename Strategy>
+ static inline void
+ apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
+ Geometry2 const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
+ {
+ boost::apply_visitor(visitor<Collection, Strategy>(geometry2,
+ output_collection,
+ strategy),
+ geometry1);
+ }
+};
+
+
+template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct union_<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ template <typename Collection, typename Strategy>
+ struct visitor: static_visitor<>
+ {
+ Geometry1 const& m_geometry1;
+ Collection& m_output_collection;
+ Strategy const& m_strategy;
+
+ visitor(Geometry1 const& geometry1,
+ Collection& output_collection,
+ Strategy const& strategy)
+ : m_geometry1(geometry1)
+ , m_output_collection(output_collection)
+ , m_strategy(strategy)
+ {}
+
+ template <typename Geometry2>
+ void operator()(Geometry2 const& geometry2) const
+ {
+ union_
+ <
+ Geometry1,
+ Geometry2
+ >::apply(m_geometry1, geometry2, m_output_collection, m_strategy);
+ }
+ };
+
+ template <typename Collection, typename Strategy>
+ static inline void
+ apply(Geometry1 const& geometry1,
+ variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
+ {
+ boost::apply_visitor(visitor<Collection, Strategy>(geometry1,
+ output_collection,
+ strategy),
+ geometry2);
+ }
+};
+
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2)>
+struct union_<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
+{
+ template <typename Collection, typename Strategy>
+ struct visitor: static_visitor<>
+ {
+ Collection& m_output_collection;
+ Strategy const& m_strategy;
+
+ visitor(Collection& output_collection, Strategy const& strategy)
+ : m_output_collection(output_collection)
+ , m_strategy(strategy)
+ {}
+
+ template <typename Geometry1, typename Geometry2>
+ void operator()(Geometry1 const& geometry1,
+ Geometry2 const& geometry2) const
+ {
+ union_
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, m_output_collection, m_strategy);
+ }
+ };
+
+ template <typename Collection, typename Strategy>
+ static inline void
+ apply(variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
+ variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
+ {
+ boost::apply_visitor(visitor<Collection, Strategy>(output_collection,
+ strategy),
+ geometry1, geometry2);
+ }
+};
+
+} // namespace resolve_variant
/*!
@@ -247,31 +468,66 @@ inline OutputIterator union_insert(Geometry1 const& geometry1,
\tparam Geometry2 \tparam_geometry
\tparam Collection output collection, either a multi-geometry,
or a std::vector<Geometry> / std::deque<Geometry> etc
+\tparam Strategy \tparam_strategy{Union_}
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\param output_collection the output collection
+\param strategy \param_strategy{union_}
\note Called union_ because union is a reserved word.
+\qbk{distinguish,with strategy}
\qbk{[include reference/algorithms/union.qbk]}
*/
template
<
typename Geometry1,
typename Geometry2,
- typename Collection
+ typename Collection,
+ typename Strategy
>
inline void union_(Geometry1 const& geometry1,
- Geometry2 const& geometry2,
- Collection& output_collection)
+ Geometry2 const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
{
- concepts::check<Geometry1 const>();
- concepts::check<Geometry2 const>();
+ resolve_variant::union_
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, output_collection, strategy);
+}
- typedef typename boost::range_value<Collection>::type geometry_out;
- concepts::check<geometry_out>();
- detail::union_::union_insert<geometry_out>(geometry1, geometry2,
- range::back_inserter(output_collection));
+/*!
+\brief Combines two geometries which each other
+\ingroup union
+\details \details_calc2{union, spatial set theoretic union}.
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam Collection output collection, either a multi-geometry,
+ or a std::vector<Geometry> / std::deque<Geometry> etc
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param output_collection the output collection
+\note Called union_ because union is a reserved word.
+
+\qbk{[include reference/algorithms/union.qbk]}
+*/
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename Collection
+>
+inline void union_(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Collection& output_collection)
+{
+ resolve_variant::union_
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, output_collection, default_strategy());
}
diff --git a/boost/geometry/algorithms/within.hpp b/boost/geometry/algorithms/within.hpp
index a1e6a58f8d..ba170dd27b 100644
--- a/boost/geometry/algorithms/within.hpp
+++ b/boost/geometry/algorithms/within.hpp
@@ -4,8 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2013, 2014.
-// Modifications copyright (c) 2013, 2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2017.
+// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
+
+// 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.
@@ -14,8 +16,6 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_ALGORITHMS_WITHIN_HPP
#define BOOST_GEOMETRY_ALGORITHMS_WITHIN_HPP
@@ -52,6 +52,7 @@
#include <boost/geometry/views/reversible_view.hpp>
#include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
+#include <boost/geometry/algorithms/relate.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
#include <boost/geometry/algorithms/detail/overlay/do_reverse.hpp>
@@ -75,9 +76,13 @@ struct use_point_in_geometry
struct use_relate
{
template <typename Geometry1, typename Geometry2, typename Strategy>
- static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& /*strategy*/)
+ static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
{
- return Strategy::apply(geometry1, geometry2);
+ typedef typename detail::de9im::static_mask_within_type
+ <
+ Geometry1, Geometry2
+ >::type within_mask;
+ return geometry::relate(geometry1, geometry2, within_mask(), strategy);
}
};
@@ -300,23 +305,8 @@ struct within
Geometry2 const& geometry2,
default_strategy)
{
- typedef typename point_type<Geometry1>::type point_type1;
- typedef typename point_type<Geometry2>::type point_type2;
-
typedef typename strategy::within::services::default_strategy
<
- typename tag<Geometry1>::type,
- typename tag<Geometry2>::type,
- typename tag<Geometry1>::type,
- typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
- typename tag_cast
- <
- typename cs_tag<point_type1>::type, spherical_tag
- >::type,
- typename tag_cast
- <
- typename cs_tag<point_type2>::type, spherical_tag
- >::type,
Geometry1,
Geometry2
>::type strategy_type;
@@ -517,8 +507,9 @@ inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2)
}
*/
template<typename Geometry1, typename Geometry2, typename Strategy>
-inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2,
- Strategy const& strategy)
+inline bool within(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
{
return resolve_variant::within
<