summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2016-10-06 10:30:07 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2016-10-06 10:32:57 +0900
commit71d216b90256936a9638f325af9bc69d720e75de (patch)
tree9c5f682d341c7c88ad0c8e3d4b262e00b6fb691a /boost/geometry/algorithms
parent733b5d5ae2c5d625211e2985ac25728ac3f54883 (diff)
downloadboost-71d216b90256936a9638f325af9bc69d720e75de.tar.gz
boost-71d216b90256936a9638f325af9bc69d720e75de.tar.bz2
boost-71d216b90256936a9638f325af9bc69d720e75de.zip
Imported Upstream version 1.59.0
Change-Id: I2dde00f4eca71df3eea9d251dcaecde18a6c90a5 Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'boost/geometry/algorithms')
-rw-r--r--boost/geometry/algorithms/append.hpp2
-rw-r--r--boost/geometry/algorithms/assign.hpp6
-rw-r--r--boost/geometry/algorithms/buffer.hpp13
-rw-r--r--boost/geometry/algorithms/centroid.hpp20
-rw-r--r--boost/geometry/algorithms/clear.hpp2
-rw-r--r--boost/geometry/algorithms/convert.hpp2
-rw-r--r--boost/geometry/algorithms/convex_hull.hpp13
-rw-r--r--boost/geometry/algorithms/crosses.hpp53
-rw-r--r--boost/geometry/algorithms/detail/andoyer_inverse.hpp163
-rw-r--r--boost/geometry/algorithms/detail/azimuth.hpp4
-rw-r--r--boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp104
-rw-r--r--boost/geometry/algorithms/detail/buffer/buffer_policies.hpp35
-rw-r--r--boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp192
-rw-r--r--boost/geometry/algorithms/detail/buffer/buffered_ring.hpp9
-rw-r--r--boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp51
-rw-r--r--boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp244
-rw-r--r--boost/geometry/algorithms/detail/check_iterator_range.hpp4
-rw-r--r--boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp5
-rw-r--r--boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp6
-rw-r--r--boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp15
-rw-r--r--boost/geometry/algorithms/detail/comparable_distance/interface.hpp8
-rw-r--r--boost/geometry/algorithms/detail/disjoint/interface.hpp2
-rw-r--r--boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp140
-rw-r--r--boost/geometry/algorithms/detail/disjoint/point_geometry.hpp47
-rw-r--r--boost/geometry/algorithms/detail/disjoint/point_point.hpp165
-rw-r--r--boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp24
-rw-r--r--boost/geometry/algorithms/detail/distance/interface.hpp8
-rw-r--r--boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp5
-rw-r--r--boost/geometry/algorithms/detail/distance/segment_to_box.hpp8
-rw-r--r--boost/geometry/algorithms/detail/envelope/box.hpp167
-rw-r--r--boost/geometry/algorithms/detail/envelope/implementation.hpp106
-rw-r--r--boost/geometry/algorithms/detail/envelope/initialize.hpp86
-rw-r--r--boost/geometry/algorithms/detail/envelope/interface.hpp126
-rw-r--r--boost/geometry/algorithms/detail/envelope/intersects_antimeridian.hpp78
-rw-r--r--boost/geometry/algorithms/detail/envelope/linear.hpp96
-rw-r--r--boost/geometry/algorithms/detail/envelope/multipoint.hpp378
-rw-r--r--boost/geometry/algorithms/detail/envelope/point.hpp127
-rw-r--r--boost/geometry/algorithms/detail/envelope/range.hpp179
-rw-r--r--boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp326
-rw-r--r--boost/geometry/algorithms/detail/envelope/segment.hpp386
-rw-r--r--boost/geometry/algorithms/detail/envelope/transform_units.hpp103
-rw-r--r--boost/geometry/algorithms/detail/expand/box.hpp126
-rw-r--r--boost/geometry/algorithms/detail/expand/implementation.hpp27
-rw-r--r--boost/geometry/algorithms/detail/expand/indexed.hpp144
-rw-r--r--boost/geometry/algorithms/detail/expand/interface.hpp128
-rw-r--r--boost/geometry/algorithms/detail/expand/point.hpp303
-rw-r--r--boost/geometry/algorithms/detail/expand/segment.hpp115
-rw-r--r--boost/geometry/algorithms/detail/get_left_turns.hpp18
-rw-r--r--boost/geometry/algorithms/detail/intersection/interface.hpp28
-rw-r--r--boost/geometry/algorithms/detail/intersection/multi.hpp6
-rw-r--r--boost/geometry/algorithms/detail/is_simple/linear.hpp12
-rw-r--r--boost/geometry/algorithms/detail/is_valid/box.hpp5
-rw-r--r--boost/geometry/algorithms/detail/is_valid/complement_graph.hpp18
-rw-r--r--boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp15
-rw-r--r--boost/geometry/algorithms/detail/is_valid/has_spikes.hpp40
-rw-r--r--boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp7
-rw-r--r--boost/geometry/algorithms/detail/is_valid/interface.hpp6
-rw-r--r--boost/geometry/algorithms/detail/is_valid/linear.hpp5
-rw-r--r--boost/geometry/algorithms/detail/is_valid/multipolygon.hpp18
-rw-r--r--boost/geometry/algorithms/detail/is_valid/pointlike.hpp10
-rw-r--r--boost/geometry/algorithms/detail/is_valid/polygon.hpp15
-rw-r--r--boost/geometry/algorithms/detail/is_valid/ring.hpp9
-rw-r--r--boost/geometry/algorithms/detail/is_valid/segment.hpp5
-rw-r--r--boost/geometry/algorithms/detail/max_interval_gap.hpp278
-rw-r--r--boost/geometry/algorithms/detail/normalize.hpp294
-rw-r--r--boost/geometry/algorithms/detail/occupation_info.hpp31
-rw-r--r--boost/geometry/algorithms/detail/overlay/add_rings.hpp2
-rw-r--r--boost/geometry/algorithms/detail/overlay/assign_parents.hpp2
-rw-r--r--boost/geometry/algorithms/detail/overlay/check_enrich.hpp4
-rw-r--r--boost/geometry/algorithms/detail/overlay/clip_linestring.hpp9
-rw-r--r--boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp14
-rw-r--r--boost/geometry/algorithms/detail/overlay/copy_segments.hpp47
-rw-r--r--boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp5
-rw-r--r--boost/geometry/algorithms/detail/overlay/enrichment_info.hpp6
-rw-r--r--boost/geometry/algorithms/detail/overlay/follow.hpp14
-rw-r--r--boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp20
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp3
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_ring.hpp6
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turn_info.hpp6
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp25
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp93
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp6
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp8
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turns.hpp27
-rw-r--r--boost/geometry/algorithms/detail/overlay/intersection_insert.hpp132
-rw-r--r--boost/geometry/algorithms/detail/overlay/linear_linear.hpp30
-rw-r--r--boost/geometry/algorithms/detail/overlay/overlay.hpp23
-rw-r--r--boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp343
-rw-r--r--boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp8
-rw-r--r--boost/geometry/algorithms/detail/overlay/ring_properties.hpp7
-rw-r--r--boost/geometry/algorithms/detail/overlay/segment_identifier.hpp18
-rw-r--r--boost/geometry/algorithms/detail/overlay/self_turn_points.hpp1
-rw-r--r--boost/geometry/algorithms/detail/overlay/traverse.hpp9
-rw-r--r--boost/geometry/algorithms/detail/partition.hpp456
-rw-r--r--boost/geometry/algorithms/detail/recalculate.hpp1
-rw-r--r--boost/geometry/algorithms/detail/relate/areal_areal.hpp28
-rw-r--r--boost/geometry/algorithms/detail/relate/boundary_checker.hpp2
-rw-r--r--boost/geometry/algorithms/detail/relate/de9im.hpp439
-rw-r--r--boost/geometry/algorithms/detail/relate/follow_helpers.hpp22
-rw-r--r--boost/geometry/algorithms/detail/relate/implementation.hpp110
-rw-r--r--boost/geometry/algorithms/detail/relate/interface.hpp348
-rw-r--r--boost/geometry/algorithms/detail/relate/less.hpp4
-rw-r--r--boost/geometry/algorithms/detail/relate/linear_areal.hpp71
-rw-r--r--boost/geometry/algorithms/detail/relate/linear_linear.hpp16
-rw-r--r--boost/geometry/algorithms/detail/relate/point_geometry.hpp17
-rw-r--r--boost/geometry/algorithms/detail/relate/point_point.hpp39
-rw-r--r--boost/geometry/algorithms/detail/relate/relate.hpp339
-rw-r--r--boost/geometry/algorithms/detail/relate/relate_impl.hpp80
-rw-r--r--boost/geometry/algorithms/detail/relate/result.hpp648
-rw-r--r--boost/geometry/algorithms/detail/relate/turns.hpp33
-rw-r--r--boost/geometry/algorithms/detail/relation/implementation.hpp18
-rw-r--r--boost/geometry/algorithms/detail/relation/interface.hpp186
-rw-r--r--boost/geometry/algorithms/detail/result_inverse.hpp44
-rw-r--r--boost/geometry/algorithms/detail/ring_identifier.hpp14
-rw-r--r--boost/geometry/algorithms/detail/sections/range_by_section.hpp4
-rw-r--r--boost/geometry/algorithms/detail/sections/sectionalize.hpp33
-rw-r--r--boost/geometry/algorithms/detail/signed_size_type.hpp (renamed from boost/geometry/algorithms/detail/signed_index_type.hpp)11
-rw-r--r--boost/geometry/algorithms/detail/single_geometry.hpp12
-rw-r--r--boost/geometry/algorithms/detail/sub_range.hpp12
-rw-r--r--boost/geometry/algorithms/detail/sweep.hpp87
-rw-r--r--boost/geometry/algorithms/detail/thomas_inverse.hpp191
-rw-r--r--boost/geometry/algorithms/detail/throw_on_empty_input.hpp15
-rw-r--r--boost/geometry/algorithms/detail/turns/compare_turns.hpp16
-rw-r--r--boost/geometry/algorithms/detail/turns/print_turns.hpp4
-rw-r--r--boost/geometry/algorithms/detail/vincenty_direct.hpp121
-rw-r--r--boost/geometry/algorithms/detail/vincenty_inverse.hpp166
-rw-r--r--boost/geometry/algorithms/detail/within/point_in_geometry.hpp8
-rw-r--r--boost/geometry/algorithms/dispatch/envelope.hpp49
-rw-r--r--boost/geometry/algorithms/dispatch/expand.hpp58
-rw-r--r--boost/geometry/algorithms/envelope.hpp294
-rw-r--r--boost/geometry/algorithms/equals.hpp13
-rw-r--r--boost/geometry/algorithms/expand.hpp348
-rw-r--r--boost/geometry/algorithms/is_convex.hpp160
-rw-r--r--boost/geometry/algorithms/is_empty.hpp207
-rw-r--r--boost/geometry/algorithms/length.hpp2
-rw-r--r--boost/geometry/algorithms/overlaps.hpp7
-rw-r--r--boost/geometry/algorithms/relate.hpp17
-rw-r--r--boost/geometry/algorithms/relation.hpp17
-rw-r--r--boost/geometry/algorithms/simplify.hpp2
-rw-r--r--boost/geometry/algorithms/sym_difference.hpp201
-rw-r--r--boost/geometry/algorithms/touches.hpp17
-rw-r--r--boost/geometry/algorithms/transform.hpp31
-rw-r--r--boost/geometry/algorithms/within.hpp30
143 files changed, 8600 insertions, 2487 deletions
diff --git a/boost/geometry/algorithms/append.hpp b/boost/geometry/algorithms/append.hpp
index 6ffb5f9587..894f52c68b 100644
--- a/boost/geometry/algorithms/append.hpp
+++ b/boost/geometry/algorithms/append.hpp
@@ -327,7 +327,7 @@ struct append<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
int ring_index,
int multi_index)
{
- apply_visitor(
+ boost::apply_visitor(
visitor<RangeOrPoint>(
range_or_point,
ring_index,
diff --git a/boost/geometry/algorithms/assign.hpp b/boost/geometry/algorithms/assign.hpp
index 2f325448ad..b17e305f2a 100644
--- a/boost/geometry/algorithms/assign.hpp
+++ b/boost/geometry/algorithms/assign.hpp
@@ -281,7 +281,7 @@ struct assign<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry1,
Geometry2 const& geometry2)
{
- return apply_visitor(visitor(geometry2), geometry1);
+ return boost::apply_visitor(visitor(geometry2), geometry1);
}
};
@@ -313,7 +313,7 @@ struct assign<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
apply(Geometry1& geometry1,
variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2)
{
- return apply_visitor(visitor(geometry1), geometry2);
+ return boost::apply_visitor(visitor(geometry1), geometry2);
}
};
@@ -341,7 +341,7 @@ struct assign<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM
apply(variant<BOOST_VARIANT_ENUM_PARAMS(T1)>& geometry1,
variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2)
{
- return apply_visitor(visitor(), geometry1, geometry2);
+ return boost::apply_visitor(visitor(), geometry1, geometry2);
}
};
diff --git a/boost/geometry/algorithms/buffer.hpp b/boost/geometry/algorithms/buffer.hpp
index d85d32a0c6..e776072a2f 100644
--- a/boost/geometry/algorithms/buffer.hpp
+++ b/boost/geometry/algorithms/buffer.hpp
@@ -18,12 +18,15 @@
#include <boost/numeric/conversion/cast.hpp>
+#include <boost/range.hpp>
+
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/algorithms/clear.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
+#include <boost/geometry/algorithms/is_empty.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
@@ -261,9 +264,15 @@ inline void buffer(GeometryIn const& geometry_in,
geometry_out.clear();
+ if (geometry::is_empty(geometry_in))
+ {
+ // Then output geometry is kept empty as well
+ return;
+ }
+
model::box<point_type> box;
- envelope(geometry_in, box);
- buffer(box, box, distance_strategy.max_distance(join_strategy, end_strategy));
+ geometry::envelope(geometry_in, box);
+ geometry::buffer(box, box, distance_strategy.max_distance(join_strategy, end_strategy));
rescale_policy_type rescale_policy
= boost::geometry::get_rescale_policy<rescale_policy_type>(box);
diff --git a/boost/geometry/algorithms/centroid.hpp b/boost/geometry/algorithms/centroid.hpp
index 67ed68ac03..1b99ab2ef3 100644
--- a/boost/geometry/algorithms/centroid.hpp
+++ b/boost/geometry/algorithms/centroid.hpp
@@ -1,14 +1,15 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+// 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.
// This file was modified by Oracle on 2014, 2015.
// Modifications copyright (c) 2014-2015 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
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -55,8 +56,7 @@
#include <boost/geometry/util/for_each_coordinate.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
-#include <boost/geometry/algorithms/num_points.hpp>
-#include <boost/geometry/multi/algorithms/num_points.hpp>
+#include <boost/geometry/algorithms/is_empty.hpp>
#include <boost/geometry/algorithms/detail/centroid/translating_transformer.hpp>
@@ -361,7 +361,7 @@ struct centroid_multi
#if ! defined(BOOST_GEOMETRY_CENTROID_NO_THROW)
// If there is nothing in any of the ranges, it is not possible
// to calculate the centroid
- if (geometry::num_points(multi) == 0)
+ if (geometry::is_empty(multi))
{
throw centroid_exception();
}
@@ -624,7 +624,7 @@ inline void centroid(Geometry const& geometry, Point& c,
template<typename Geometry, typename Point>
inline void centroid(Geometry const& geometry, Point& c)
{
- centroid(geometry, c, default_strategy());
+ geometry::centroid(geometry, c, default_strategy());
}
@@ -643,7 +643,7 @@ template<typename Point, typename Geometry>
inline Point return_centroid(Geometry const& geometry)
{
Point c;
- centroid(geometry, c);
+ geometry::centroid(geometry, c);
return c;
}
@@ -666,7 +666,7 @@ template<typename Point, typename Geometry, typename Strategy>
inline Point return_centroid(Geometry const& geometry, Strategy const& strategy)
{
Point c;
- centroid(geometry, c, strategy);
+ geometry::centroid(geometry, c, strategy);
return c;
}
diff --git a/boost/geometry/algorithms/clear.hpp b/boost/geometry/algorithms/clear.hpp
index 22b61e7c30..54b2162767 100644
--- a/boost/geometry/algorithms/clear.hpp
+++ b/boost/geometry/algorithms/clear.hpp
@@ -162,7 +162,7 @@ struct clear<variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
static inline void apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry)
{
- apply_visitor(visitor(), geometry);
+ boost::apply_visitor(visitor(), geometry);
}
};
diff --git a/boost/geometry/algorithms/convert.hpp b/boost/geometry/algorithms/convert.hpp
index 5d68854a45..78618aed2d 100644
--- a/boost/geometry/algorithms/convert.hpp
+++ b/boost/geometry/algorithms/convert.hpp
@@ -522,7 +522,7 @@ struct convert<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
Geometry2& geometry2
)
{
- apply_visitor(visitor(geometry2), geometry1);
+ boost::apply_visitor(visitor(geometry2), geometry1);
}
};
diff --git a/boost/geometry/algorithms/convex_hull.hpp b/boost/geometry/algorithms/convex_hull.hpp
index c6db004f3d..71c18bb5f3 100644
--- a/boost/geometry/algorithms/convex_hull.hpp
+++ b/boost/geometry/algorithms/convex_hull.hpp
@@ -1,13 +1,14 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// 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.
// This file was modified by Oracle on 2014, 2015.
// Modifications copyright (c) 2014-2015 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
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -40,7 +41,7 @@
#include <boost/geometry/views/detail/range_type.hpp>
-#include <boost/geometry/algorithms/num_points.hpp>
+#include <boost/geometry/algorithms/is_empty.hpp>
#include <boost/geometry/algorithms/detail/as_range.hpp>
#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
@@ -301,7 +302,7 @@ template<typename Geometry, typename OutputGeometry, typename Strategy>
inline void convex_hull(Geometry const& geometry,
OutputGeometry& out, Strategy const& strategy)
{
- if (geometry::num_points(geometry) == 0)
+ if (geometry::is_empty(geometry))
{
// Leave output empty
return;
@@ -326,7 +327,7 @@ template<typename Geometry, typename OutputGeometry>
inline void convex_hull(Geometry const& geometry,
OutputGeometry& hull)
{
- convex_hull(geometry, hull, default_strategy());
+ geometry::convex_hull(geometry, hull, default_strategy());
}
#ifndef DOXYGEN_NO_DETAIL
diff --git a/boost/geometry/algorithms/crosses.hpp b/boost/geometry/algorithms/crosses.hpp
index cec4931a64..9546a5335b 100644
--- a/boost/geometry/algorithms/crosses.hpp
+++ b/boost/geometry/algorithms/crosses.hpp
@@ -30,7 +30,8 @@
#include <boost/geometry/geometries/concepts/check.hpp>
-#include <boost/geometry/algorithms/detail/relate/relate.hpp>
+#include <boost/geometry/algorithms/relate.hpp>
+#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
namespace boost { namespace geometry
{
@@ -48,9 +49,9 @@ template
typename Tag2 = typename tag<Geometry2>::type
>
struct crosses
- : detail::relate::relate_base
+ : detail::relate::relate_impl
<
- detail::relate::static_mask_crosses_type,
+ detail::de9im::static_mask_crosses_type,
Geometry1,
Geometry2
>
@@ -87,18 +88,17 @@ namespace resolve_variant
Geometry2 const& m_geometry2;
visitor(Geometry2 const& geometry2)
- : m_geometry2(geometry2)
+ : m_geometry2(geometry2)
{}
template <typename Geometry1>
result_type operator()(Geometry1 const& geometry1) const
{
return crosses
- <
- Geometry1,
- Geometry2
- >::apply
- (geometry1, m_geometry2);
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, m_geometry2);
}
};
@@ -106,7 +106,7 @@ namespace resolve_variant
apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
Geometry2 const& geometry2)
{
- return apply_visitor(visitor(geometry2), geometry1);
+ return boost::apply_visitor(visitor(geometry2), geometry1);
}
};
@@ -119,27 +119,25 @@ namespace resolve_variant
Geometry1 const& m_geometry1;
visitor(Geometry1 const& geometry1)
- : m_geometry1(geometry1)
+ : m_geometry1(geometry1)
{}
template <typename Geometry2>
result_type operator()(Geometry2 const& geometry2) const
{
return crosses
- <
- Geometry1,
- Geometry2
- >::apply
- (m_geometry1, geometry2);
+ <
+ Geometry1,
+ Geometry2
+ >::apply(m_geometry1, geometry2);
}
};
static inline bool
- apply(
- Geometry1 const& geometry1,
+ apply(Geometry1 const& geometry1,
const variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry2)
{
- return apply_visitor(visitor(geometry1), geometry2);
+ return boost::apply_visitor(visitor(geometry1), geometry2);
}
};
@@ -150,25 +148,22 @@ namespace resolve_variant
struct visitor: static_visitor<bool>
{
template <typename Geometry1, typename Geometry2>
- result_type operator()(
- Geometry1 const& geometry1,
+ result_type operator()(Geometry1 const& geometry1,
Geometry2 const& geometry2) const
{
return crosses
- <
- Geometry1,
- Geometry2
- >::apply
- (geometry1, geometry2);
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2);
}
};
static inline bool
- apply(
- const variant<BOOST_VARIANT_ENUM_PARAMS(T1)>& geometry1,
+ apply(const variant<BOOST_VARIANT_ENUM_PARAMS(T1)>& geometry1,
const variant<BOOST_VARIANT_ENUM_PARAMS(T2)>& geometry2)
{
- return apply_visitor(visitor(), geometry1, geometry2);
+ return boost::apply_visitor(visitor(), geometry1, geometry2);
}
};
diff --git a/boost/geometry/algorithms/detail/andoyer_inverse.hpp b/boost/geometry/algorithms/detail/andoyer_inverse.hpp
new file mode 100644
index 0000000000..eb8485b8e1
--- /dev/null
+++ b/boost/geometry/algorithms/detail/andoyer_inverse.hpp
@@ -0,0 +1,163 @@
+// Boost.Geometry
+
+// Copyright (c) 2015 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_ANDOYER_INVERSE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ANDOYER_INVERSE_HPP
+
+
+#include <boost/math/constants/constants.hpp>
+
+#include <boost/geometry/core/radius.hpp>
+#include <boost/geometry/core/srs.hpp>
+
+#include <boost/geometry/util/condition.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/detail/flattening.hpp>
+#include <boost/geometry/algorithms/detail/result_inverse.hpp>
+
+
+namespace boost { namespace geometry { namespace detail
+{
+
+/*!
+\brief The solution of the inverse problem of geodesics on latlong coordinates,
+ Forsyth-Andoyer-Lambert type approximation with first order terms.
+\author See
+ - Technical Report: PAUL D. THOMAS, MATHEMATICAL MODELS FOR NAVIGATION SYSTEMS, 1965
+ http://www.dtic.mil/docs/citations/AD0627893
+ - Technical Report: PAUL D. THOMAS, SPHEROIDAL GEODESICS, REFERENCE SYSTEMS, AND LOCAL GEOMETRY, 1970
+ http://www.dtic.mil/docs/citations/AD703541
+*/
+
+template <typename CT, bool EnableDistance, bool EnableAzimuth>
+struct andoyer_inverse
+{
+ typedef result_inverse<CT> result_type;
+
+ template <typename T1, typename T2, typename Spheroid>
+ static inline result_type apply(T1 const& lon1,
+ T1 const& lat1,
+ T2 const& lon2,
+ T2 const& lat2,
+ Spheroid const& spheroid)
+ {
+ result_type result;
+
+ // coordinates in radians
+
+ if ( math::equals(lon1, lon2)
+ && math::equals(lat1, lat2) )
+ {
+ result.set(CT(0), CT(0));
+ return result;
+ }
+
+ CT const pi_half = math::pi<CT>() / CT(2);
+
+ if ( math::equals(math::abs(lat1), pi_half)
+ && math::equals(math::abs(lat2), pi_half) )
+ {
+ result.set(CT(0), CT(0));
+ return result;
+ }
+
+ CT const dlon = lon2 - lon1;
+ CT const sin_dlon = sin(dlon);
+ CT const cos_dlon = cos(dlon);
+ CT const sin_lat1 = sin(lat1);
+ CT const cos_lat1 = cos(lat1);
+ CT const sin_lat2 = sin(lat2);
+ CT const cos_lat2 = cos(lat2);
+
+ // H,G,T = infinity if cos_d = 1 or cos_d = -1
+ // lat1 == +-90 && lat2 == +-90
+ // lat1 == lat2 && lon1 == lon2
+ CT const cos_d = sin_lat1*sin_lat2 + cos_lat1*cos_lat2*cos_dlon;
+ CT const d = acos(cos_d);
+ CT const sin_d = sin(d);
+
+ // just in case since above lat1 and lat2 is checked
+ // the check below is equal to cos_d == 1 || cos_d == -1 || d == 0
+ if ( math::equals(sin_d, CT(0)) )
+ {
+ result.set(CT(0), CT(0));
+ return result;
+ }
+
+ // if the function returned before this place
+ // and endpoints were on the poles +-90 deg
+ // in this case the azimuth could either be 0 or +-pi
+
+ CT const f = detail::flattening<CT>(spheroid);
+
+ if ( BOOST_GEOMETRY_CONDITION(EnableDistance) )
+ {
+ CT const K = math::sqr(sin_lat1-sin_lat2);
+ CT const L = math::sqr(sin_lat1+sin_lat2);
+ CT const three_sin_d = CT(3) * sin_d;
+ // H or G = infinity if cos_d = 1 or cos_d = -1
+ CT const H = (d+three_sin_d)/(CT(1)-cos_d);
+ CT const G = (d-three_sin_d)/(CT(1)+cos_d);
+
+ // for e.g. lat1=-90 && lat2=90 here we have G*L=INF*0
+ CT const dd = -(f/CT(4))*(H*K+G*L);
+
+ CT const a = get_radius<0>(spheroid);
+
+ result.distance = a * (d + dd);
+ }
+ else
+ {
+ result.distance = CT(0);
+ }
+
+ if ( BOOST_GEOMETRY_CONDITION(EnableAzimuth) )
+ {
+ CT A = CT(0);
+ CT U = CT(0);
+ if ( ! math::equals(cos_lat2, CT(0)) )
+ {
+ CT const tan_lat2 = sin_lat2/cos_lat2;
+ CT const M = cos_lat1*tan_lat2-sin_lat1*cos_dlon;
+ A = atan2(sin_dlon, M);
+ CT const sin_2A = sin(CT(2)*A);
+ U = (f/CT(2))*math::sqr(cos_lat1)*sin_2A;
+ }
+
+ CT V = CT(0);
+ if ( ! math::equals(cos_lat1, CT(0)) )
+ {
+ CT const tan_lat1 = sin_lat1/cos_lat1;
+ CT const N = cos_lat2*tan_lat1-sin_lat2*cos_dlon;
+ CT const B = atan2(sin_dlon, N);
+ CT const sin_2B = sin(CT(2)*B);
+ V = (f/CT(2))*math::sqr(cos_lat2)*sin_2B;
+ }
+
+ // infinity if sin_d = 0, so cos_d = 1 or cos_d = -1
+ CT const T = d / sin_d;
+ CT const dA = V*T-U;
+
+ result.azimuth = A - dA;
+ }
+ else
+ {
+ result.azimuth = CT(0);
+ }
+
+ return result;
+ }
+};
+
+}}} // namespace boost::geometry::detail
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ANDOYER_INVERSE_HPP
diff --git a/boost/geometry/algorithms/detail/azimuth.hpp b/boost/geometry/algorithms/detail/azimuth.hpp
index 7810b4814e..f0a8d65c86 100644
--- a/boost/geometry/algorithms/detail/azimuth.hpp
+++ b/boost/geometry/algorithms/detail/azimuth.hpp
@@ -49,10 +49,10 @@ struct azimuth<ReturnType, geographic_tag>
template <typename P1, typename P2, typename Spheroid>
static inline ReturnType apply(P1 const& p1, P2 const& p2, Spheroid const& spheroid)
{
- return geometry::detail::vincenty_inverse<ReturnType>
+ return geometry::detail::vincenty_inverse<ReturnType, false, true>
( get_as_radian<0>(p1), get_as_radian<1>(p1),
get_as_radian<0>(p2), get_as_radian<1>(p2),
- spheroid ).azimuth12();
+ spheroid ).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 127e4c3fb2..b25bcc7fb5 100644
--- a/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp
+++ b/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp
@@ -12,11 +12,12 @@
#include <cstddef>
#include <iterator>
+
#include <boost/core/ignore_unused.hpp>
#include <boost/numeric/conversion/cast.hpp>
-
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
@@ -227,7 +228,7 @@ struct buffer_range
typename EndStrategy,
typename RobustPolicy
>
- static inline bool iterate(Collection& collection,
+ static inline strategy::buffer::result_code iterate(Collection& collection,
Iterator begin, Iterator end,
strategy::buffer::buffer_side_selector side,
DistanceStrategy const& distance_strategy,
@@ -266,7 +267,7 @@ struct buffer_range
* pup: penultimate_point
*/
- bool result = false;
+ strategy::buffer::result_code result = strategy::buffer::result_no_output;
bool first = true;
Iterator it = begin;
@@ -277,18 +278,25 @@ struct buffer_range
for (Iterator prev = it++; it != end; ++it)
{
generated_side.clear();
- side_strategy.apply(*prev, *it, side,
+ strategy::buffer::result_code error_code
+ = side_strategy.apply(*prev, *it, side,
distance_strategy, generated_side);
- if (generated_side.empty())
+ if (error_code == strategy::buffer::result_no_output)
{
// Because input is simplified, this is improbable,
// but it can happen for degenerate geometries
// Further handling of this side is skipped
continue;
}
+ else if (error_code == strategy::buffer::result_error_numerical)
+ {
+ return error_code;
+ }
+
+ BOOST_GEOMETRY_ASSERT(! generated_side.empty());
- result = true;
+ result = strategy::buffer::result_normal;
if (! first)
{
@@ -383,6 +391,7 @@ inline void buffer_point(Point const& point, Collection& collection,
std::vector<OutputPointType> range_out;
point_strategy.apply(point, distance_strategy, range_out);
collection.add_piece(strategy::buffer::buffered_point, range_out, false);
+ collection.set_piece_center(point);
collection.finish_ring();
}
@@ -458,7 +467,7 @@ struct buffer_inserter<ring_tag, RingInput, RingOutput>
typename EndStrategy,
typename RobustPolicy
>
- static inline bool iterate(Collection& collection,
+ static inline strategy::buffer::result_code iterate(Collection& collection,
Iterator begin, Iterator end,
strategy::buffer::buffer_side_selector side,
DistanceStrategy const& distance_strategy,
@@ -471,13 +480,14 @@ struct buffer_inserter<ring_tag, RingInput, RingOutput>
typedef detail::buffer::buffer_range<RingOutput> buffer_range;
- bool result = buffer_range::iterate(collection, begin, end,
+ strategy::buffer::result_code result
+ = buffer_range::iterate(collection, begin, end,
side,
distance_strategy, side_strategy, join_strategy, end_strategy, robust_policy,
first_p1, first_p2, last_p1, last_p2);
// Generate closing join
- if (result)
+ if (result == strategy::buffer::result_normal)
{
buffer_range::add_join(collection,
*(end - 2),
@@ -502,7 +512,7 @@ struct buffer_inserter<ring_tag, RingInput, RingOutput>
typename PointStrategy,
typename RobustPolicy
>
- static inline void apply(RingInput const& ring,
+ static inline strategy::buffer::result_code apply(RingInput const& ring,
Collection& collection,
DistanceStrategy const& distance,
SideStrategy const& side_strategy,
@@ -514,7 +524,7 @@ struct buffer_inserter<ring_tag, RingInput, RingOutput>
RingInput simplified;
detail::buffer::simplify_input(ring, distance, simplified);
- bool has_output = false;
+ strategy::buffer::result_code code = strategy::buffer::result_no_output;
std::size_t n = boost::size(simplified);
std::size_t const min_points = core_detail::closure::minimum_ring_size
@@ -528,21 +538,19 @@ struct buffer_inserter<ring_tag, RingInput, RingOutput>
if (distance.negative())
{
// Walk backwards (rings will be reversed afterwards)
- // It might be that this will be changed later.
- // TODO: decide this.
- has_output = iterate(collection, boost::rbegin(view), boost::rend(view),
+ code = iterate(collection, boost::rbegin(view), boost::rend(view),
strategy::buffer::buffer_side_right,
distance, side_strategy, join_strategy, end_strategy, robust_policy);
}
else
{
- has_output = iterate(collection, boost::begin(view), boost::end(view),
+ code = iterate(collection, boost::begin(view), boost::end(view),
strategy::buffer::buffer_side_left,
distance, side_strategy, join_strategy, end_strategy, robust_policy);
}
}
- if (! has_output && n >= 1)
+ if (code == strategy::buffer::result_no_output && n >= 1)
{
// Use point_strategy to buffer degenerated ring
detail::buffer::buffer_point<output_point_type>
@@ -551,6 +559,7 @@ struct buffer_inserter<ring_tag, RingInput, RingOutput>
collection, distance, point_strategy
);
}
+ return code;
}
};
@@ -576,7 +585,7 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
typename EndStrategy,
typename RobustPolicy
>
- static inline bool iterate(Collection& collection,
+ static inline strategy::buffer::result_code iterate(Collection& collection,
Iterator begin, Iterator end,
strategy::buffer::buffer_side_selector side,
DistanceStrategy const& distance_strategy,
@@ -601,27 +610,33 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
else
{
std::vector<output_point_type> generated_side;
- side_strategy.apply(ultimate_point, penultimate_point,
+ strategy::buffer::result_code code
+ = side_strategy.apply(ultimate_point, penultimate_point,
strategy::buffer::buffer_side_right,
distance_strategy, generated_side);
- if (generated_side.empty())
+ if (code != strategy::buffer::result_normal)
{
- return false;
+ // No output or numerical error
+ return code;
}
reverse_p1 = generated_side.front();
}
output_point_type first_p2, last_p1, last_p2;
- detail::buffer::buffer_range<output_ring_type>::iterate(collection,
+ strategy::buffer::result_code result
+ = detail::buffer::buffer_range<output_ring_type>::iterate(collection,
begin, end, side,
distance_strategy, side_strategy, join_strategy, end_strategy, robust_policy,
first_p1, first_p2, last_p1, last_p2);
- std::vector<output_point_type> range_out;
- end_strategy.apply(penultimate_point, last_p2, ultimate_point, reverse_p1, side, distance_strategy, range_out);
- collection.add_endcap(end_strategy, range_out, ultimate_point);
- return true;
+ if (result == strategy::buffer::result_normal)
+ {
+ std::vector<output_point_type> range_out;
+ end_strategy.apply(penultimate_point, last_p2, ultimate_point, reverse_p1, side, distance_strategy, range_out);
+ collection.add_endcap(end_strategy, range_out, ultimate_point);
+ }
+ return result;
}
template
@@ -634,7 +649,7 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
typename PointStrategy,
typename RobustPolicy
>
- static inline void apply(Linestring const& linestring, Collection& collection,
+ static inline strategy::buffer::result_code apply(Linestring const& linestring, Collection& collection,
DistanceStrategy const& distance,
SideStrategy const& side_strategy,
JoinStrategy const& join_strategy,
@@ -645,28 +660,29 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
Linestring simplified;
detail::buffer::simplify_input(linestring, distance, simplified);
- bool has_output = false;
+ strategy::buffer::result_code code = strategy::buffer::result_no_output;
std::size_t n = boost::size(simplified);
if (n > 1)
{
collection.start_new_ring();
output_point_type first_p1;
- has_output = iterate(collection,
+ code = iterate(collection,
boost::begin(simplified), boost::end(simplified),
strategy::buffer::buffer_side_left,
distance, side_strategy, join_strategy, end_strategy, robust_policy,
first_p1);
- if (has_output)
+ if (code == strategy::buffer::result_normal)
{
- iterate(collection, boost::rbegin(simplified), boost::rend(simplified),
+ code = iterate(collection,
+ boost::rbegin(simplified), boost::rend(simplified),
strategy::buffer::buffer_side_right,
distance, side_strategy, join_strategy, end_strategy, robust_policy,
first_p1);
}
collection.finish_ring();
}
- if (! has_output && n >= 1)
+ if (code == strategy::buffer::result_no_output && n >= 1)
{
// Use point_strategy to buffer degenerated linestring
detail::buffer::buffer_point<output_point_type>
@@ -675,6 +691,7 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
collection, distance, point_strategy
);
}
+ return code;
}
};
@@ -718,9 +735,16 @@ private:
for (Iterator it = begin; it != end; ++it)
{
collection.start_new_ring();
- policy::apply(*it, collection, distance, side_strategy,
+ strategy::buffer::result_code const code
+ = policy::apply(*it, collection, distance, side_strategy,
join_strategy, end_strategy, point_strategy,
robust_policy);
+
+ if (code == strategy::buffer::result_error_numerical)
+ {
+ collection.abort_ring();
+ return;
+ }
collection.finish_ring(is_interior);
}
}
@@ -774,11 +798,21 @@ public:
{
{
collection.start_new_ring();
- policy::apply(exterior_ring(polygon), collection,
+
+ strategy::buffer::result_code const code
+ = policy::apply(exterior_ring(polygon), collection,
distance, side_strategy,
join_strategy, end_strategy, point_strategy,
robust_policy);
- collection.finish_ring(false, geometry::num_interior_rings(polygon) > 0u);
+
+ if (code == strategy::buffer::result_error_numerical)
+ {
+ collection.abort_ring();
+ }
+ else
+ {
+ collection.finish_ring(false, geometry::num_interior_rings(polygon) > 0u);
+ }
}
apply_interior_rings(interior_rings(polygon),
@@ -910,7 +944,7 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
collection.reverse();
}
- if (distance_strategy.negative() && areal)
+ if (BOOST_GEOMETRY_CONDITION(distance_strategy.negative() && areal))
{
collection.discard_nonintersecting_deflated_rings();
}
diff --git a/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp b/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp
index c5bb8acc05..255ac797dc 100644
--- a/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp
+++ b/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp
@@ -9,6 +9,9 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFER_POLICIES_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFER_POLICIES_HPP
+#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
+# define BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION
+#endif
#include <cstddef>
@@ -81,8 +84,8 @@ template <typename Point, typename SegmentRatio>
struct buffer_turn_operation
: public detail::overlay::traversal_turn_operation<Point, SegmentRatio>
{
- int piece_index;
- int index_in_robust_ring;
+ signed_size_type piece_index;
+ signed_size_type index_in_robust_ring;
inline buffer_turn_operation()
: piece_index(-1)
@@ -103,7 +106,7 @@ struct buffer_turn_info
typedef Point point_type;
typedef RobustPoint robust_point_type;
- int turn_index; // TODO: this might go if partition can operate on non-const input
+ std::size_t turn_index; // TODO: this might go if partition can operate on non-const input
RobustPoint robust_point;
#if defined(BOOST_GEOMETRY_BUFFER_ENLARGED_CLUSTERS)
@@ -122,24 +125,30 @@ struct buffer_turn_info
intersection_location_type location;
- int count_within;
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ robust_point_type rob_pi, rob_pj, rob_qi, rob_qj;
+#endif
+
+ std::size_t count_within;
bool within_original;
- int count_on_original_boundary;
- int count_in_original; // increased by +1 for in ext.ring, -1 for int.ring
+ std::size_t count_on_original_boundary;
+ signed_size_type count_in_original; // increased by +1 for in ext.ring, -1 for int.ring
- int count_on_offsetted;
- int count_on_helper;
- int count_within_near_offsetted;
+ std::size_t count_on_offsetted;
+ std::size_t count_on_helper;
+#if ! defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ std::size_t count_within_near_offsetted;
+#endif
bool remove_on_multi;
// Obsolete:
- int count_on_occupied;
- int count_on_multi;
+ std::size_t count_on_occupied;
+ std::size_t count_on_multi;
inline buffer_turn_info()
- : turn_index(-1)
+ : turn_index(0)
, location(location_ok)
, count_within(0)
, within_original(false)
@@ -147,7 +156,9 @@ struct buffer_turn_info
, count_in_original(0)
, count_on_offsetted(0)
, count_on_helper(0)
+#if ! defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
, count_within_near_offsetted(0)
+#endif
, remove_on_multi(false)
, count_on_occupied(0)
, count_on_multi(0)
diff --git a/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp b/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp
index a501e3f197..545d89cb9b 100644
--- a/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp
+++ b/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp
@@ -16,11 +16,14 @@
#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/algorithms/comparable_distance.hpp>
#include <boost/geometry/algorithms/covered_by.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
+#include <boost/geometry/algorithms/is_convex.hpp>
#include <boost/geometry/strategies/buffer.hpp>
@@ -126,6 +129,11 @@ struct buffered_piece_collection
typedef geometry::model::ring<robust_point_type> robust_ring_type;
typedef geometry::model::box<robust_point_type> robust_box_type;
+ typedef typename default_comparable_distance_result
+ <
+ robust_point_type
+ >::type robust_comparable_radius_type;
+
typedef typename strategy::side::services::default_strategy
<
typename cs_tag<point_type>::type
@@ -159,7 +167,7 @@ struct buffered_piece_collection
struct robust_turn
{
- int turn_index;
+ std::size_t turn_index;
int operation_index;
robust_point_type point;
segment_identifier seg_id;
@@ -172,10 +180,10 @@ struct buffered_piece_collection
typedef geometry::section<robust_box_type, 1> section_type;
strategy::buffer::piece_type type;
- int index;
+ signed_size_type index;
- int left_index; // points to previous piece of same ring
- int right_index; // points to next piece of same ring
+ signed_size_type left_index; // points to previous piece of same ring
+ signed_size_type right_index; // points to next piece of same ring
// The next two members (1, 2) form together a complete clockwise ring
// for each piece (with one dupped point)
@@ -183,21 +191,21 @@ struct buffered_piece_collection
// 1: half, part of offsetted_rings
segment_identifier first_seg_id;
- int last_segment_index; // no segment-identifier - it is the same as first_seg_id
- int offsetted_count; // part in robust_ring which is part of offsetted ring
+ signed_size_type last_segment_index; // no segment-identifier - it is the same as first_seg_id
+ signed_size_type offsetted_count; // part in robust_ring which is part of offsetted ring
#if defined(BOOST_GEOMETRY_BUFFER_USE_HELPER_POINTS)
// 2: half, not part of offsetted rings - part of robust ring
std::vector<point_type> helper_points; // 4 points for side, 3 points for join - 0 points for flat-end
#endif
+ bool is_convex;
bool is_monotonic_increasing[2]; // 0=x, 1=y
bool is_monotonic_decreasing[2]; // 0=x, 1=y
// Monotonic sections of pieces around points
std::vector<section_type> sections;
-
// Robust representations
// 3: complete ring
robust_ring_type robust_ring;
@@ -206,6 +214,27 @@ struct buffered_piece_collection
robust_box_type robust_offsetted_envelope;
std::vector<robust_turn> robust_turns; // Used only in insert_rescaled_piece_turns - we might use a map instead
+
+ robust_point_type robust_center;
+ robust_comparable_radius_type robust_min_comparable_radius;
+ robust_comparable_radius_type robust_max_comparable_radius;
+
+ piece()
+ : type(strategy::buffer::piece_type_unknown)
+ , index(-1)
+ , left_index(-1)
+ , right_index(-1)
+ , last_segment_index(-1)
+ , offsetted_count(-1)
+ , is_convex(false)
+ , robust_min_comparable_radius(0)
+ , robust_max_comparable_radius(0)
+ {
+ is_monotonic_increasing[0] = false;
+ is_monotonic_increasing[1] = false;
+ is_monotonic_decreasing[0] = false;
+ is_monotonic_decreasing[1] = false;
+ }
};
struct robust_original
@@ -244,7 +273,7 @@ struct buffered_piece_collection
piece_vector_type m_pieces;
turn_vector_type m_turns;
- int m_first_piece_index;
+ signed_size_type m_first_piece_index;
buffered_ring_collection<buffered_ring<Ring> > offsetted_rings; // indexed by multi_index
std::vector<robust_original> robust_originals; // robust representation of the original(s)
@@ -444,6 +473,7 @@ struct buffered_piece_collection
{
it->location = inside_buffer;
}
+#if ! defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
if (it->count_within_near_offsetted > 0)
{
// Within can have in rare cases a rounding issue. We don't discard this
@@ -451,6 +481,7 @@ struct buffered_piece_collection
// will never start a new ring from this type of points.
it->selectable_start = false;
}
+#endif
}
}
@@ -515,7 +546,7 @@ struct buffered_piece_collection
{
// Add rescaled turn points to corresponding pieces
// (after this, each turn occurs twice)
- int index = 0;
+ std::size_t index = 0;
for (typename boost::range_iterator<turn_vector_type>::type it =
boost::begin(m_turns); it != boost::end(m_turns); ++it, ++index)
{
@@ -544,16 +575,16 @@ struct buffered_piece_collection
}
}
+#if ! defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
// Insert all rescaled turn-points into these rings, to form a
// reliable integer-based ring. All turns can be compared (inside) to this
// rings to see if they are inside.
- for (typename piece_vector_type::iterator it = boost::begin(m_pieces);
- it != boost::end(m_pieces);
- ++it)
+ for (typename boost::range_iterator<piece_vector_type>::type
+ it = boost::begin(m_pieces); it != boost::end(m_pieces); ++it)
{
piece& pc = *it;
- int piece_segment_index = pc.first_seg_id.segment_index;
+ signed_size_type piece_segment_index = pc.first_seg_id.segment_index;
if (! pc.robust_turns.empty())
{
if (pc.robust_turns.size() > 1u)
@@ -561,14 +592,14 @@ struct buffered_piece_collection
std::sort(pc.robust_turns.begin(), pc.robust_turns.end(), buffer_operation_less());
}
// Walk through them, in reverse to insert at right index
- int index_offset = pc.robust_turns.size() - 1;
- for (typename std::vector<robust_turn>::const_reverse_iterator
- rit = pc.robust_turns.rbegin();
- rit != pc.robust_turns.rend();
+ signed_size_type index_offset = static_cast<signed_size_type>(pc.robust_turns.size()) - 1;
+ for (typename boost::range_reverse_iterator<const std::vector<robust_turn> >::type
+ rit = boost::const_rbegin(pc.robust_turns);
+ rit != boost::const_rend(pc.robust_turns);
++rit, --index_offset)
{
- int const index_in_vector = 1 + rit->seg_id.segment_index - piece_segment_index;
- BOOST_ASSERT
+ signed_size_type const index_in_vector = 1 + rit->seg_id.segment_index - piece_segment_index;
+ BOOST_GEOMETRY_ASSERT
(
index_in_vector > 0
&& index_in_vector < pc.offsetted_count
@@ -582,7 +613,8 @@ struct buffered_piece_collection
}
}
- BOOST_ASSERT(assert_indices_in_robust_rings());
+ BOOST_GEOMETRY_ASSERT(assert_indices_in_robust_rings());
+#endif
}
template <std::size_t Dimension>
@@ -607,6 +639,8 @@ struct buffered_piece_collection
pc.is_monotonic_decreasing[0] = true;
pc.is_monotonic_decreasing[1] = true;
+ pc.is_convex = geometry::is_convex(pc.robust_ring);
+
if (pc.offsetted_count < 2)
{
return;
@@ -615,14 +649,13 @@ struct buffered_piece_collection
typename robust_ring_type::const_iterator current = pc.robust_ring.begin();
typename robust_ring_type::const_iterator next = current + 1;
- for (int i = 1; i < pc.offsetted_count; i++)
+ for (signed_size_type i = 1; i < pc.offsetted_count; i++)
{
determine_monotonicity<0>(pc, *current, *next);
determine_monotonicity<1>(pc, *current, *next);
current = next;
++next;
}
-
}
void determine_properties()
@@ -659,7 +692,31 @@ struct buffered_piece_collection
geometry::sectionalize<false, dimensions>(pc.robust_ring,
detail::no_rescale_policy(), pc.sections);
- // TODO (next phase) determine min/max radius
+ // Determine min/max radius
+ typedef geometry::model::referring_segment<robust_point_type const>
+ robust_segment_type;
+
+ typename robust_ring_type::const_iterator current = pc.robust_ring.begin();
+ typename robust_ring_type::const_iterator next = current + 1;
+
+ for (signed_size_type i = 1; i < pc.offsetted_count; i++)
+ {
+ robust_segment_type s(*current, *next);
+ robust_comparable_radius_type const d
+ = geometry::comparable_distance(pc.robust_center, s);
+
+ if (i == 1 || d < pc.robust_min_comparable_radius)
+ {
+ pc.robust_min_comparable_radius = d;
+ }
+ if (i == 1 || d > pc.robust_max_comparable_radius)
+ {
+ pc.robust_max_comparable_radius = d;
+ }
+
+ current = next;
+ ++next;
+ }
}
inline void prepare_buffered_point_pieces()
@@ -730,7 +787,7 @@ struct buffered_piece_collection
inline void start_new_ring()
{
- int const n = offsetted_rings.size();
+ signed_size_type const n = static_cast<signed_size_type>(offsetted_rings.size());
current_segment_id.source_index = 0;
current_segment_id.multi_index = n;
current_segment_id.ring_index = -1;
@@ -739,12 +796,35 @@ struct buffered_piece_collection
offsetted_rings.resize(n + 1);
current_robust_ring.clear();
- m_first_piece_index = boost::size(m_pieces);
+ m_first_piece_index = static_cast<signed_size_type>(boost::size(m_pieces));
+ }
+
+ inline void abort_ring()
+ {
+ // Remove all created pieces for this ring, sections, last offsetted
+ while (! m_pieces.empty()
+ && m_pieces.back().first_seg_id.multi_index
+ == current_segment_id.multi_index)
+ {
+ m_pieces.erase(m_pieces.end() - 1);
+ }
+
+ while (! monotonic_sections.empty()
+ && monotonic_sections.back().ring_id.multi_index
+ == current_segment_id.multi_index)
+ {
+ monotonic_sections.erase(monotonic_sections.end() - 1);
+ }
+
+ offsetted_rings.erase(offsetted_rings.end() - 1);
+ current_robust_ring.clear();
+
+ m_first_piece_index = -1;
}
inline void update_closing_point()
{
- BOOST_ASSERT(! offsetted_rings.empty());
+ BOOST_GEOMETRY_ASSERT(! offsetted_rings.empty());
buffered_ring<Ring>& added = offsetted_rings.back();
if (! boost::empty(added))
{
@@ -764,7 +844,7 @@ struct buffered_piece_collection
// For now, it is made equal because due to numerical instability,
// it can be a tiny bit off, possibly causing a self-intersection
- BOOST_ASSERT(boost::size(m_pieces) > 0);
+ BOOST_GEOMETRY_ASSERT(boost::size(m_pieces) > 0);
if (! ring.empty()
&& current_segment_id.segment_index
== m_pieces.back().first_seg_id.segment_index)
@@ -773,6 +853,13 @@ struct buffered_piece_collection
}
}
+ inline void set_piece_center(point_type const& center)
+ {
+ BOOST_GEOMETRY_ASSERT(! m_pieces.empty());
+ geometry::recalculate(m_pieces.back().robust_center, center,
+ m_robust_policy);
+ }
+
inline void finish_ring(bool is_interior = false, bool has_interiors = false)
{
if (m_first_piece_index == -1)
@@ -780,12 +867,12 @@ struct buffered_piece_collection
return;
}
- if (m_first_piece_index < static_cast<int>(boost::size(m_pieces)))
+ if (m_first_piece_index < static_cast<signed_size_type>(boost::size(m_pieces)))
{
// If piece was added
// Reassign left-of-first and right-of-last
geometry::range::at(m_pieces, m_first_piece_index).left_index
- = boost::size(m_pieces) - 1;
+ = static_cast<signed_size_type>(boost::size(m_pieces)) - 1;
geometry::range::back(m_pieces).right_index = m_first_piece_index;
}
m_first_piece_index = -1;
@@ -794,7 +881,7 @@ struct buffered_piece_collection
if (! current_robust_ring.empty())
{
- BOOST_ASSERT
+ BOOST_GEOMETRY_ASSERT
(
geometry::equals(current_robust_ring.front(),
current_robust_ring.back())
@@ -808,20 +895,20 @@ struct buffered_piece_collection
inline void set_current_ring_concave()
{
- BOOST_ASSERT(boost::size(offsetted_rings) > 0);
+ BOOST_GEOMETRY_ASSERT(boost::size(offsetted_rings) > 0);
offsetted_rings.back().has_concave = true;
}
- inline int add_point(point_type const& p)
+ inline signed_size_type add_point(point_type const& p)
{
- BOOST_ASSERT(boost::size(offsetted_rings) > 0);
+ BOOST_GEOMETRY_ASSERT(boost::size(offsetted_rings) > 0);
buffered_ring<Ring>& current_ring = offsetted_rings.back();
update_last_point(p, current_ring);
current_segment_id.segment_index++;
current_ring.push_back(p);
- return current_ring.size();
+ return static_cast<signed_size_type>(current_ring.size());
}
//-------------------------------------------------------------------------
@@ -836,7 +923,7 @@ struct buffered_piece_collection
piece pc;
pc.type = type;
- pc.index = boost::size(m_pieces);
+ pc.index = static_cast<signed_size_type>(boost::size(m_pieces));
pc.first_seg_id = current_segment_id;
// Assign left/right (for first/last piece per ring they will be re-assigned later)
@@ -862,11 +949,11 @@ struct buffered_piece_collection
return;
}
- BOOST_ASSERT(pc.first_seg_id.multi_index >= 0);
- BOOST_ASSERT(pc.last_segment_index >= 0);
+ BOOST_GEOMETRY_ASSERT(pc.first_seg_id.multi_index >= 0);
+ BOOST_GEOMETRY_ASSERT(pc.last_segment_index >= 0);
pc.offsetted_count = pc.last_segment_index - pc.first_seg_id.segment_index;
- BOOST_ASSERT(pc.offsetted_count >= 0);
+ BOOST_GEOMETRY_ASSERT(pc.offsetted_count >= 0);
pc.robust_ring.reserve(pc.offsetted_count + helper_points_size);
@@ -915,11 +1002,10 @@ struct buffered_piece_collection
return;
}
- geometry::detail::envelope::envelope_range::apply(pc.robust_ring,
- pc.robust_envelope);
+ geometry::envelope(pc.robust_ring, pc.robust_envelope);
geometry::assign_inverse(pc.robust_offsetted_envelope);
- for (int i = 0; i < pc.offsetted_count; i++)
+ for (signed_size_type i = 0; i < pc.offsetted_count; i++)
{
geometry::expand(pc.robust_offsetted_envelope, pc.robust_ring[i]);
}
@@ -1010,7 +1096,7 @@ struct buffered_piece_collection
template <typename Range>
inline void add_range_to_piece(piece& pc, Range const& range, bool add_front)
{
- BOOST_ASSERT(boost::size(range) != 0u);
+ BOOST_GEOMETRY_ASSERT(boost::size(range) != 0u);
typename Range::const_iterator it = boost::begin(range);
@@ -1046,7 +1132,7 @@ struct buffered_piece_collection
inline void add_side_piece(point_type const& p1, point_type const& p2,
Range const& range, bool first)
{
- BOOST_ASSERT(boost::size(range) >= 2u);
+ BOOST_GEOMETRY_ASSERT(boost::size(range) >= 2u);
piece& pc = create_piece(strategy::buffer::buffered_segment, ! first);
add_range_to_piece(pc, range, first);
@@ -1133,7 +1219,7 @@ struct buffered_piece_collection
robust_point_type any_point;
geometry::recalculate(any_point, point, m_robust_policy);
- int count_in_original = 0;
+ signed_size_type count_in_original = 0;
// Check of the robust point of this outputted ring is in
// any of the robust original rings
@@ -1279,7 +1365,7 @@ struct buffered_piece_collection
// Inner rings, for deflate, which do not have intersections, and
// which are outside originals, are skipped
// (other ones should be traversed)
- int index = 0;
+ signed_size_type index = 0;
for(typename buffered_ring_collection<buffered_ring<Ring> >::const_iterator it = boost::begin(offsetted_rings);
it != boost::end(offsetted_rings);
++it, ++index)
@@ -1287,8 +1373,12 @@ struct buffered_piece_collection
if (! it->has_intersections()
&& ! it->is_untouched_outside_original)
{
- ring_identifier id(0, index, -1);
- selected[id] = properties(*it);
+ properties p = properties(*it);
+ if (p.valid)
+ {
+ ring_identifier id(0, index, -1);
+ selected[id] = p;
+ }
}
}
@@ -1299,8 +1389,12 @@ struct buffered_piece_collection
it != boost::end(traversed_rings);
++it, ++index)
{
- ring_identifier id(2, index, -1);
- selected[id] = properties(*it);
+ properties p = properties(*it);
+ if (p.valid)
+ {
+ ring_identifier id(2, index, -1);
+ selected[id] = p;
+ }
}
detail::overlay::assign_parents(offsetted_rings, traversed_rings, selected, true);
diff --git a/boost/geometry/algorithms/detail/buffer/buffered_ring.hpp b/boost/geometry/algorithms/detail/buffer/buffered_ring.hpp
index 9ea8bc1e85..19c91544ac 100644
--- a/boost/geometry/algorithms/detail/buffer/buffered_ring.hpp
+++ b/boost/geometry/algorithms/detail/buffer/buffered_ring.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -14,11 +14,14 @@
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/strategies/buffer.hpp>
+#include <boost/geometry/algorithms/within.hpp>
+
#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
#include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
#include <boost/geometry/algorithms/detail/overlay/enrichment_info.hpp>
@@ -26,8 +29,6 @@
#include <boost/geometry/algorithms/detail/overlay/traversal_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
-#include <boost/geometry/multi/algorithms/within.hpp>
-
namespace boost { namespace geometry
{
@@ -225,7 +226,7 @@ struct get_ring<detail::buffer::buffered_ring_collection_tag>
ring_identifier const& id,
MultiGeometry const& multi_ring)
{
- BOOST_ASSERT
+ BOOST_GEOMETRY_ASSERT
(
id.multi_index >= 0
&& id.multi_index < int(boost::size(multi_ring))
diff --git a/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp b/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp
index 6a3daa282e..3425ee6ffd 100644
--- a/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp
+++ b/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp
@@ -17,6 +17,7 @@
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
#include <boost/geometry/algorithms/detail/sections/section_functions.hpp>
+#include <boost/geometry/algorithms/detail/buffer/buffer_policies.hpp>
namespace boost { namespace geometry
@@ -28,6 +29,34 @@ namespace detail { namespace buffer
{
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+struct buffer_assign_turn
+{
+ static bool const include_no_turn = false;
+ static bool const include_degenerate = false;
+ static bool const include_opposite = false;
+
+ template
+ <
+ typename Info,
+ typename Point1,
+ typename Point2,
+ typename IntersectionInfo
+ >
+ static inline void apply(Info& info,
+ Point1 const& /*p1*/,
+ Point2 const& /*p2*/,
+ IntersectionInfo const& iinfo)
+ {
+ info.rob_pi = iinfo.rpi();
+ info.rob_pj = iinfo.rpj();
+ info.rob_qi = iinfo.rqi();
+ info.rob_qj = iinfo.rqj();
+ }
+
+};
+#endif
+
template
<
typename Pieces,
@@ -91,7 +120,7 @@ class piece_turn_visitor
template <std::size_t Dimension, typename Iterator, typename Box>
inline void move_begin_iterator(Iterator& it_begin, Iterator it_beyond,
- int& index, int dir, Box const& other_bounding_box)
+ signed_size_type& index, int dir, Box const& other_bounding_box)
{
for(; it_begin != it_beyond
&& it_begin + 1 != it_beyond
@@ -129,20 +158,20 @@ class piece_turn_visitor
typedef typename boost::range_value<Turns const>::type turn_type;
typedef typename boost::range_iterator<ring_type const>::type iterator;
- int const piece1_first_index = piece1.first_seg_id.segment_index;
- int const piece2_first_index = piece2.first_seg_id.segment_index;
+ signed_size_type const piece1_first_index = piece1.first_seg_id.segment_index;
+ signed_size_type const piece2_first_index = piece2.first_seg_id.segment_index;
if (piece1_first_index < 0 || piece2_first_index < 0)
{
return;
}
// Get indices of part of offsetted_rings for this monotonic section:
- int const sec1_first_index = piece1_first_index + section1.begin_index;
- int const sec2_first_index = piece2_first_index + section2.begin_index;
+ signed_size_type const sec1_first_index = piece1_first_index + section1.begin_index;
+ signed_size_type const sec2_first_index = piece2_first_index + section2.begin_index;
// index of last point in section, beyond-end is one further
- int const sec1_last_index = piece1_first_index + section1.end_index;
- int const sec2_last_index = piece2_first_index + section2.end_index;
+ signed_size_type const sec1_last_index = piece1_first_index + section1.end_index;
+ signed_size_type const sec2_last_index = piece2_first_index + section2.end_index;
// get geometry and iterators over these sections
ring_type const& ring1 = m_rings[piece1.first_seg_id.multi_index];
@@ -154,7 +183,7 @@ class piece_turn_visitor
iterator it2_beyond = boost::begin(ring2) + sec2_last_index + 1;
// Set begin/end of monotonic ranges, in both x/y directions
- int index1 = sec1_first_index;
+ signed_size_type index1 = sec1_first_index;
move_begin_iterator<0>(it1_first, it1_beyond, index1,
section1.directions[0], section2.bounding_box);
move_end_iterator<0>(it1_first, it1_beyond,
@@ -164,7 +193,7 @@ class piece_turn_visitor
move_end_iterator<1>(it1_first, it1_beyond,
section1.directions[1], section2.bounding_box);
- int index2 = sec2_first_index;
+ signed_size_type index2 = sec2_first_index;
move_begin_iterator<0>(it2_first, it2_beyond, index2,
section2.directions[0], section1.bounding_box);
move_end_iterator<0>(it2_first, it2_beyond,
@@ -204,7 +233,11 @@ class piece_turn_visitor
// and iterating in sync with them...
typedef detail::overlay::get_turn_info
<
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ buffer_assign_turn
+#else
detail::overlay::assign_null_policy
+#endif
> turn_policy;
turn_policy::apply(*prev1, *it1, *next1,
diff --git a/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp b/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp
index 8803efdec9..0aca21ce88 100644
--- a/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp
+++ b/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp
@@ -14,6 +14,8 @@
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
+
#include <boost/geometry/arithmetic/dot_product.hpp>
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/comparable_distance.hpp>
@@ -25,6 +27,11 @@
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
#include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/strategies/buffer.hpp>
+#include <boost/geometry/algorithms/detail/buffer/buffer_policies.hpp>
+
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+#include <boost/geometry/strategies/cartesian/side_of_intersection.hpp>
+#endif
namespace boost { namespace geometry
@@ -89,8 +96,10 @@ enum analyse_result
analyse_disjoint,
analyse_within,
analyse_on_original_boundary,
- analyse_on_offsetted,
- analyse_near_offsetted
+ analyse_on_offsetted
+#if ! defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ , analyse_near_offsetted
+#endif
};
template <typename Point>
@@ -112,6 +121,31 @@ inline analyse_result check_segment(Point const& previous,
Point const& current, Turn const& turn,
bool from_monotonic)
{
+
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ typedef geometry::model::referring_segment<Point const> segment_type;
+ segment_type const p(turn.rob_pi, turn.rob_pj);
+ segment_type const q(turn.rob_qi, turn.rob_qj);
+ segment_type const r(previous, current);
+ int const side = strategy::side::side_of_intersection::apply(p, q, r,
+ turn.robust_point);
+
+ if (side == 0)
+ {
+ return analyse_on_offsetted;
+ }
+ if (side == -1 && from_monotonic)
+ {
+ return analyse_within;
+ }
+ if (side == 1 && from_monotonic)
+ {
+ return analyse_disjoint;
+ }
+ return analyse_continue;
+
+#else
+
typedef typename strategy::side::services::default_strategy
<
typename cs_tag<Point>::type
@@ -156,6 +190,7 @@ inline analyse_result check_segment(Point const& previous,
// Not monotonic, on left or right side: continue analysing
return analyse_continue;
+#endif
}
@@ -169,14 +204,22 @@ public :
typedef typename Turn::robust_point_type point_type;
typedef typename geometry::coordinate_type<point_type>::type coordinate_type;
- coordinate_type const point_y = geometry::get<1>(turn.robust_point);
-
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ typedef geometry::model::referring_segment<point_type const> segment_type;
+ segment_type const p(turn.rob_pi, turn.rob_pj);
+ segment_type const q(turn.rob_qi, turn.rob_qj);
+#else
typedef strategy::within::winding<point_type> strategy_type;
typename strategy_type::state_type state;
strategy_type strategy;
boost::ignore_unused(strategy);
-
+#endif
+
+ BOOST_GEOMETRY_ASSERT(! piece.sections.empty());
+
+ coordinate_type const point_y = geometry::get<1>(turn.robust_point);
+
for (std::size_t s = 0; s < piece.sections.size(); s++)
{
section_type const& section = piece.sections[s];
@@ -186,11 +229,43 @@ public :
&& point_y >= geometry::get<min_corner, 1>(section.bounding_box) - 1
&& point_y <= geometry::get<max_corner, 1>(section.bounding_box) + 1)
{
- for (int i = section.begin_index + 1; i <= section.end_index; i++)
+ for (signed_size_type i = section.begin_index + 1; i <= section.end_index; i++)
{
point_type const& previous = piece.robust_ring[i - 1];
point_type const& current = piece.robust_ring[i];
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+
+ // First check if it is in range - if it is not, the
+ // expensive side_of_intersection does not need to be
+ // applied
+ coordinate_type y1 = geometry::get<1>(previous);
+ coordinate_type y2 = geometry::get<1>(current);
+
+ if (y1 > y2)
+ {
+ std::swap(y1, y2);
+ }
+
+ if (point_y >= y1 - 1 && point_y <= y2 + 1)
+ {
+ segment_type const r(previous, current);
+ int const side = strategy::side::side_of_intersection::apply(p, q, r,
+ turn.robust_point);
+
+ // Sections are monotonic in y-dimension
+ if (side == 1)
+ {
+ // Left on segment
+ return analyse_disjoint;
+ }
+ else if (side == 0)
+ {
+ // Collinear - TODO: check if really on segment
+ return analyse_on_offsetted;
+ }
+ }
+#else
analyse_result code = check_segment(previous, current, turn, false);
if (code != analyse_continue)
{
@@ -200,10 +275,15 @@ public :
// Get the state (to determine it is within), we don't have
// to cover the on-segment case (covered above)
strategy.apply(turn.robust_point, previous, current, state);
+#endif
}
}
}
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ // It is nowhere outside, and not on segment, so it is within
+ return analyse_within;
+#else
int const code = strategy.result(state);
if (code == 1)
{
@@ -216,6 +296,7 @@ public :
// Should normally not occur - on-segment is covered
return analyse_unknown;
+#endif
}
};
@@ -228,6 +309,49 @@ class analyse_turn_wrt_piece
bool is_original,
Point const& offsetted)
{
+ boost::ignore_unused(offsetted);
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ typedef geometry::model::referring_segment<Point const> segment_type;
+ segment_type const p(turn.rob_pi, turn.rob_pj);
+ segment_type const q(turn.rob_qi, turn.rob_qj);
+ segment_type const r(s1, s2);
+ int const side = strategy::side::side_of_intersection::apply(p, q, r,
+ turn.robust_point);
+
+ if (side == 1)
+ {
+ // left of segment
+ return analyse_disjoint;
+ }
+ else if (side == 0)
+ {
+ // If is collinear, either on segment or before/after
+ typedef geometry::model::box<Point> box_type;
+
+ box_type box;
+ geometry::assign_inverse(box);
+ geometry::expand(box, s1);
+ geometry::expand(box, s2);
+
+ if (geometry::covered_by(turn.robust_point, box))
+ {
+ // Points on helper-segments are considered as within
+ // Points on original boundary are processed differently
+ return is_original
+ ? analyse_on_original_boundary
+ : analyse_within;
+ }
+
+ // It is collinear but not on the segment. Because these
+ // segments are convex, it is outside
+ // Unless the offsetted ring is collinear or concave w.r.t.
+ // helper-segment but that scenario is not yet supported
+ return analyse_disjoint;
+ }
+
+ // right of segment
+ return analyse_continue;
+#else
typedef typename strategy::side::services::default_strategy
<
typename cs_tag<Point>::type
@@ -276,6 +400,7 @@ class analyse_turn_wrt_piece
// right of segment
return analyse_continue;
+#endif
}
template <typename Turn, typename Piece>
@@ -286,7 +411,8 @@ class analyse_turn_wrt_piece
point_type points[4];
- int helper_count = piece.robust_ring.size() - piece.offsetted_count;
+ signed_size_type helper_count = static_cast<signed_size_type>(piece.robust_ring.size())
+ - piece.offsetted_count;
if (helper_count == 4)
{
for (int i = 0; i < 4; i++)
@@ -436,7 +562,7 @@ public :
// It is small or not monotonic, walk linearly through offset
// TODO: this will be combined with winding strategy
- for (int i = 1; i < piece.offsetted_count; i++)
+ for (signed_size_type i = 1; i < piece.offsetted_count; i++)
{
point_type const& previous = piece.robust_ring[i - 1];
point_type const& current = piece.robust_ring[i];
@@ -492,6 +618,61 @@ class turn_in_piece_visitor
return false;
}
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ // NOTE: this function returns a side value in {-1, 0, 1}
+ template <typename Turn, typename Piece>
+ static inline int turn_in_convex_piece(Turn const& turn,
+ Piece const& piece)
+ {
+ typedef typename Turn::robust_point_type point_type;
+ typedef typename Piece::piece_robust_ring_type ring_type;
+ typedef geometry::model::referring_segment<point_type const> segment;
+
+ segment const p(turn.rob_pi, turn.rob_pj);
+ segment const q(turn.rob_qi, turn.rob_qj);
+
+ typedef typename boost::range_iterator<ring_type const>::type iterator_type;
+ iterator_type it = boost::begin(piece.robust_ring);
+ iterator_type end = boost::end(piece.robust_ring);
+
+ // A robust ring is always closed, and always clockwise
+ for (iterator_type previous = it++; it != end; ++previous, ++it)
+ {
+ geometry::equal_to<point_type> comparator;
+ if (comparator(*previous, *it))
+ {
+ // Points are the same
+ continue;
+ }
+
+ segment r(*previous, *it);
+
+ int const side = strategy::side::side_of_intersection::apply(p, q, r,
+ turn.robust_point);
+
+ if (side == 1)
+ {
+ // IP is left of segment, so it is outside
+ return -1; // outside
+ }
+ else if (side == 0)
+ {
+ // IP is collinear with segment. TODO: we should analyze this further
+ // For now we use the fallback point
+ if (in_box(*previous, *it, turn.robust_point))
+ {
+ return 0;
+ }
+ else
+ {
+ return -1; // outside
+ }
+ }
+ }
+ return 1; // inside
+ }
+#endif
+
public:
@@ -530,12 +711,37 @@ public:
}
// TODO: mutable_piece to make some on-demand preparations in analyse
+ Turn& mutable_turn = m_turns[turn.turn_index];
+
+ if (piece.type == geometry::strategy::buffer::buffered_point)
+ {
+ // Optimization for buffer around points: if distance from center
+ // is not between min/max radius, the result is clear
+ typedef typename default_comparable_distance_result
+ <
+ typename Turn::robust_point_type
+ >::type distance_type;
+
+ distance_type const cd
+ = geometry::comparable_distance(piece.robust_center,
+ turn.robust_point);
+
+ if (cd < piece.robust_min_comparable_radius)
+ {
+ mutable_turn.count_within++;
+ return;
+ }
+ if (cd > piece.robust_max_comparable_radius)
+ {
+ return;
+ }
+ }
+
analyse_result analyse_code =
piece.type == geometry::strategy::buffer::buffered_point
? analyse_turn_wrt_point_piece::apply(turn, piece)
: analyse_turn_wrt_piece::apply(turn, piece);
- Turn& mutable_turn = m_turns[turn.turn_index];
switch(analyse_code)
{
case analyse_disjoint :
@@ -549,16 +755,32 @@ public:
case analyse_within :
mutable_turn.count_within++;
return;
+#if ! defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
case analyse_near_offsetted :
mutable_turn.count_within_near_offsetted++;
return;
+#endif
default :
break;
}
- // TODO: this point_in_geometry is a performance-bottleneck here and
- // will be replaced completely by extending analyse_piece functionality
+#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ // We don't know (yet)
+ int geometry_code = 0;
+ if (piece.is_convex)
+ {
+ geometry_code = turn_in_convex_piece(turn, piece);
+ }
+ else
+ {
+
+ // TODO: this point_in_geometry is a performance-bottleneck here and
+ // will be replaced completely by extending analyse_piece functionality
+ geometry_code = detail::within::point_in_geometry(turn.robust_point, piece.robust_ring);
+ }
+#else
int geometry_code = detail::within::point_in_geometry(turn.robust_point, piece.robust_ring);
+#endif
if (geometry_code == 1)
{
diff --git a/boost/geometry/algorithms/detail/check_iterator_range.hpp b/boost/geometry/algorithms/detail/check_iterator_range.hpp
index 09ea7f79a0..9bd1d7ae27 100644
--- a/boost/geometry/algorithms/detail/check_iterator_range.hpp
+++ b/boost/geometry/algorithms/detail/check_iterator_range.hpp
@@ -33,7 +33,7 @@ struct check_iterator_range
{
for (InputIterator it = first; it != beyond; ++it)
{
- if ( !Predicate::apply(*it) )
+ if (! Predicate::apply(*it))
{
return false;
}
@@ -54,7 +54,7 @@ struct check_iterator_range
for (InputIterator it = first; it != beyond; ++it)
{
- if ( !predicate.apply(*it) )
+ if (! predicate.apply(*it))
{
return false;
}
diff --git a/boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp b/boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp
index 04fa9ee86b..4ac5ac6976 100644
--- a/boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp
+++ b/boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp
@@ -12,8 +12,7 @@
#include <iterator>
-#include <boost/assert.hpp>
-
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/util/math.hpp>
@@ -49,7 +48,7 @@ private:
RangeIterator& it_min,
Distance& dist_min)
{
- BOOST_ASSERT( first != last );
+ BOOST_GEOMETRY_ASSERT( first != last );
Distance const zero = Distance(0);
diff --git a/boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp b/boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp
index 91be6b0ad0..df67890138 100644
--- a/boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp
+++ b/boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp
@@ -12,9 +12,9 @@
#include <utility>
-#include <boost/assert.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/util/math.hpp>
@@ -51,7 +51,7 @@ protected:
iterator_type& it_min2,
Distance& dist_min)
{
- BOOST_ASSERT( first != last );
+ BOOST_GEOMETRY_ASSERT( first != last );
Distance const zero = Distance(0);
@@ -162,7 +162,7 @@ private:
iterator_type& it_min2,
Distance& dist_min)
{
- BOOST_ASSERT( first != last );
+ BOOST_GEOMETRY_ASSERT( first != last );
base_type::apply(point, first, last, strategy,
it_min1, it_min2, dist_min);
diff --git a/boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp b/boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp
index ceba59b41a..26b8684828 100644
--- a/boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp
+++ b/boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp
@@ -15,8 +15,7 @@
#include <iterator>
#include <utility>
-#include <boost/assert.hpp>
-
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/algorithms/dispatch/distance.hpp>
@@ -56,8 +55,8 @@ private:
{
typedef index::rtree<RTreeValueType, index::linear<8> > rtree_type;
- BOOST_ASSERT( rtree_first != rtree_last );
- BOOST_ASSERT( queries_first != queries_last );
+ BOOST_GEOMETRY_ASSERT( rtree_first != rtree_last );
+ BOOST_GEOMETRY_ASSERT( queries_first != queries_last );
Distance const zero = Distance(0);
dist_min = zero;
@@ -73,13 +72,13 @@ private:
{
std::size_t n = rt.query(index::nearest(*qit, 1), &t_v);
- BOOST_ASSERT( n > 0 );
- // n above is unused outside BOOST_ASSERT, hence the call
- // to boost::ignore_unused below
+ BOOST_GEOMETRY_ASSERT( n > 0 );
+ // n above is unused outside BOOST_GEOMETRY_ASSERT,
+ // hence the call to boost::ignore_unused below
//
// however, t_v (initialized by the call to rt.query(...))
// is used below, which is why we cannot put the call to
- // rt.query(...) inside BOOST_ASSERT
+ // rt.query(...) inside BOOST_GEOMETRY_ASSERT
boost::ignore_unused(n);
Distance dist = dispatch::distance
diff --git a/boost/geometry/algorithms/detail/comparable_distance/interface.hpp b/boost/geometry/algorithms/detail/comparable_distance/interface.hpp
index c443a54e58..86eec4c036 100644
--- a/boost/geometry/algorithms/detail/comparable_distance/interface.hpp
+++ b/boost/geometry/algorithms/detail/comparable_distance/interface.hpp
@@ -164,7 +164,7 @@ struct comparable_distance
Geometry2 const& geometry2,
Strategy const& strategy)
{
- return apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
+ return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
}
};
@@ -225,7 +225,7 @@ struct comparable_distance
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
Strategy const& strategy)
{
- return apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
+ return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
}
};
@@ -287,7 +287,7 @@ struct comparable_distance
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
Strategy const& strategy)
{
- return apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
+ return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
}
};
@@ -353,7 +353,7 @@ comparable_distance(Geometry1 const& geometry1, Geometry2 const& geometry2)
concept::check<Geometry1 const>();
concept::check<Geometry2 const>();
- return comparable_distance(geometry1, geometry2, default_strategy());
+ return geometry::comparable_distance(geometry1, geometry2, default_strategy());
}
diff --git a/boost/geometry/algorithms/detail/disjoint/interface.hpp b/boost/geometry/algorithms/detail/disjoint/interface.hpp
index 96d6881296..18c010731e 100644
--- a/boost/geometry/algorithms/detail/disjoint/interface.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/interface.hpp
@@ -175,7 +175,7 @@ struct disjoint<
*/
template <typename Geometry1, typename Geometry2>
inline bool disjoint(Geometry1 const& geometry1,
- Geometry2 const& geometry2)
+ Geometry2 const& geometry2)
{
return resolve_variant::disjoint<Geometry1, Geometry2>::apply(geometry1, geometry2);
}
diff --git a/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp b/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp
index 7d1bb05242..29e438e546 100644
--- a/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -13,10 +13,20 @@
#include <algorithm>
#include <vector>
-#include <boost/assert.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/geometries/box.hpp>
+
+#include <boost/geometry/iterators/segment_iterator.hpp>
+
+#include <boost/geometry/algorithms/envelope.hpp>
+#include <boost/geometry/algorithms/expand.hpp>
+
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
+#include <boost/geometry/algorithms/detail/partition.hpp>
#include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp>
#include <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
#include <boost/geometry/algorithms/detail/disjoint/point_geometry.hpp>
@@ -33,7 +43,8 @@ namespace boost { namespace geometry
namespace detail { namespace disjoint
{
-template<typename MultiPoint1, typename MultiPoint2>
+
+template <typename MultiPoint1, typename MultiPoint2>
class multipoint_multipoint
{
private:
@@ -66,7 +77,7 @@ public:
static inline bool apply(MultiPoint1 const& multipoint1,
MultiPoint2 const& multipoint2)
{
- BOOST_ASSERT( boost::size(multipoint1) <= boost::size(multipoint2) );
+ BOOST_GEOMETRY_ASSERT( boost::size(multipoint1) <= boost::size(multipoint2) );
typedef typename boost::range_value<MultiPoint1>::type point1_type;
@@ -90,6 +101,98 @@ public:
};
+template <typename MultiPoint, typename Linear>
+class multipoint_linear
+{
+private:
+ // structs for partition -- start
+ struct expand_box
+ {
+ template <typename Box, typename Geometry>
+ static inline void apply(Box& total, Geometry const& geometry)
+ {
+ geometry::expand(total, geometry::return_envelope<Box>(geometry));
+ }
+
+ };
+
+ struct overlaps_box
+ {
+ template <typename Box, typename Geometry>
+ static inline bool apply(Box const& box, Geometry const& geometry)
+ {
+ return ! dispatch::disjoint<Geometry, Box>::apply(geometry, box);
+ }
+ };
+
+ class item_visitor_type
+ {
+ public:
+ item_visitor_type() : m_intersection_found(false) {}
+
+ 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))
+ {
+ m_intersection_found = true;
+ }
+ }
+
+ inline bool intersection_found() const { return m_intersection_found; }
+
+ private:
+ bool m_intersection_found;
+ };
+ // structs for partition -- end
+
+ class segment_range
+ {
+ public:
+ typedef geometry::segment_iterator<Linear const> const_iterator;
+ typedef const_iterator iterator;
+
+ segment_range(Linear const& linear)
+ : m_linear(linear)
+ {}
+
+ const_iterator begin() const
+ {
+ return geometry::segments_begin(m_linear);
+ }
+
+ const_iterator end() const
+ {
+ return geometry::segments_end(m_linear);
+ }
+
+ private:
+ Linear const& m_linear;
+ };
+
+public:
+ static inline bool apply(MultiPoint const& multipoint, Linear const& linear)
+ {
+ item_visitor_type visitor;
+
+ geometry::partition
+ <
+ geometry::model::box<typename point_type<MultiPoint>::type>,
+ expand_box,
+ overlaps_box
+ >::apply(multipoint, segment_range(linear), visitor);
+
+ return ! visitor.intersection_found();
+ }
+
+ static inline bool apply(Linear const& linear, MultiPoint const& multipoint)
+ {
+ return apply(multipoint, linear);
+ }
+};
+
+
}} // namespace detail::disjoint
#endif // DOXYGEN_NO_DETAIL
@@ -101,7 +204,7 @@ namespace dispatch
{
-template<typename Point, typename MultiPoint, std::size_t DimensionCount>
+template <typename Point, typename MultiPoint, std::size_t DimensionCount>
struct disjoint
<
Point, MultiPoint, DimensionCount, point_tag, multi_point_tag, false
@@ -109,7 +212,7 @@ struct disjoint
{};
-template<typename MultiPoint, typename Segment, std::size_t DimensionCount>
+template <typename MultiPoint, typename Segment, std::size_t DimensionCount>
struct disjoint
<
MultiPoint, Segment, DimensionCount, multi_point_tag, segment_tag, false
@@ -117,7 +220,7 @@ struct disjoint
{};
-template<typename MultiPoint, typename Box, std::size_t DimensionCount>
+template <typename MultiPoint, typename Box, std::size_t DimensionCount>
struct disjoint
<
MultiPoint, Box, DimensionCount, multi_point_tag, box_tag, false
@@ -125,7 +228,12 @@ struct disjoint
{};
-template<typename MultiPoint1, typename MultiPoint2, std::size_t DimensionCount>
+template
+<
+ typename MultiPoint1,
+ typename MultiPoint2,
+ std::size_t DimensionCount
+>
struct disjoint
<
MultiPoint1, MultiPoint2, DimensionCount,
@@ -151,6 +259,22 @@ struct disjoint
};
+template <typename Linear, typename MultiPoint, std::size_t DimensionCount>
+struct disjoint
+ <
+ Linear, MultiPoint, DimensionCount, linear_tag, multi_point_tag, false
+ > : detail::disjoint::multipoint_linear<MultiPoint, Linear>
+{};
+
+
+template <typename MultiPoint, typename Linear, std::size_t DimensionCount>
+struct disjoint
+ <
+ MultiPoint, Linear, DimensionCount, multi_point_tag, linear_tag, false
+ > : detail::disjoint::multipoint_linear<MultiPoint, Linear>
+{};
+
+
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
diff --git a/boost/geometry/algorithms/detail/disjoint/point_geometry.hpp b/boost/geometry/algorithms/detail/disjoint/point_geometry.hpp
index a58bff41da..9ae43f73d0 100644
--- a/boost/geometry/algorithms/detail/disjoint/point_geometry.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/point_geometry.hpp
@@ -1,12 +1,12 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
-// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 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) 2013-2015 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, 2014, 2015.
+// Modifications copyright (c) 2013-2015, 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
@@ -21,8 +21,6 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_POINT_GEOMETRY_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_POINT_GEOMETRY_HPP
-#include <boost/geometry/geometries/segment.hpp>
-
#include <boost/geometry/algorithms/covered_by.hpp>
#include <boost/geometry/algorithms/detail/disjoint/linear_linear.hpp>
@@ -39,24 +37,13 @@ namespace detail { namespace disjoint
{
-template<typename Point, typename Geometry>
-struct disjoint_point_linear
-{
- static inline
- bool apply(Point const& pt, Geometry const& g)
- {
- return !geometry::covered_by(pt, g);
- }
-};
-
-
-template <typename Geometry1, typename Geometry2>
struct reverse_covered_by
{
+ template <typename Geometry1, typename Geometry2>
static inline
bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
{
- return !geometry::covered_by(geometry1, geometry2);
+ return ! geometry::covered_by(geometry1, geometry2);
}
};
@@ -74,30 +61,20 @@ namespace dispatch
template<typename Point, typename Linear, std::size_t DimensionCount>
struct disjoint<Point, Linear, DimensionCount, point_tag, linear_tag, false>
- : public detail::disjoint::disjoint_point_linear<Point, Linear>
+ : detail::disjoint::reverse_covered_by
{};
template <typename Point, typename Areal, std::size_t DimensionCount>
struct disjoint<Point, Areal, DimensionCount, point_tag, areal_tag, false>
- : detail::disjoint::reverse_covered_by<Point, Areal>
+ : detail::disjoint::reverse_covered_by
{};
template<typename Point, typename Segment, std::size_t DimensionCount>
struct disjoint<Point, Segment, DimensionCount, point_tag, segment_tag, false>
-{
- static inline bool apply(Point const& point, Segment const& segment)
- {
- typedef geometry::model::referring_segment<Point const> other_segment;
-
- other_segment other(point, point);
- return detail::disjoint::disjoint_segment
- <
- Segment, other_segment
- >::apply(segment, other);
- }
-};
+ : detail::disjoint::reverse_covered_by
+{};
} // namespace dispatch
diff --git a/boost/geometry/algorithms/detail/disjoint/point_point.hpp b/boost/geometry/algorithms/detail/disjoint/point_point.hpp
index b1d32bf95e..7580b7287b 100644
--- a/boost/geometry/algorithms/detail/disjoint/point_point.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/point_point.hpp
@@ -1,12 +1,12 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
-// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland
+// Copyright (c) 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) 2013-2015 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, 2014, 2015.
+// Modifications copyright (c) 2013-2015, 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
@@ -23,11 +23,26 @@
#include <cstddef>
+#include <boost/type_traits/is_same.hpp>
+
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+#include <boost/geometry/strategies/strategy_transform.hpp>
+
+#include <boost/geometry/geometries/helper_geometry.hpp>
+
+#include <boost/geometry/algorithms/transform.hpp>
+
+#include <boost/geometry/algorithms/detail/normalize.hpp>
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
@@ -40,38 +55,146 @@ namespace boost { namespace geometry
namespace detail { namespace disjoint
{
-template
-<
- typename Point1, typename Point2,
- std::size_t Dimension, std::size_t DimensionCount
->
-struct point_point
+
+template <std::size_t Dimension, std::size_t DimensionCount>
+struct point_point_generic
{
+ template <typename Point1, typename Point2>
static inline bool apply(Point1 const& p1, Point2 const& p2)
{
if (! geometry::math::equals(get<Dimension>(p1), get<Dimension>(p2)))
{
return true;
}
- return point_point
- <
- Point1, Point2,
- Dimension + 1, DimensionCount
- >::apply(p1, p2);
+ return
+ point_point_generic<Dimension + 1, DimensionCount>::apply(p1, p2);
}
};
-
-template <typename Point1, typename Point2, std::size_t DimensionCount>
-struct point_point<Point1, Point2, DimensionCount, DimensionCount>
+template <std::size_t DimensionCount>
+struct point_point_generic<DimensionCount, DimensionCount>
{
- static inline bool apply(Point1 const& , Point2 const& )
+ template <typename Point1, typename Point2>
+ static inline bool apply(Point1 const&, Point2 const&)
{
return false;
}
};
+class point_point_on_spheroid
+{
+private:
+ template <typename Point1, typename Point2, bool SameUnits>
+ struct are_same_points
+ {
+ static inline bool apply(Point1 const& point1, Point2 const& point2)
+ {
+ typedef typename helper_geometry<Point1>::type helper_point_type1;
+ typedef typename helper_geometry<Point2>::type helper_point_type2;
+
+ helper_point_type1 point1_normalized
+ = return_normalized<helper_point_type1>(point1);
+ helper_point_type2 point2_normalized
+ = return_normalized<helper_point_type2>(point2);
+
+ return point_point_generic
+ <
+ 0, dimension<Point1>::value
+ >::apply(point1_normalized, point2_normalized);
+ }
+ };
+
+ template <typename Point1, typename Point2>
+ struct are_same_points<Point1, Point2, false> // points have different units
+ {
+ static inline bool apply(Point1 const& point1, Point2 const& point2)
+ {
+ typedef typename geometry::select_most_precise
+ <
+ typename fp_coordinate_type<Point1>::type,
+ typename fp_coordinate_type<Point2>::type
+ >::type calculation_type;
+
+ typename helper_geometry
+ <
+ Point1, calculation_type, radian
+ >::type helper_point1, helper_point2;
+
+ Point1 point1_normalized = return_normalized<Point1>(point1);
+ Point2 point2_normalized = return_normalized<Point2>(point2);
+
+ geometry::transform(point1_normalized, helper_point1);
+ geometry::transform(point2_normalized, helper_point2);
+
+ return point_point_generic
+ <
+ 0, dimension<Point1>::value
+ >::apply(helper_point1, helper_point2);
+ }
+ };
+
+public:
+ template <typename Point1, typename Point2>
+ static inline bool apply(Point1 const& point1, Point2 const& point2)
+ {
+ return are_same_points
+ <
+ Point1,
+ Point2,
+ boost::is_same
+ <
+ typename coordinate_system<Point1>::type::units,
+ typename coordinate_system<Point2>::type::units
+ >::value
+ >::apply(point1, point2);
+ }
+};
+
+
+template
+<
+ typename Point1, typename Point2,
+ std::size_t Dimension, std::size_t DimensionCount,
+ typename CSTag1 = typename cs_tag<Point1>::type,
+ typename CSTag2 = CSTag1
+>
+struct point_point
+ : point_point<Point1, Point2, Dimension, DimensionCount, cartesian_tag>
+{};
+
+template
+<
+ typename Point1, typename Point2,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct point_point
+ <
+ Point1, Point2, Dimension, DimensionCount, spherical_equatorial_tag
+ > : point_point_on_spheroid
+{};
+
+template
+<
+ typename Point1, typename Point2,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct point_point
+ <
+ Point1, Point2, Dimension, DimensionCount, geographic_tag
+ > : point_point_on_spheroid
+{};
+
+template
+<
+ typename Point1, typename Point2,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct point_point<Point1, Point2, Dimension, DimensionCount, cartesian_tag>
+ : point_point_generic<Dimension, DimensionCount>
+{};
+
+
/*!
\brief Internal utility function to detect of points are disjoint
\note To avoid circular references
diff --git a/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp b/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp
index 57257dbdcc..d6de7cac91 100644
--- a/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp
+++ b/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp
@@ -185,10 +185,10 @@ public:
Geometry const
> segment_iterator_type;
- typedef typename std::vector
+ typedef typename boost::range_const_iterator
<
- segment_or_box_point
- >::const_iterator seg_or_box_iterator_type;
+ std::vector<segment_or_box_point>
+ >::type seg_or_box_const_iterator;
typedef assign_new_min_iterator<SegmentOrBox> assign_new_value;
@@ -219,8 +219,9 @@ public:
// segment or box
comparable_return_type cd_min1(0);
point_iterator_type pit_min;
- seg_or_box_iterator_type it_min1 = seg_or_box_points.begin();
- seg_or_box_iterator_type it_min2 = ++seg_or_box_points.begin();
+ seg_or_box_const_iterator it_min1 = boost::const_begin(seg_or_box_points);
+ seg_or_box_const_iterator it_min2 = it_min1;
+ ++it_min2;
bool first = true;
for (point_iterator_type pit = points_begin(geometry);
@@ -229,11 +230,11 @@ public:
comparable_return_type cd;
std::pair
<
- seg_or_box_iterator_type, seg_or_box_iterator_type
+ seg_or_box_const_iterator, seg_or_box_const_iterator
> it_pair
= point_to_point_range::apply(*pit,
- seg_or_box_points.begin(),
- seg_or_box_points.end(),
+ boost::const_begin(seg_or_box_points),
+ boost::const_end(seg_or_box_points),
cstrategy,
cd);
@@ -250,12 +251,11 @@ public:
// segments of the geometry
comparable_return_type cd_min2(0);
segment_iterator_type sit_min;
- typename std::vector<segment_or_box_point>::const_iterator it_min;
+ seg_or_box_const_iterator it_min;
first = true;
- for (typename std::vector<segment_or_box_point>::const_iterator it
- = seg_or_box_points.begin();
- it != seg_or_box_points.end(); ++it, first = false)
+ for (seg_or_box_const_iterator it = boost::const_begin(seg_or_box_points);
+ it != boost::const_end(seg_or_box_points); ++it, first = false)
{
comparable_return_type cd;
segment_iterator_type sit
diff --git a/boost/geometry/algorithms/detail/distance/interface.hpp b/boost/geometry/algorithms/detail/distance/interface.hpp
index fa8cbd69ee..1e7cc433ef 100644
--- a/boost/geometry/algorithms/detail/distance/interface.hpp
+++ b/boost/geometry/algorithms/detail/distance/interface.hpp
@@ -198,7 +198,7 @@ struct distance<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
Geometry2 const& geometry2,
Strategy const& strategy)
{
- return apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
+ return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
}
};
@@ -253,7 +253,7 @@ struct distance<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
const variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry2,
Strategy const& strategy)
{
- return apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
+ return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
}
};
@@ -312,7 +312,7 @@ struct distance
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
Strategy const& strategy)
{
- return apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
+ return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
}
};
@@ -395,7 +395,7 @@ distance(Geometry1 const& geometry1,
concept::check<Geometry1 const>();
concept::check<Geometry2 const>();
- return distance(geometry1, geometry2, default_strategy());
+ return geometry::distance(geometry1, geometry2, default_strategy());
}
}} // namespace boost::geometry
diff --git a/boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp b/boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp
index 78189794a1..6e78bee694 100644
--- a/boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp
+++ b/boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp
@@ -13,8 +13,7 @@
#include <iterator>
#include <utility>
-#include <boost/assert.hpp>
-
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/iterators/has_one_element.hpp>
@@ -70,7 +69,7 @@ public:
{
namespace sds = strategy::distance::services;
- BOOST_ASSERT( first != last );
+ BOOST_GEOMETRY_ASSERT( first != last );
if ( geometry::has_one_element(first, last) )
{
diff --git a/boost/geometry/algorithms/detail/distance/segment_to_box.hpp b/boost/geometry/algorithms/detail/distance/segment_to_box.hpp
index 79d9adb703..783699ee0a 100644
--- a/boost/geometry/algorithms/detail/distance/segment_to_box.hpp
+++ b/boost/geometry/algorithms/detail/distance/segment_to_box.hpp
@@ -15,13 +15,13 @@
#include <functional>
#include <vector>
-#include <boost/assert.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/mpl/if.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/point_type.hpp>
@@ -561,7 +561,7 @@ private:
typedef compare_less_equal<ReturnType, true> less_equal;
// assert that the segment has non-negative slope
- BOOST_ASSERT( ( math::equals(geometry::get<0>(p0), geometry::get<0>(p1))
+ BOOST_GEOMETRY_ASSERT( ( math::equals(geometry::get<0>(p0), geometry::get<0>(p1))
&& geometry::get<1>(p0) < geometry::get<1>(p1))
||
( geometry::get<0>(p0) < geometry::get<0>(p1)
@@ -617,7 +617,7 @@ private:
typedef compare_less_equal<ReturnType, false> greater_equal;
// assert that the segment has negative slope
- BOOST_ASSERT( geometry::get<0>(p0) < geometry::get<0>(p1)
+ BOOST_GEOMETRY_ASSERT( geometry::get<0>(p0) < geometry::get<0>(p1)
&& geometry::get<1>(p0) > geometry::get<1>(p1) );
ReturnType result(0);
@@ -665,7 +665,7 @@ public:
PPStrategy const& pp_strategy,
PSStrategy const& ps_strategy)
{
- BOOST_ASSERT( geometry::less<SegmentPoint>()(p0, p1) );
+ BOOST_GEOMETRY_ASSERT( geometry::less<SegmentPoint>()(p0, p1) );
if (geometry::get<0>(p0) < geometry::get<0>(p1)
&& geometry::get<1>(p0) > geometry::get<1>(p1))
diff --git a/boost/geometry/algorithms/detail/envelope/box.hpp b/boost/geometry/algorithms/detail/envelope/box.hpp
new file mode 100644
index 0000000000..3790262948
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/box.hpp
@@ -0,0 +1,167 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// 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.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under 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_ENVELOPE_BOX_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_BOX_HPP
+
+#include <cstddef>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/views/detail/indexed_point_view.hpp>
+
+#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
+#include <boost/geometry/algorithms/detail/normalize.hpp>
+#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+template
+<
+ std::size_t Index,
+ std::size_t Dimension,
+ std::size_t DimensionCount
+>
+struct envelope_indexed_box
+{
+ template <typename BoxIn, typename BoxOut>
+ static inline void apply(BoxIn const& box_in, BoxOut& mbr)
+ {
+ detail::indexed_point_view<BoxIn const, Index> box_in_corner(box_in);
+ detail::indexed_point_view<BoxOut, Index> mbr_corner(mbr);
+
+ detail::conversion::point_to_point
+ <
+ detail::indexed_point_view<BoxIn const, Index>,
+ detail::indexed_point_view<BoxOut, Index>,
+ Dimension,
+ DimensionCount
+ >::apply(box_in_corner, mbr_corner);
+ }
+};
+
+template
+<
+ std::size_t Index,
+ std::size_t DimensionCount
+>
+struct envelope_indexed_box_on_spheroid
+{
+ template <typename BoxIn, typename BoxOut>
+ static inline void apply(BoxIn const& box_in, BoxOut& mbr)
+ {
+ // transform() does not work with boxes of dimension higher
+ // than 2; to account for such boxes we transform the min/max
+ // points of the boxes using the indexed_point_view
+ detail::indexed_point_view<BoxIn const, Index> box_in_corner(box_in);
+ detail::indexed_point_view<BoxOut, Index> mbr_corner(mbr);
+
+ // first transform the units
+ transform_units(box_in_corner, mbr_corner);
+
+ // now transform the remaining coordinates
+ detail::conversion::point_to_point
+ <
+ detail::indexed_point_view<BoxIn const, Index>,
+ detail::indexed_point_view<BoxOut, Index>,
+ 2,
+ DimensionCount
+ >::apply(box_in_corner, mbr_corner);
+ }
+};
+
+
+struct envelope_box
+{
+ template<typename BoxIn, typename BoxOut>
+ static inline void apply(BoxIn const& box_in, BoxOut& mbr)
+ {
+ envelope_indexed_box
+ <
+ min_corner, 0, dimension<BoxIn>::value
+ >::apply(box_in, mbr);
+
+ envelope_indexed_box
+ <
+ max_corner, 0, dimension<BoxIn>::value
+ >::apply(box_in, mbr);
+ }
+};
+
+
+struct envelope_box_on_spheroid
+{
+ template <typename BoxIn, typename BoxOut>
+ static inline void apply(BoxIn const& box_in, BoxOut& mbr)
+ {
+ BoxIn box_in_normalized = detail::return_normalized<BoxIn>(box_in);
+
+ envelope_indexed_box_on_spheroid
+ <
+ min_corner, dimension<BoxIn>::value
+ >::apply(box_in_normalized, mbr);
+
+ envelope_indexed_box_on_spheroid
+ <
+ max_corner, dimension<BoxIn>::value
+ >::apply(box_in_normalized, mbr);
+ }
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Box, typename CS_Tag>
+struct envelope<Box, box_tag, CS_Tag>
+ : detail::envelope::envelope_box
+{};
+
+
+template <typename Box>
+struct envelope<Box, box_tag, spherical_equatorial_tag>
+ : detail::envelope::envelope_box_on_spheroid
+{};
+
+
+template <typename Box>
+struct envelope<Box, box_tag, geographic_tag>
+ : detail::envelope::envelope_box_on_spheroid
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_BOX_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/implementation.hpp b/boost/geometry/algorithms/detail/envelope/implementation.hpp
new file mode 100644
index 0000000000..c1dbf8e589
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/implementation.hpp
@@ -0,0 +1,106 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// 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.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Distributed under 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_ENVELOPE_IMPLEMENTATION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_IMPLEMENTATION_HPP
+
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/is_empty.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/box.hpp>
+#include <boost/geometry/algorithms/detail/envelope/linear.hpp>
+#include <boost/geometry/algorithms/detail/envelope/multipoint.hpp>
+#include <boost/geometry/algorithms/detail/envelope/point.hpp>
+#include <boost/geometry/algorithms/detail/envelope/range.hpp>
+#include <boost/geometry/algorithms/detail/envelope/segment.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+struct envelope_polygon
+{
+ template <typename Polygon, typename Box>
+ static inline void apply(Polygon const& polygon, Box& mbr)
+ {
+ typename ring_return_type<Polygon const>::type ext_ring
+ = exterior_ring(polygon);
+
+ if (geometry::is_empty(ext_ring))
+ {
+ // if the exterior ring is empty, consider the interior rings
+ envelope_multi_range
+ <
+ envelope_range
+ >::apply(interior_rings(polygon), mbr);
+ }
+ else
+ {
+ // otherwise, consider only the exterior ring
+ envelope_range::apply(ext_ring, mbr);
+ }
+ }
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Ring>
+struct envelope<Ring, ring_tag>
+ : detail::envelope::envelope_range
+{};
+
+
+template <typename Polygon>
+struct envelope<Polygon, polygon_tag>
+ : detail::envelope::envelope_polygon
+{};
+
+
+template <typename MultiPolygon>
+struct envelope<MultiPolygon, multi_polygon_tag>
+ : detail::envelope::envelope_multi_range
+ <
+ detail::envelope::envelope_polygon
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_IMPLEMENTATION_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/initialize.hpp b/boost/geometry/algorithms/detail/envelope/initialize.hpp
new file mode 100644
index 0000000000..d8e252b53a
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/initialize.hpp
@@ -0,0 +1,86 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under 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_ENVELOPE_INITIALIZE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INITIALIZE_HPP
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/bounds.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+template <std::size_t Dimension, std::size_t DimensionCount>
+struct initialize_loop
+{
+ template <typename Box, typename CoordinateType>
+ static inline void apply(Box& box,
+ CoordinateType min_value,
+ CoordinateType max_value)
+ {
+ geometry::set<min_corner, Dimension>(box, min_value);
+ geometry::set<max_corner, Dimension>(box, max_value);
+
+ initialize_loop
+ <
+ Dimension + 1, DimensionCount
+ >::apply(box, min_value, max_value);
+ }
+};
+
+template <std::size_t DimensionCount>
+struct initialize_loop<DimensionCount, DimensionCount>
+{
+ template <typename Box, typename CoordinateType>
+ static inline void apply(Box&, CoordinateType, CoordinateType)
+ {
+ }
+};
+
+
+template
+<
+ typename Box,
+ std::size_t Dimension = 0,
+ std::size_t DimensionCount = dimension<Box>::value
+>
+struct initialize
+{
+ typedef typename coordinate_type<Box>::type coordinate_type;
+
+ static inline void apply(Box& box,
+ coordinate_type min_value
+ = boost::numeric::bounds<coordinate_type>::highest(),
+ coordinate_type max_value
+ = boost::numeric::bounds<coordinate_type>::lowest())
+ {
+ initialize_loop
+ <
+ Dimension, DimensionCount
+ >::apply(box, min_value, max_value);
+ }
+};
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INITIALIZE_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/interface.hpp b/boost/geometry/algorithms/detail/envelope/interface.hpp
new file mode 100644
index 0000000000..997ac1b23e
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/interface.hpp
@@ -0,0 +1,126 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// 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.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Distributed under 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_ENVELOPE_INTERFACE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERFACE_HPP
+
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace resolve_variant
+{
+
+template <typename Geometry>
+struct envelope
+{
+ template <typename Box>
+ static inline void apply(Geometry const& geometry, Box& box)
+ {
+ concept::check<Geometry const>();
+ concept::check<Box>();
+
+ dispatch::envelope<Geometry>::apply(geometry, box);
+ }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct envelope<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ template <typename Box>
+ struct visitor: boost::static_visitor<void>
+ {
+ Box& m_box;
+
+ visitor(Box& box): m_box(box) {}
+
+ template <typename Geometry>
+ void operator()(Geometry const& geometry) const
+ {
+ envelope<Geometry>::apply(geometry, m_box);
+ }
+ };
+
+ template <typename Box>
+ static inline void
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
+ Box& box)
+ {
+ boost::apply_visitor(visitor<Box>(box), geometry);
+ }
+};
+
+} // namespace resolve_variant
+
+
+/*!
+\brief \brief_calc{envelope}
+\ingroup envelope
+\details \details_calc{envelope,\det_envelope}.
+\tparam Geometry \tparam_geometry
+\tparam Box \tparam_box
+\param geometry \param_geometry
+\param mbr \param_box \param_set{envelope}
+
+\qbk{[include reference/algorithms/envelope.qbk]}
+\qbk{
+[heading Example]
+[envelope] [envelope_output]
+}
+*/
+template<typename Geometry, typename Box>
+inline void envelope(Geometry const& geometry, Box& mbr)
+{
+ resolve_variant::envelope<Geometry>::apply(geometry, 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}
+
+\qbk{[include reference/algorithms/envelope.qbk]}
+\qbk{
+[heading Example]
+[return_envelope] [return_envelope_output]
+}
+*/
+template<typename Box, typename Geometry>
+inline Box return_envelope(Geometry const& geometry)
+{
+ Box mbr;
+ resolve_variant::envelope<Geometry>::apply(geometry, mbr);
+ return mbr;
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERFACE_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/intersects_antimeridian.hpp b/boost/geometry/algorithms/detail/envelope/intersects_antimeridian.hpp
new file mode 100644
index 0000000000..47937bf740
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/intersects_antimeridian.hpp
@@ -0,0 +1,78 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under 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_ENVELOPE_INTERSECTS_ANTIMERIDIAN_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERSECTS_ANTIMERIDIAN_HPP
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/detail/normalize.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace detail { namespace envelope
+{
+
+
+struct intersects_antimeridian
+{
+ template <typename Units, typename CoordinateType>
+ static inline bool apply(CoordinateType const& lon1,
+ CoordinateType const& lat1,
+ CoordinateType const& lon2,
+ CoordinateType const& lat2)
+ {
+ typedef math::detail::constants_on_spheroid
+ <
+ CoordinateType, Units
+ > constants;
+
+ return
+ math::equals(math::abs(lat1), constants::max_latitude())
+ ||
+ math::equals(math::abs(lat2), constants::max_latitude())
+ ||
+ math::larger(math::abs(lon1 - lon2), constants::half_period());
+ }
+
+ template <typename Segment>
+ static inline bool apply(Segment const& segment)
+ {
+ return apply(detail::indexed_point_view<Segment, 0>(segment),
+ detail::indexed_point_view<Segment, 1>(segment));
+ }
+
+ template <typename Point>
+ static inline bool apply(Point const& p1, Point const& p2)
+ {
+ Point p1_normalized = detail::return_normalized<Point>(p1);
+ Point p2_normalized = detail::return_normalized<Point>(p2);
+
+ return apply
+ <
+ typename coordinate_system<Point>::type::units
+ >(geometry::get<0>(p1_normalized),
+ geometry::get<1>(p1_normalized),
+ geometry::get<0>(p2_normalized),
+ geometry::get<1>(p2_normalized));
+ }
+};
+
+
+}} // namespace detail::envelope
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERSECTS_ANTIMERIDIAN_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/linear.hpp b/boost/geometry/algorithms/detail/envelope/linear.hpp
new file mode 100644
index 0000000000..49c3cf3135
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/linear.hpp
@@ -0,0 +1,96 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// 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.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under 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_ENVELOPE_LINEAR_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_LINEAR_HPP
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/iterators/segment_iterator.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/range.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+struct envelope_linestring_on_spheroid
+{
+ template <typename Linestring, typename Box>
+ static inline void apply(Linestring const& linestring, Box& mbr)
+ {
+ envelope_range::apply(geometry::segments_begin(linestring),
+ geometry::segments_end(linestring),
+ mbr);
+ }
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Linestring, typename CS_Tag>
+struct envelope<Linestring, linestring_tag, CS_Tag>
+ : detail::envelope::envelope_range
+{};
+
+template <typename Linestring>
+struct envelope<Linestring, linestring_tag, spherical_equatorial_tag>
+ : detail::envelope::envelope_linestring_on_spheroid
+{};
+
+
+template <typename MultiLinestring, typename CS_Tag>
+struct envelope
+ <
+ MultiLinestring, multi_linestring_tag, CS_Tag
+ > : detail::envelope::envelope_multi_range
+ <
+ detail::envelope::envelope_range
+ >
+{};
+
+template <typename MultiLinestring>
+struct envelope
+ <
+ MultiLinestring, multi_linestring_tag, spherical_equatorial_tag
+ > : detail::envelope::envelope_multi_range_on_spheroid
+ <
+ detail::envelope::envelope_linestring_on_spheroid
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_LINEAR_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/multipoint.hpp b/boost/geometry/algorithms/detail/envelope/multipoint.hpp
new file mode 100644
index 0000000000..210debfdba
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/multipoint.hpp
@@ -0,0 +1,378 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under 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_ENVELOPE_MULTIPOINT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTIPOINT_HPP
+
+#include <cstddef>
+#include <algorithm>
+#include <utility>
+#include <vector>
+
+#include <boost/algorithm/minmax_element.hpp>
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/range.hpp>
+
+#include <boost/geometry/geometries/helper_geometry.hpp>
+
+#include <boost/geometry/algorithms/detail/normalize.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/box.hpp>
+#include <boost/geometry/algorithms/detail/envelope/initialize.hpp>
+#include <boost/geometry/algorithms/detail/envelope/range.hpp>
+#include <boost/geometry/algorithms/detail/expand/point.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+class envelope_multipoint_on_spheroid
+{
+private:
+ template <std::size_t Dim>
+ struct coordinate_less
+ {
+ template <typename Point>
+ inline bool operator()(Point const& point1, Point const& point2) const
+ {
+ return math::smaller(geometry::get<Dim>(point1),
+ geometry::get<Dim>(point2));
+ }
+ };
+
+ template <typename Constants, typename MultiPoint, typename OutputIterator>
+ static inline void analyze_point_coordinates(MultiPoint const& multipoint,
+ bool& has_south_pole,
+ bool& has_north_pole,
+ OutputIterator oit)
+ {
+ typedef typename boost::range_value<MultiPoint>::type point_type;
+ typedef typename boost::range_iterator
+ <
+ MultiPoint const
+ >::type iterator_type;
+
+ // analyze point coordinates:
+ // (1) normalize point coordinates
+ // (2) check if any point is the north or the south pole
+ // (3) put all non-pole points in a container
+ //
+ // notice that at this point in the algorithm, we have at
+ // least two points on the spheroid
+ has_south_pole = false;
+ has_north_pole = false;
+
+ for (iterator_type it = boost::begin(multipoint);
+ it != boost::end(multipoint);
+ ++it)
+ {
+ point_type point = detail::return_normalized<point_type>(*it);
+
+ if (math::equals(geometry::get<1>(point),
+ Constants::min_latitude()))
+ {
+ has_south_pole = true;
+ }
+ else if (math::equals(geometry::get<1>(point),
+ Constants::max_latitude()))
+ {
+ has_north_pole = true;
+ }
+ else
+ {
+ *oit++ = point;
+ }
+ }
+ }
+
+ template <typename SortedRange, typename Value>
+ static inline Value maximum_gap(SortedRange const& sorted_range,
+ Value& max_gap_left,
+ Value& max_gap_right)
+ {
+ typedef typename boost::range_iterator
+ <
+ SortedRange const
+ >::type iterator_type;
+
+ iterator_type it1 = boost::begin(sorted_range), it2 = it1;
+ ++it2;
+ max_gap_left = geometry::get<0>(*it1);
+ max_gap_right = geometry::get<0>(*it2);
+
+ Value max_gap = max_gap_right - max_gap_left;
+ for (++it1, ++it2; it2 != boost::end(sorted_range); ++it1, ++it2)
+ {
+ Value gap = geometry::get<0>(*it2) - geometry::get<0>(*it1);
+ if (math::larger(gap, max_gap))
+ {
+ max_gap_left = geometry::get<0>(*it1);
+ max_gap_right = geometry::get<0>(*it2);
+ max_gap = gap;
+ }
+ }
+
+ return max_gap;
+ }
+
+ template
+ <
+ typename Constants,
+ typename PointRange,
+ typename LongitudeLess,
+ typename CoordinateType
+ >
+ static inline void get_min_max_longitudes(PointRange& range,
+ LongitudeLess const& lon_less,
+ CoordinateType& lon_min,
+ CoordinateType& lon_max)
+ {
+ typedef typename boost::range_iterator
+ <
+ PointRange const
+ >::type iterator_type;
+
+ // compute min and max longitude values
+ std::pair<iterator_type, iterator_type> min_max_longitudes
+ = boost::minmax_element(boost::begin(range),
+ boost::end(range),
+ lon_less);
+
+ lon_min = geometry::get<0>(*min_max_longitudes.first);
+ lon_max = geometry::get<0>(*min_max_longitudes.second);
+
+ // if the longitude span is "large" compute the true maximum gap
+ if (math::larger(lon_max - lon_min, Constants::half_period()))
+ {
+ std::sort(boost::begin(range), boost::end(range), lon_less);
+
+ CoordinateType max_gap_left = 0, max_gap_right = 0;
+ CoordinateType max_gap
+ = maximum_gap(range, max_gap_left, max_gap_right);
+
+ CoordinateType complement_gap
+ = Constants::period() + lon_min - lon_max;
+
+ if (math::larger(max_gap, complement_gap))
+ {
+ lon_min = max_gap_right;
+ lon_max = max_gap_left + Constants::period();
+ }
+ }
+ }
+
+ template
+ <
+ typename Constants,
+ typename Iterator,
+ typename LatitudeLess,
+ typename CoordinateType
+ >
+ static inline void get_min_max_latitudes(Iterator const first,
+ Iterator const last,
+ LatitudeLess const& lat_less,
+ bool has_south_pole,
+ bool has_north_pole,
+ CoordinateType& lat_min,
+ CoordinateType& lat_max)
+ {
+ if (has_south_pole && has_north_pole)
+ {
+ lat_min = Constants::min_latitude();
+ lat_max = Constants::max_latitude();
+ }
+ else if (has_south_pole)
+ {
+ lat_min = Constants::min_latitude();
+ lat_max
+ = geometry::get<1>(*std::max_element(first, last, lat_less));
+ }
+ else if (has_north_pole)
+ {
+ lat_min
+ = geometry::get<1>(*std::min_element(first, last, lat_less));
+ lat_max = Constants::max_latitude();
+ }
+ else
+ {
+ std::pair<Iterator, Iterator> min_max_latitudes
+ = boost::minmax_element(first, last, lat_less);
+
+ lat_min = geometry::get<1>(*min_max_latitudes.first);
+ lat_max = geometry::get<1>(*min_max_latitudes.second);
+ }
+ }
+
+public:
+ template <typename MultiPoint, typename Box>
+ static inline void apply(MultiPoint const& multipoint, Box& mbr)
+ {
+ typedef typename point_type<MultiPoint>::type point_type;
+ typedef typename coordinate_type<MultiPoint>::type coordinate_type;
+ typedef typename boost::range_iterator
+ <
+ MultiPoint const
+ >::type iterator_type;
+
+ typedef math::detail::constants_on_spheroid
+ <
+ coordinate_type,
+ typename coordinate_system<MultiPoint>::type::units
+ > constants;
+
+ if (boost::empty(multipoint))
+ {
+ initialize<Box, 0, dimension<Box>::value>::apply(mbr);
+ return;
+ }
+
+ initialize<Box, 0, 2>::apply(mbr);
+
+ if (boost::size(multipoint) == 1)
+ {
+ return dispatch::envelope
+ <
+ typename boost::range_value<MultiPoint>::type
+ >::apply(range::front(multipoint), mbr);
+ }
+
+ // analyze the points and put the non-pole ones in the
+ // points vector
+ std::vector<point_type> points;
+ bool has_north_pole = false, has_south_pole = false;
+
+ analyze_point_coordinates<constants>(multipoint,
+ has_south_pole, has_north_pole,
+ std::back_inserter(points));
+
+ coordinate_type lon_min, lat_min, lon_max, lat_max;
+ if (points.size() == 1)
+ {
+ // we have one non-pole point and at least one pole point
+ lon_min = geometry::get<0>(range::front(points));
+ lon_max = geometry::get<0>(range::front(points));
+ lat_min = has_south_pole
+ ? constants::min_latitude()
+ : constants::max_latitude();
+ lat_max = has_north_pole
+ ? constants::max_latitude()
+ : constants::min_latitude();
+ }
+ else if (points.empty())
+ {
+ // all points are pole points
+ BOOST_GEOMETRY_ASSERT(has_south_pole || has_north_pole);
+ lon_min = coordinate_type(0);
+ lon_max = coordinate_type(0);
+ lat_min = has_south_pole
+ ? constants::min_latitude()
+ : constants::max_latitude();
+ lat_max = (has_north_pole)
+ ? constants::max_latitude()
+ : constants::min_latitude();
+ }
+ else
+ {
+ get_min_max_longitudes<constants>(points,
+ coordinate_less<0>(),
+ lon_min,
+ lon_max);
+
+ get_min_max_latitudes<constants>(points.begin(),
+ points.end(),
+ coordinate_less<1>(),
+ has_south_pole,
+ has_north_pole,
+ lat_min,
+ lat_max);
+ }
+
+ typedef typename helper_geometry
+ <
+ Box,
+ coordinate_type,
+ typename coordinate_system<MultiPoint>::type::units
+ >::type helper_box_type;
+
+ helper_box_type helper_mbr;
+
+ geometry::set<min_corner, 0>(helper_mbr, lon_min);
+ geometry::set<min_corner, 1>(helper_mbr, lat_min);
+ geometry::set<max_corner, 0>(helper_mbr, lon_max);
+ geometry::set<max_corner, 1>(helper_mbr, lat_max);
+
+ // now transform to output MBR (per index)
+ envelope_indexed_box_on_spheroid<min_corner, 2>::apply(helper_mbr, mbr);
+ envelope_indexed_box_on_spheroid<max_corner, 2>::apply(helper_mbr, mbr);
+
+ // compute envelope for higher coordinates
+ iterator_type it = boost::begin(multipoint);
+ envelope_one_point<2, dimension<Box>::value>::apply(*it, mbr);
+
+ for (++it; it != boost::end(multipoint); ++it)
+ {
+ detail::expand::point_loop
+ <
+ strategy::compare::default_strategy,
+ strategy::compare::default_strategy,
+ 2, dimension<Box>::value
+ >::apply(mbr, *it);
+ }
+ }
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename MultiPoint, typename CSTag>
+struct envelope<MultiPoint, multi_point_tag, CSTag>
+ : detail::envelope::envelope_range
+{};
+
+template <typename MultiPoint>
+struct envelope<MultiPoint, multi_point_tag, spherical_equatorial_tag>
+ : detail::envelope::envelope_multipoint_on_spheroid
+{};
+
+template <typename MultiPoint>
+struct envelope<MultiPoint, multi_point_tag, geographic_tag>
+ : detail::envelope::envelope_multipoint_on_spheroid
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTIPOINT_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/point.hpp b/boost/geometry/algorithms/detail/envelope/point.hpp
new file mode 100644
index 0000000000..e914e7e8a0
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/point.hpp
@@ -0,0 +1,127 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// 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.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under 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_ENVELOPE_POINT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_POINT_HPP
+
+#include <cstddef>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/views/detail/indexed_point_view.hpp>
+
+#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
+#include <boost/geometry/algorithms/detail/normalize.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+template <std::size_t Dimension, std::size_t DimensionCount>
+struct envelope_one_point
+{
+ template <std::size_t Index, typename Point, typename Box>
+ static inline void apply(Point const& point, Box& mbr)
+ {
+ detail::indexed_point_view<Box, Index> box_corner(mbr);
+ detail::conversion::point_to_point
+ <
+ Point,
+ detail::indexed_point_view<Box, Index>,
+ Dimension,
+ DimensionCount
+ >::apply(point, box_corner);
+ }
+
+ template <typename Point, typename Box>
+ static inline void apply(Point const& point, Box& mbr)
+ {
+ apply<min_corner>(point, mbr);
+ apply<max_corner>(point, mbr);
+ }
+};
+
+
+struct envelope_point_on_spheroid
+{
+ template<typename Point, typename Box>
+ static inline void apply(Point const& point, Box& mbr)
+ {
+ Point normalized_point = detail::return_normalized<Point>(point);
+
+ typename point_type<Box>::type box_point;
+
+ // transform units of input point to units of a box point
+ transform_units(normalized_point, box_point);
+
+ geometry::set<min_corner, 0>(mbr, geometry::get<0>(box_point));
+ geometry::set<min_corner, 1>(mbr, geometry::get<1>(box_point));
+
+ geometry::set<max_corner, 0>(mbr, geometry::get<0>(box_point));
+ geometry::set<max_corner, 1>(mbr, geometry::get<1>(box_point));
+
+ envelope_one_point
+ <
+ 2, dimension<Point>::value
+ >::apply(normalized_point, mbr);
+ }
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Point, typename CS_Tag>
+struct envelope<Point, point_tag, CS_Tag>
+ : detail::envelope::envelope_one_point<0, dimension<Point>::value>
+{};
+
+
+template <typename Point>
+struct envelope<Point, point_tag, spherical_equatorial_tag>
+ : detail::envelope::envelope_point_on_spheroid
+{};
+
+
+template <typename Point>
+struct envelope<Point, point_tag, geographic_tag>
+ : detail::envelope::envelope_point_on_spheroid
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_POINT_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/range.hpp b/boost/geometry/algorithms/detail/envelope/range.hpp
new file mode 100644
index 0000000000..63b518114b
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/range.hpp
@@ -0,0 +1,179 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// 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.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Distributed under 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_ENVELOPE_RANGE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_RANGE_HPP
+
+#include <iterator>
+#include <vector>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+
+#include <boost/geometry/util/range.hpp>
+
+#include <boost/geometry/algorithms/is_empty.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/initialize.hpp>
+#include <boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp>
+
+#include <boost/geometry/algorithms/detail/expand/box.hpp>
+#include <boost/geometry/algorithms/detail/expand/point.hpp>
+#include <boost/geometry/algorithms/detail/expand/segment.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+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)
+ {
+ typedef typename std::iterator_traits<Iterator>::value_type value_type;
+
+ // initialize MBR
+ initialize<Box, 0, dimension<Box>::value>::apply(mbr);
+
+ Iterator it = first;
+ if (it != last)
+ {
+ // initialize box with first element in range
+ dispatch::envelope<value_type>::apply(*it, mbr);
+
+ // consider now the remaining elements in the range (if any)
+ for (++it; it != last; ++it)
+ {
+ dispatch::expand<Box, value_type>::apply(mbr, *it);
+ }
+ }
+ }
+
+ template <typename Range, typename Box>
+ static inline void apply(Range const& range, Box& mbr)
+ {
+ return apply(boost::begin(range), boost::end(range), mbr);
+ }
+};
+
+
+// implementation for multi-ranges
+template <typename EnvelopePolicy>
+struct envelope_multi_range
+{
+ template <typename MultiRange, typename Box>
+ static inline void apply(MultiRange const& multirange, Box& mbr)
+ {
+ typedef typename boost::range_iterator
+ <
+ MultiRange const
+ >::type iterator_type;
+
+ bool initialized = false;
+ for (iterator_type it = boost::begin(multirange);
+ it != boost::end(multirange);
+ ++it)
+ {
+ if (! geometry::is_empty(*it))
+ {
+ if (initialized)
+ {
+ Box helper_mbr;
+ EnvelopePolicy::apply(*it, helper_mbr);
+
+ dispatch::expand<Box, Box>::apply(mbr, helper_mbr);
+ }
+ else
+ {
+ // compute the initial envelope
+ EnvelopePolicy::apply(*it, mbr);
+ initialized = true;
+ }
+ }
+ }
+
+ if (! initialized)
+ {
+ // if not already initialized, initialize MBR
+ initialize<Box, 0, dimension<Box>::value>::apply(mbr);
+ }
+ }
+};
+
+
+// implementation for multi-range on a spheroid (longitude is periodic)
+template <typename EnvelopePolicy>
+struct envelope_multi_range_on_spheroid
+{
+ template <typename MultiRange, typename Box>
+ static inline void apply(MultiRange const& multirange, Box& mbr)
+ {
+ typedef typename boost::range_iterator
+ <
+ MultiRange const
+ >::type iterator_type;
+
+ // due to the periodicity of longitudes we need to compute the boxes
+ // of all the single geometries and keep them in a container
+ std::vector<Box> boxes;
+ for (iterator_type it = boost::begin(multirange);
+ it != boost::end(multirange);
+ ++it)
+ {
+ if (! geometry::is_empty(*it))
+ {
+ Box helper_box;
+ EnvelopePolicy::apply(*it, helper_box);
+ boxes.push_back(helper_box);
+ }
+ }
+
+ // now we need to compute the envelope of the range of boxes
+ // (cannot be done in an incremental fashion as in the
+ // Cartesian coordinate system)
+ // if all single geometries are empty no boxes have been found
+ // and the MBR is simply initialized
+ if (! boxes.empty())
+ {
+ envelope_range_of_boxes::apply(boxes, mbr);
+ }
+ else
+ {
+ initialize<Box, 0, dimension<Box>::value>::apply(mbr);
+ }
+
+ }
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_RANGE_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp b/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp
new file mode 100644
index 0000000000..64bdb9b9cb
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp
@@ -0,0 +1,326 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under 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_ENVELOPE_RANGE_OF_BOXES_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_RANGE_OF_BOXES_HPP
+
+#include <cstddef>
+
+#include <algorithm>
+#include <vector>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/range.hpp>
+
+#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
+#include <boost/geometry/algorithms/detail/max_interval_gap.hpp>
+#include <boost/geometry/algorithms/detail/expand/indexed.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+template <typename T>
+class longitude_interval
+{
+ typedef T const& reference_type;
+
+public:
+ typedef T value_type;
+ typedef T difference_type;
+
+ longitude_interval(T const& left, T const& right)
+ {
+ m_end[0] = left;
+ m_end[1] = right;
+ }
+
+ template <std::size_t Index>
+ reference_type get() const
+ {
+ return m_end[Index];
+ }
+
+ difference_type length() const
+ {
+ return get<1>() - get<0>();
+ }
+
+private:
+ T m_end[2];
+};
+
+
+template <typename Units>
+struct envelope_range_of_longitudes
+{
+ template <std::size_t Index>
+ struct longitude_less
+ {
+ template <typename Interval>
+ inline bool operator()(Interval const& i1, Interval const& i2) const
+ {
+ return math::smaller(i1.template get<Index>(),
+ i2.template get<Index>());
+ }
+ };
+
+ template <typename RangeOfLongitudeIntervals, typename Longitude>
+ static inline void apply(RangeOfLongitudeIntervals const& range,
+ Longitude& lon_min, Longitude& lon_max)
+ {
+ typedef typename math::detail::constants_on_spheroid
+ <
+ Longitude, Units
+ > constants;
+
+ Longitude const zero = 0;
+ Longitude const period = constants::period();
+
+ lon_min = lon_max = zero;
+
+ // the range of longitude intervals can be empty if all input boxes
+ // degenerate to the north or south pole (or combination of the two)
+ // in this case the initialization values for lon_min and
+ // lon_max are valid choices
+ if (! boost::empty(range))
+ {
+ lon_min = std::min_element(boost::begin(range),
+ boost::end(range),
+ longitude_less<0>())->template get<0>();
+ lon_max = std::max_element(boost::begin(range),
+ boost::end(range),
+ longitude_less<1>())->template get<1>();
+
+ if (math::larger(lon_max - lon_min, constants::half_period()))
+ {
+ Longitude max_gap_left, max_gap_right;
+ Longitude max_gap = geometry::maximum_gap(range,
+ max_gap_left,
+ max_gap_right);
+
+ BOOST_GEOMETRY_ASSERT(! math::larger(lon_min, lon_max));
+ BOOST_GEOMETRY_ASSERT
+ (! math::larger(lon_max, constants::max_longitude()));
+ BOOST_GEOMETRY_ASSERT
+ (! math::smaller(lon_min, constants::min_longitude()));
+
+ BOOST_GEOMETRY_ASSERT
+ (! math::larger(max_gap_left, max_gap_right));
+ BOOST_GEOMETRY_ASSERT
+ (! math::larger(max_gap_right, constants::max_longitude()));
+ BOOST_GEOMETRY_ASSERT
+ (! math::smaller(max_gap_left, constants::min_longitude()));
+
+ if (math::larger(max_gap, zero))
+ {
+ Longitude wrapped_gap = period + lon_min - lon_max;
+ if (math::larger(max_gap, wrapped_gap))
+ {
+ lon_min = max_gap_right;
+ lon_max = max_gap_left + period;
+ }
+ }
+ }
+ }
+ }
+};
+
+
+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)
+ {
+ typedef typename boost::range_value<RangeOfBoxes>::type box_type;
+
+ typedef typename boost::range_iterator
+ <
+ RangeOfBoxes const
+ >::type iterator_type;
+
+ // first initialize MBR
+ detail::indexed_point_view<Box, min_corner> mbr_min(mbr);
+ detail::indexed_point_view<Box, max_corner> mbr_max(mbr);
+
+ detail::indexed_point_view<box_type const, min_corner>
+ first_box_min(range::front(range_of_boxes));
+
+ detail::indexed_point_view<box_type const, max_corner>
+ first_box_max(range::front(range_of_boxes));
+
+ detail::conversion::point_to_point
+ <
+ detail::indexed_point_view<box_type const, min_corner>,
+ detail::indexed_point_view<Box, min_corner>,
+ Dimension,
+ DimensionCount
+ >::apply(first_box_min, mbr_min);
+
+ detail::conversion::point_to_point
+ <
+ detail::indexed_point_view<box_type const, max_corner>,
+ detail::indexed_point_view<Box, max_corner>,
+ Dimension,
+ DimensionCount
+ >::apply(first_box_max, mbr_max);
+
+ // now expand using the remaining boxes
+ iterator_type it = boost::begin(range_of_boxes);
+ for (++it; it != boost::end(range_of_boxes); ++it)
+ {
+ detail::expand::indexed_loop
+ <
+ strategy::compare::default_strategy,
+ strategy::compare::default_strategy,
+ min_corner,
+ Dimension,
+ DimensionCount
+ >::apply(mbr, *it);
+
+ detail::expand::indexed_loop
+ <
+ strategy::compare::default_strategy,
+ strategy::compare::default_strategy,
+ max_corner,
+ Dimension,
+ DimensionCount
+ >::apply(mbr, *it);
+ }
+ }
+
+};
+
+
+struct envelope_range_of_boxes
+{
+ template <std::size_t Index>
+ struct latitude_less
+ {
+ template <typename Box>
+ inline bool operator()(Box const& box1, Box const& box2) const
+ {
+ return math::smaller(geometry::get<Index, 1>(box1),
+ geometry::get<Index, 1>(box2));
+ }
+ };
+
+ template <typename RangeOfBoxes, typename Box>
+ static inline void apply(RangeOfBoxes const& range_of_boxes, Box& mbr)
+ {
+ // boxes in the range are assumed to be normalized already
+
+ typedef typename boost::range_value<RangeOfBoxes>::type box_type;
+ typedef typename coordinate_type<box_type>::type coordinate_type;
+ typedef typename coordinate_system<box_type>::type::units units_type;
+ typedef typename boost::range_iterator
+ <
+ RangeOfBoxes const
+ >::type iterator_type;
+
+ typedef math::detail::constants_on_spheroid
+ <
+ coordinate_type, units_type
+ > constants;
+
+ typedef longitude_interval<coordinate_type> interval_type;
+ typedef std::vector<interval_type> interval_range_type;
+
+ BOOST_GEOMETRY_ASSERT(! boost::empty(range_of_boxes));
+
+ iterator_type it_min = std::min_element(boost::begin(range_of_boxes),
+ boost::end(range_of_boxes),
+ latitude_less<min_corner>());
+ iterator_type it_max = std::max_element(boost::begin(range_of_boxes),
+ boost::end(range_of_boxes),
+ latitude_less<max_corner>());
+
+ coordinate_type const min_longitude = constants::min_longitude();
+ coordinate_type const max_longitude = constants::max_longitude();
+ coordinate_type const period = constants::period();
+
+ interval_range_type intervals;
+ for (iterator_type it = boost::begin(range_of_boxes);
+ it != boost::end(range_of_boxes);
+ ++it)
+ {
+ coordinate_type lat_min = geometry::get<min_corner, 1>(*it);
+ coordinate_type lat_max = geometry::get<max_corner, 1>(*it);
+ if (math::equals(lat_min, constants::max_latitude())
+ || math::equals(lat_max, constants::min_latitude()))
+ {
+ // if the box degenerates to the south or north pole
+ // just ignore it
+ continue;
+ }
+
+ coordinate_type lon_left = geometry::get<min_corner, 0>(*it);
+ coordinate_type lon_right = geometry::get<max_corner, 0>(*it);
+
+ if (math::larger(lon_right, max_longitude))
+ {
+ intervals.push_back(interval_type(lon_left, max_longitude));
+ intervals.push_back
+ (interval_type(min_longitude, lon_right - period));
+ }
+ else
+ {
+ intervals.push_back(interval_type(lon_left, lon_right));
+ }
+ }
+
+ coordinate_type lon_min = 0;
+ coordinate_type lon_max = 0;
+ envelope_range_of_longitudes
+ <
+ units_type
+ >::apply(intervals, lon_min, lon_max);
+
+ // do not convert units; conversion will be performed at a
+ // higher level
+
+ // assign now the min/max longitude/latitude values
+ detail::indexed_point_view<Box, min_corner> mbr_min(mbr);
+ detail::indexed_point_view<Box, max_corner> mbr_max(mbr);
+
+ geometry::set<0>(mbr_min, lon_min);
+ geometry::set<1>(mbr_min, geometry::get<min_corner, 1>(*it_min));
+ geometry::set<0>(mbr_max, lon_max);
+ geometry::set<1>(mbr_max, geometry::get<max_corner, 1>(*it_max));
+
+ // what remains to be done is to compute the envelope range
+ // for the remaining dimensions (if any)
+ envelope_range_of_boxes_by_expansion
+ <
+ 2, dimension<Box>::value
+ >::apply(range_of_boxes, mbr);
+ }
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_RANGE_OF_BOXES_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/segment.hpp b/boost/geometry/algorithms/detail/envelope/segment.hpp
new file mode 100644
index 0000000000..570f0e1a43
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/segment.hpp
@@ -0,0 +1,386 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// 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.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under 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_ENVELOPE_SEGMENT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_SEGMENT_HPP
+
+#include <cstddef>
+#include <utility>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/geometries/helper_geometry.hpp>
+
+#include <boost/geometry/strategies/compare.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>
+
+#include <boost/geometry/algorithms/detail/expand/point.hpp>
+
+#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+template <std::size_t Dimension, std::size_t DimensionCount>
+struct envelope_one_segment
+{
+ template<typename Point, typename Box>
+ static inline void apply(Point const& p1, Point const& p2, Box& mbr)
+ {
+ 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);
+ }
+};
+
+
+// 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
+{
+private:
+ // computes the azimuths of the segment with endpoints (lon1, lat1)
+ // and (lon2, lat2)
+ template <typename CalculationType>
+ static inline void azimuths(CalculationType const& lon1,
+ CalculationType const& lat1,
+ CalculationType const& lon2,
+ CalculationType const& lat2,
+ CalculationType& a1,
+ CalculationType& a2)
+ {
+ BOOST_GEOMETRY_ASSERT(math::smaller(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>();
+ }
+
+ template <typename CalculationType>
+ static inline void swap(CalculationType& lon1,
+ CalculationType& lat1,
+ CalculationType& lon2,
+ CalculationType& lat2)
+ {
+ std::swap(lon1, lon2);
+ std::swap(lat1, lat2);
+ }
+
+ template <typename CalculationType>
+ static inline bool contains_pi_half(CalculationType const& a1,
+ CalculationType const& a2)
+ {
+ // azimuths a1 and a2 are assumed to be in radians
+ BOOST_GEOMETRY_ASSERT(! math::equals(a1, a2));
+
+ static CalculationType const pi_half = math::half_pi<CalculationType>();
+
+ return (a1 < a2)
+ ? (a1 < pi_half && pi_half < a2)
+ : (a1 > pi_half && pi_half > a2);
+ }
+
+ template <typename CoordinateType>
+ static inline bool crosses_antimeridian(CoordinateType const& lon1,
+ CoordinateType const& lon2)
+ {
+ return math::larger(math::abs(lon1 - lon2), math::pi<CoordinateType>());
+ }
+
+ 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)) );
+ }
+
+ template <typename CalculationType>
+ static inline void compute_box_corners(CalculationType& lon1,
+ CalculationType& lat1,
+ CalculationType& lon2,
+ CalculationType& lat2,
+ CalculationType const& a1,
+ CalculationType const& a2)
+ {
+ // coordinates are assumed to be in radians
+ BOOST_GEOMETRY_ASSERT(! math::larger(lon1, lon2));
+
+ if (math::equals(a1, a2))
+ {
+ // the segment must lie on the equator; nothing to do
+ BOOST_GEOMETRY_ASSERT(math::equals(lat1, CalculationType(0)));
+ BOOST_GEOMETRY_ASSERT(math::equals(lat2, CalculationType(0)));
+ return;
+ }
+
+ if (math::larger(lat1, lat2))
+ {
+ std::swap(lat1, lat2);
+ }
+
+ if (contains_pi_half(a1, a2))
+ {
+ CalculationType mid_lat = lat1 + lat2;
+ if (mid_lat < 0)
+ {
+ // update using min latitude
+ CalculationType lat_min = -max_latitude(a1, lat1);
+
+ if (math::larger(lat1, lat_min))
+ {
+ lat1 = lat_min;
+ }
+ }
+ else if (mid_lat > 0)
+ {
+ // update using max latitude
+ CalculationType lat_max = max_latitude(a1, lat1);
+
+ if (math::smaller(lat2, lat_max))
+ {
+ lat2 = lat_max;
+ }
+ }
+ }
+ }
+
+ template <typename CalculationType>
+ static inline void apply(CalculationType& lon1,
+ CalculationType& lat1,
+ CalculationType& lon2,
+ CalculationType& lat2)
+ {
+ CalculationType const half_pi = math::half_pi<CalculationType>();
+
+ bool is_pole1 = math::equals(math::abs(lat1), half_pi);
+ bool is_pole2 = math::equals(math::abs(lat2), half_pi);
+
+ if (is_pole1 && is_pole2)
+ {
+ // both points are poles; nothing more to do:
+ // longitudes are already normalized to 0
+ BOOST_GEOMETRY_ASSERT(lon1 == CalculationType(0)
+ &&
+ lon2 == CalculationType(0));
+ }
+ else if (is_pole1 && !is_pole2)
+ {
+ // first point is a pole, second point is not:
+ // make the longitude of the first point the same as that
+ // of the second point
+ lon1 = lon2;
+ }
+ else if (!is_pole1 && is_pole2)
+ {
+ // second point is a pole, first point is not:
+ // make the longitude of the second point the same as that
+ // of the first point
+ lon2 = lon1;
+ }
+
+ if (math::equals(lon1, lon2))
+ {
+ // segment lies on a meridian
+ if (math::larger(lat1, lat2))
+ {
+ std::swap(lat1, lat2);
+ }
+ return;
+ }
+
+ BOOST_GEOMETRY_ASSERT(!is_pole1 && !is_pole2);
+
+ if (math::larger(lon1, lon2))
+ {
+ swap(lon1, lat1, lon2, lat2);
+ }
+
+ if (crosses_antimeridian(lon1, lon2))
+ {
+ lon1 += math::two_pi<CalculationType>();
+ swap(lon1, lat1, lon2, lat2);
+ }
+
+ CalculationType a1 = 0, a2 = 0;
+ azimuths(lon1, lat1, lon2, lat2, a1, a2);
+
+ compute_box_corners(lon1, lat1, lon2, lat2, a1, a2);
+ }
+
+public:
+ template <typename CalculationType, typename Box>
+ static inline void apply(CalculationType lon1,
+ CalculationType lat1,
+ CalculationType lon2,
+ CalculationType lat2,
+ Box& mbr)
+ {
+ typedef typename coordinate_type<Box>::type box_coordinate_type;
+
+ typedef typename helper_geometry
+ <
+ Box, box_coordinate_type, radian
+ >::type helper_box_type;
+
+ helper_box_type radian_mbr;
+
+ apply(lon1, lat1, lon2, lat2);
+
+ geometry::set
+ <
+ min_corner, 0
+ >(radian_mbr, boost::numeric_cast<box_coordinate_type>(lon1));
+
+ geometry::set
+ <
+ min_corner, 1
+ >(radian_mbr, boost::numeric_cast<box_coordinate_type>(lat1));
+
+ geometry::set
+ <
+ max_corner, 0
+ >(radian_mbr, boost::numeric_cast<box_coordinate_type>(lon2));
+
+ geometry::set
+ <
+ max_corner, 1
+ >(radian_mbr, boost::numeric_cast<box_coordinate_type>(lat2));
+
+ transform_units(radian_mbr, mbr);
+ }
+};
+
+
+template <std::size_t DimensionCount>
+struct envelope_segment_on_sphere
+{
+ template <typename Point, typename Box>
+ static inline void apply(Point const& p1, Point const& p2, Box& mbr)
+ {
+ // 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);
+
+ compute_mbr_of_segment::apply(geometry::get_as_radian<0>(p1_normalized),
+ geometry::get_as_radian<1>(p1_normalized),
+ geometry::get_as_radian<0>(p2_normalized),
+ geometry::get_as_radian<1>(p2_normalized),
+ mbr);
+
+ // now compute the envelope range for coordinates of
+ // dimension 2 and higher
+ envelope_one_segment<2, DimensionCount>::apply(p1, p2, mbr);
+ }
+
+ template <typename Segment, typename Box>
+ static inline void apply(Segment const& segment, Box& mbr)
+ {
+ 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]);
+ apply(p[0], p[1], mbr);
+ }
+};
+
+
+
+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
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Segment, typename CS_Tag>
+struct envelope<Segment, segment_tag, CS_Tag>
+{
+ template <typename Box>
+ static inline void apply(Segment const& segment, Box& mbr)
+ {
+ 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);
+ }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_SEGMENT_HPP
diff --git a/boost/geometry/algorithms/detail/envelope/transform_units.hpp b/boost/geometry/algorithms/detail/envelope/transform_units.hpp
new file mode 100644
index 0000000000..0c5382a47b
--- /dev/null
+++ b/boost/geometry/algorithms/detail/envelope/transform_units.hpp
@@ -0,0 +1,103 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under 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_ENVELOPE_TRANSFORM_UNITS_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_TRANSFORM_UNITS_HPP
+
+#include <cstddef>
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/strategies/strategy_transform.hpp>
+
+#include <boost/geometry/views/detail/indexed_point_view.hpp>
+#include <boost/geometry/views/detail/two_dimensional_view.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.hpp>
+#include <boost/geometry/algorithms/transform.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+template
+<
+ typename GeometryIn,
+ typename GeometryOut,
+ typename TagIn = typename tag<GeometryIn>::type,
+ typename TagOut = typename tag<GeometryOut>::type
+>
+struct transform_units_impl
+ : not_implemented<TagIn, TagOut>
+{};
+
+template <typename PointIn, typename PointOut>
+struct transform_units_impl<PointIn, PointOut, point_tag, point_tag>
+{
+ static inline void apply(PointIn const& point_in, PointOut& point_out)
+ {
+ detail::two_dimensional_view<PointIn const> view_in(point_in);
+ detail::two_dimensional_view<PointOut> view_out(point_out);
+
+ geometry::transform(view_in, view_out);
+ }
+};
+
+template <typename BoxIn, typename BoxOut>
+struct transform_units_impl<BoxIn, BoxOut, box_tag, box_tag>
+{
+ template <std::size_t Index>
+ static inline void apply(BoxIn const& box_in, BoxOut& box_out)
+ {
+ typedef detail::indexed_point_view<BoxIn const, Index> view_in_type;
+ typedef detail::indexed_point_view<BoxOut, Index> view_out_type;
+
+ view_in_type view_in(box_in);
+ view_out_type view_out(box_out);
+
+ transform_units_impl
+ <
+ view_in_type, view_out_type
+ >::apply(view_in, view_out);
+ }
+
+ static inline void apply(BoxIn const& box_in, BoxOut& box_out)
+ {
+ apply<min_corner>(box_in, box_out);
+ apply<max_corner>(box_in, box_out);
+ }
+};
+
+
+// Short utility to transform the units of the first two coordinates of
+// geometry_in to the units of geometry_out
+template <typename GeometryIn, typename GeometryOut>
+inline void transform_units(GeometryIn const& geometry_in,
+ GeometryOut& geometry_out)
+{
+ transform_units_impl
+ <
+ GeometryIn, GeometryOut
+ >::apply(geometry_in, geometry_out);
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost:geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_TRANSFORM_UNITS_HPP
diff --git a/boost/geometry/algorithms/detail/expand/box.hpp b/boost/geometry/algorithms/detail/expand/box.hpp
new file mode 100644
index 0000000000..4c89e6f1d4
--- /dev/null
+++ b/boost/geometry/algorithms/detail/expand/box.hpp
@@ -0,0 +1,126 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// 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 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under 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_EXPAND_BOX_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_BOX_HPP
+
+#include <cstddef>
+#include <algorithm>
+
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/box.hpp>
+#include <boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp>
+
+#include <boost/geometry/algorithms/detail/expand/indexed.hpp>
+
+#include <boost/geometry/algorithms/dispatch/expand.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace expand
+{
+
+
+struct box_on_spheroid
+{
+ template <typename BoxOut, typename BoxIn>
+ static inline void apply(BoxOut& box_out, BoxIn const& box_in)
+ {
+ // 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]);
+
+ // compute the envelope of the two boxes
+ detail::envelope::envelope_range_of_boxes::apply(mbrs, box_out);
+ }
+};
+
+
+}} // namespace detail::expand
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+// Box + box -> new box containing two input boxes
+template
+<
+ typename BoxOut, typename BoxIn,
+ typename StrategyLess, typename StrategyGreater,
+ typename CSTagOut, typename CSTag
+>
+struct expand
+ <
+ BoxOut, BoxIn,
+ StrategyLess, StrategyGreater,
+ box_tag, box_tag,
+ CSTagOut, CSTag
+ > : detail::expand::expand_indexed
+ <
+ 0, dimension<BoxIn>::value, StrategyLess, StrategyGreater
+ >
+{
+ BOOST_MPL_ASSERT_MSG((boost::is_same<CSTagOut, CSTag>::value),
+ COORDINATE_SYSTEMS_MUST_BE_THE_SAME,
+ (types<CSTagOut, CSTag>()));
+};
+
+template
+<
+ typename BoxOut, typename BoxIn,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand
+ <
+ BoxOut, BoxIn,
+ StrategyLess, StrategyGreater,
+ box_tag, box_tag,
+ spherical_equatorial_tag, spherical_equatorial_tag
+ > : detail::expand::box_on_spheroid
+{};
+
+template
+<
+ typename BoxOut, typename BoxIn,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand
+ <
+ BoxOut, BoxIn,
+ StrategyLess, StrategyGreater,
+ box_tag, box_tag,
+ geographic_tag, geographic_tag
+ > : detail::expand::box_on_spheroid
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INDEXED_HPP
diff --git a/boost/geometry/algorithms/detail/expand/implementation.hpp b/boost/geometry/algorithms/detail/expand/implementation.hpp
new file mode 100644
index 0000000000..95de1b5049
--- /dev/null
+++ b/boost/geometry/algorithms/detail/expand/implementation.hpp
@@ -0,0 +1,27 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// 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 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Distributed under 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_EXPAND_IMPLEMENTATION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_IMPLEMENTATION_HPP
+
+#include <boost/geometry/algorithms/detail/expand/point.hpp>
+#include <boost/geometry/algorithms/detail/expand/segment.hpp>
+#include <boost/geometry/algorithms/detail/expand/box.hpp>
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_IMPLEMENTATION_HPP
diff --git a/boost/geometry/algorithms/detail/expand/indexed.hpp b/boost/geometry/algorithms/detail/expand/indexed.hpp
new file mode 100644
index 0000000000..bdd6eb4506
--- /dev/null
+++ b/boost/geometry/algorithms/detail/expand/indexed.hpp
@@ -0,0 +1,144 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// 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 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Distributed under 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_EXPAND_INDEXED_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INDEXED_HPP
+
+#include <cstddef>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/util/select_coordinate_type.hpp>
+
+#include <boost/geometry/strategies/compare.hpp>
+#include <boost/geometry/policies/compare.hpp>
+
+#include <boost/geometry/algorithms/dispatch/expand.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace expand
+{
+
+
+template
+<
+ typename StrategyLess, typename StrategyGreater,
+ std::size_t Index,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct indexed_loop
+{
+ template <typename Box, typename Geometry>
+ static inline void apply(Box& box, Geometry const& source)
+ {
+ typedef typename strategy::compare::detail::select_strategy
+ <
+ StrategyLess, 1, Box, Dimension
+ >::type less_type;
+
+ typedef typename strategy::compare::detail::select_strategy
+ <
+ StrategyGreater, -1, Box, Dimension
+ >::type greater_type;
+
+ typedef typename select_coordinate_type
+ <
+ Box,
+ Geometry
+ >::type coordinate_type;
+
+ less_type less;
+ greater_type greater;
+
+ coordinate_type const coord = get<Index, Dimension>(source);
+
+ if (less(coord, get<min_corner, Dimension>(box)))
+ {
+ set<min_corner, Dimension>(box, coord);
+ }
+
+ if (greater(coord, get<max_corner, Dimension>(box)))
+ {
+ set<max_corner, Dimension>(box, coord);
+ }
+
+ indexed_loop
+ <
+ StrategyLess, StrategyGreater,
+ Index, Dimension + 1, DimensionCount
+ >::apply(box, source);
+ }
+};
+
+
+template
+<
+ typename StrategyLess, typename StrategyGreater,
+ std::size_t Index, std::size_t DimensionCount
+>
+struct indexed_loop
+ <
+ StrategyLess, StrategyGreater,
+ Index, DimensionCount, DimensionCount
+ >
+{
+ template <typename Box, typename Geometry>
+ static inline void apply(Box&, Geometry const&) {}
+};
+
+
+
+// Changes a box such that the other box is also contained by the box
+template
+<
+ std::size_t Dimension, std::size_t DimensionCount,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand_indexed
+{
+ template <typename Box, typename Geometry>
+ static inline void apply(Box& box, Geometry const& geometry)
+ {
+ indexed_loop
+ <
+ StrategyLess, StrategyGreater,
+ 0, Dimension, DimensionCount
+ >::apply(box, geometry);
+
+ indexed_loop
+ <
+ StrategyLess, StrategyGreater,
+ 1, Dimension, DimensionCount
+ >::apply(box, geometry);
+ }
+};
+
+
+}} // namespace detail::expand
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INDEXED_HPP
diff --git a/boost/geometry/algorithms/detail/expand/interface.hpp b/boost/geometry/algorithms/detail/expand/interface.hpp
new file mode 100644
index 0000000000..01936387a7
--- /dev/null
+++ b/boost/geometry/algorithms/detail/expand/interface.hpp
@@ -0,0 +1,128 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// 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 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Distributed under 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_EXPAND_INTERFACE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INTERFACE_HPP
+
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/algorithms/dispatch/expand.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace resolve_variant
+{
+
+template <typename Geometry>
+struct expand
+{
+ template <typename Box>
+ static inline void apply(Box& box, Geometry const& geometry)
+ {
+ concept::check<Box>();
+ concept::check<Geometry const>();
+ concept::check_concepts_and_equal_dimensions<Box, Geometry const>();
+
+ dispatch::expand<Box, Geometry>::apply(box, geometry);
+ }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct expand<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ template <typename Box>
+ struct visitor: boost::static_visitor<void>
+ {
+ Box& m_box;
+
+ visitor(Box& box) : m_box(box) {}
+
+ template <typename Geometry>
+ void operator()(Geometry const& geometry) const
+ {
+ return expand<Geometry>::apply(m_box, geometry);
+ }
+ };
+
+ template <class Box>
+ static inline void
+ apply(Box& box,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
+ {
+ return boost::apply_visitor(visitor<Box>(box), geometry);
+ }
+};
+
+} // namespace resolve_variant
+
+
+/***
+*!
+\brief Expands a box using the extend (envelope) of another geometry (box, point)
+\ingroup expand
+\tparam Box type of the box
+\tparam Geometry of second geometry, to be expanded with the box
+\param box box to expand another geometry with, might be changed
+\param geometry other geometry
+\param strategy_less
+\param strategy_greater
+\note Strategy is currently ignored
+ *
+template
+<
+ typename Box, typename Geometry,
+ typename StrategyLess, typename StrategyGreater
+>
+inline void expand(Box& box, Geometry const& geometry,
+ StrategyLess const& strategy_less,
+ StrategyGreater const& strategy_greater)
+{
+ concept::check_concepts_and_equal_dimensions<Box, Geometry const>();
+
+ dispatch::expand<Box, Geometry>::apply(box, geometry);
+}
+***/
+
+
+/*!
+\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
+
+\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);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INTERFACE_HPP
diff --git a/boost/geometry/algorithms/detail/expand/point.hpp b/boost/geometry/algorithms/detail/expand/point.hpp
new file mode 100644
index 0000000000..56b7f1c738
--- /dev/null
+++ b/boost/geometry/algorithms/detail/expand/point.hpp
@@ -0,0 +1,303 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// 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 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Distributed under 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_EXPAND_POINT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_POINT_HPP
+
+#include <cstddef>
+#include <algorithm>
+
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_coordinate_type.hpp>
+
+#include <boost/geometry/strategies/compare.hpp>
+#include <boost/geometry/policies/compare.hpp>
+
+#include <boost/geometry/algorithms/detail/normalize.hpp>
+#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
+
+#include <boost/geometry/algorithms/dispatch/expand.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace expand
+{
+
+
+template
+<
+ typename StrategyLess, typename StrategyGreater,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct point_loop
+{
+ template <typename Box, typename Point>
+ static inline void apply(Box& box, Point const& source)
+ {
+ typedef typename strategy::compare::detail::select_strategy
+ <
+ StrategyLess, 1, Point, Dimension
+ >::type less_type;
+
+ typedef typename strategy::compare::detail::select_strategy
+ <
+ StrategyGreater, -1, Point, Dimension
+ >::type greater_type;
+
+ typedef typename select_coordinate_type
+ <
+ Point, Box
+ >::type coordinate_type;
+
+ less_type less;
+ greater_type greater;
+
+ coordinate_type const coord = get<Dimension>(source);
+
+ if (less(coord, get<min_corner, Dimension>(box)))
+ {
+ set<min_corner, Dimension>(box, coord);
+ }
+
+ if (greater(coord, get<max_corner, Dimension>(box)))
+ {
+ set<max_corner, Dimension>(box, coord);
+ }
+
+ point_loop
+ <
+ StrategyLess, StrategyGreater, Dimension + 1, DimensionCount
+ >::apply(box, source);
+ }
+};
+
+
+template
+<
+ 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&) {}
+};
+
+
+// implementation for the spherical equatorial and geographic coordinate systems
+template
+<
+ typename StrategyLess,
+ typename StrategyGreater,
+ std::size_t DimensionCount
+>
+struct point_loop_on_spheroid
+{
+ template <typename Box, typename Point>
+ static inline void apply(Box& box, Point const& point)
+ {
+ typedef typename point_type<Box>::type box_point_type;
+ typedef typename coordinate_type<Box>::type box_coordinate_type;
+
+ typedef math::detail::constants_on_spheroid
+ <
+ box_coordinate_type,
+ typename coordinate_system<Box>::type::units
+ > constants;
+
+ // normalize input point and input box
+ Point p_normalized = detail::return_normalized<Point>(point);
+ detail::normalize(box, box);
+
+ // transform input point to be of the same type as the box point
+ box_point_type box_point;
+ detail::envelope::transform_units(p_normalized, box_point);
+
+ box_coordinate_type p_lon = geometry::get<0>(box_point);
+ box_coordinate_type p_lat = geometry::get<1>(box_point);
+
+ typename coordinate_type<Box>::type
+ b_lon_min = geometry::get<min_corner, 0>(box),
+ b_lat_min = geometry::get<min_corner, 1>(box),
+ b_lon_max = geometry::get<max_corner, 0>(box),
+ b_lat_max = geometry::get<max_corner, 1>(box);
+
+ if (math::equals(math::abs(p_lat), constants::max_latitude()))
+ {
+ // the point of expansion is the either the north or the
+ // south pole; the only important coordinate here is the
+ // pole's latitude, as the longitude can be anything;
+ // we, thus, take into account the point's latitude only and return
+ geometry::set<min_corner, 1>(box, (std::min)(p_lat, b_lat_min));
+ geometry::set<max_corner, 1>(box, (std::max)(p_lat, b_lat_max));
+ return;
+ }
+
+ if (math::equals(b_lat_min, b_lat_max)
+ && math::equals(math::abs(b_lat_min), constants::max_latitude()))
+ {
+ // the box degenerates to either the north or the south pole;
+ // the only important coordinate here is the pole's latitude,
+ // as the longitude can be anything;
+ // we thus take into account the box's latitude only and return
+ geometry::set<min_corner, 0>(box, p_lon);
+ geometry::set<min_corner, 1>(box, (std::min)(p_lat, b_lat_min));
+ geometry::set<max_corner, 0>(box, p_lon);
+ geometry::set<max_corner, 1>(box, (std::max)(p_lat, b_lat_max));
+ return;
+ }
+
+ // update latitudes
+ b_lat_min = (std::min)(b_lat_min, p_lat);
+ b_lat_max = (std::max)(b_lat_max, p_lat);
+
+ // update longitudes
+ if (math::smaller(p_lon, b_lon_min))
+ {
+ box_coordinate_type p_lon_shifted = p_lon + constants::period();
+
+ if (math::larger(p_lon_shifted, b_lon_max))
+ {
+ // here we could check using: ! math::larger(.., ..)
+ if (math::smaller(b_lon_min - p_lon, p_lon_shifted - b_lon_max))
+ {
+ b_lon_min = p_lon;
+ }
+ else
+ {
+ b_lon_max = p_lon_shifted;
+ }
+ }
+ }
+ else if (math::larger(p_lon, b_lon_max))
+ {
+ // in this case, and since p_lon is normalized in the range
+ // (-180, 180], we must have that b_lon_max <= 180
+ if (b_lon_min < 0
+ && math::larger(p_lon - b_lon_max,
+ constants::period() - p_lon + b_lon_min))
+ {
+ b_lon_min = p_lon;
+ b_lon_max += constants::period();
+ }
+ else
+ {
+ b_lon_max = p_lon;
+ }
+ }
+
+ geometry::set<min_corner, 0>(box, b_lon_min);
+ geometry::set<min_corner, 1>(box, b_lat_min);
+ geometry::set<max_corner, 0>(box, b_lon_max);
+ geometry::set<max_corner, 1>(box, b_lat_max);
+
+ point_loop
+ <
+ StrategyLess, StrategyGreater, 2, DimensionCount
+ >::apply(box, point);
+ }
+};
+
+
+}} // namespace detail::expand
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+// Box + point -> new box containing also point
+template
+<
+ typename BoxOut, typename Point,
+ typename StrategyLess, typename StrategyGreater,
+ typename CSTagOut, typename CSTag
+>
+struct expand
+ <
+ BoxOut, Point,
+ StrategyLess, StrategyGreater,
+ box_tag, point_tag,
+ CSTagOut, CSTag
+ > : detail::expand::point_loop
+ <
+ StrategyLess, StrategyGreater, 0, dimension<Point>::value
+ >
+{
+ BOOST_MPL_ASSERT_MSG((boost::is_same<CSTagOut, CSTag>::value),
+ COORDINATE_SYSTEMS_MUST_BE_THE_SAME,
+ (types<CSTagOut, CSTag>()));
+};
+
+template
+<
+ typename BoxOut, typename Point,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand
+ <
+ BoxOut, Point,
+ StrategyLess, StrategyGreater,
+ box_tag, point_tag,
+ spherical_equatorial_tag, spherical_equatorial_tag
+ > : detail::expand::point_loop_on_spheroid
+ <
+ StrategyLess, StrategyGreater, dimension<Point>::value
+ >
+{};
+
+template
+<
+ typename BoxOut, typename Point,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand
+ <
+ BoxOut, Point,
+ StrategyLess, StrategyGreater,
+ box_tag, point_tag,
+ geographic_tag, geographic_tag
+ > : detail::expand::point_loop_on_spheroid
+ <
+ StrategyLess, StrategyGreater, dimension<Point>::value
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_POINT_HPP
diff --git a/boost/geometry/algorithms/detail/expand/segment.hpp b/boost/geometry/algorithms/detail/expand/segment.hpp
new file mode 100644
index 0000000000..041c1e175f
--- /dev/null
+++ b/boost/geometry/algorithms/detail/expand/segment.hpp
@@ -0,0 +1,115 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// 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 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Distributed under 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_EXPAND_SEGMENT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_SEGMENT_HPP
+
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/box.hpp>
+#include <boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp>
+#include <boost/geometry/algorithms/detail/envelope/segment.hpp>
+
+#include <boost/geometry/algorithms/detail/expand/indexed.hpp>
+
+#include <boost/geometry/algorithms/dispatch/expand.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace expand
+{
+
+
+struct segment_on_sphere
+{
+ template <typename Box, typename Segment>
+ static inline void apply(Box& box, Segment const& segment)
+ {
+ Box mbrs[2];
+
+ // compute the envelope of the segment
+ detail::envelope::envelope_segment_on_sphere
+ <
+ dimension<Segment>::value
+ >::apply(segment, mbrs[0]);
+
+ // normalize the box
+ detail::envelope::envelope_box_on_spheroid::apply(box, mbrs[1]);
+
+ // compute the envelope of the two boxes
+ detail::envelope::envelope_range_of_boxes::apply(mbrs, box);
+ }
+};
+
+
+}} // namespace detail::expand
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename Box, typename Segment,
+ typename StrategyLess, typename StrategyGreater,
+ typename CSTagOut, typename CSTag
+>
+struct expand
+ <
+ Box, Segment,
+ StrategyLess, StrategyGreater,
+ box_tag, segment_tag,
+ CSTagOut, CSTag
+ > : detail::expand::expand_indexed
+ <
+ 0, dimension<Segment>::value, StrategyLess, StrategyGreater
+ >
+{
+ BOOST_MPL_ASSERT_MSG((boost::is_same<CSTagOut, CSTag>::value),
+ COORDINATE_SYSTEMS_MUST_BE_THE_SAME,
+ (types<CSTagOut, CSTag>()));
+};
+
+template
+<
+ typename Box, typename Segment,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand
+ <
+ Box, Segment,
+ StrategyLess, StrategyGreater,
+ box_tag, segment_tag,
+ spherical_equatorial_tag, spherical_equatorial_tag
+ > : detail::expand::segment_on_sphere
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_SEGMENT_HPP
diff --git a/boost/geometry/algorithms/detail/get_left_turns.hpp b/boost/geometry/algorithms/detail/get_left_turns.hpp
index 0fd243d8e3..95ab98c236 100644
--- a/boost/geometry/algorithms/detail/get_left_turns.hpp
+++ b/boost/geometry/algorithms/detail/get_left_turns.hpp
@@ -9,6 +9,8 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_LEFT_TURNS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_LEFT_TURNS_HPP
+#include <boost/geometry/core/assert.hpp>
+
#include <boost/geometry/arithmetic/arithmetic.hpp>
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
@@ -154,8 +156,8 @@ template <typename AngleCollection, typename Turns>
inline void get_left_turns(AngleCollection const& sorted_angles,
Turns& turns)
{
- std::set<int> good_incoming;
- std::set<int> good_outgoing;
+ std::set<std::size_t> good_incoming;
+ std::set<std::size_t> good_outgoing;
for (typename boost::range_iterator<AngleCollection const>::type it =
sorted_angles.begin(); it != sorted_angles.end(); ++it)
@@ -195,7 +197,7 @@ template <typename Point, typename AngleCollection>
inline std::size_t assign_cluster_indices(AngleCollection& sorted, Point const& origin)
{
// Assign same cluster_index for all turns in same direction
- BOOST_ASSERT(boost::size(sorted) >= 4u);
+ BOOST_GEOMETRY_ASSERT(boost::size(sorted) >= 4u);
angle_equal_to<Point> comparator(origin);
typename boost::range_iterator<AngleCollection>::type it = sorted.begin();
@@ -218,7 +220,7 @@ inline std::size_t assign_cluster_indices(AngleCollection& sorted, Point const&
template <typename AngleCollection>
inline void block_turns(AngleCollection& sorted, std::size_t cluster_size)
{
- BOOST_ASSERT(boost::size(sorted) >= 4u && cluster_size > 0);
+ BOOST_GEOMETRY_ASSERT(boost::size(sorted) >= 4u && cluster_size > 0);
std::vector<std::pair<bool, bool> > directions;
for (std::size_t i = 0; i < cluster_size; i++)
@@ -242,14 +244,14 @@ inline void block_turns(AngleCollection& sorted, std::size_t cluster_size)
for (typename boost::range_iterator<AngleCollection>::type it = sorted.begin();
it != sorted.end(); ++it)
{
- int cluster_index = it->cluster_index;
- int previous_index = cluster_index - 1;
+ signed_size_type cluster_index = static_cast<signed_size_type>(it->cluster_index);
+ signed_size_type previous_index = cluster_index - 1;
if (previous_index < 0)
{
previous_index = cluster_size - 1;
}
- int next_index = cluster_index + 1;
- if (next_index >= static_cast<int>(cluster_size))
+ signed_size_type next_index = cluster_index + 1;
+ if (next_index >= static_cast<signed_size_type>(cluster_size))
{
next_index = 0;
}
diff --git a/boost/geometry/algorithms/detail/intersection/interface.hpp b/boost/geometry/algorithms/detail/intersection/interface.hpp
index d57535e61f..2af618d974 100644
--- a/boost/geometry/algorithms/detail/intersection/interface.hpp
+++ b/boost/geometry/algorithms/detail/intersection/interface.hpp
@@ -120,7 +120,8 @@ struct intersection
>::type rescale_policy_type;
rescale_policy_type robust_policy
- = geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
+ = geometry::get_rescale_policy<rescale_policy_type>(geometry1,
+ geometry2);
typedef strategy_intersection
<
@@ -151,8 +152,8 @@ struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
visitor(Geometry2 const& geometry2,
GeometryOut& geometry_out)
- : m_geometry2(geometry2),
- m_geometry_out(geometry_out)
+ : m_geometry2(geometry2)
+ , m_geometry_out(geometry_out)
{}
template <typename Geometry1>
@@ -176,7 +177,7 @@ struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
Geometry2 const& geometry2,
GeometryOut& geometry_out)
{
- return apply_visitor(visitor<GeometryOut>(geometry2, geometry_out), geometry1);
+ return boost::apply_visitor(visitor<GeometryOut>(geometry2, geometry_out), geometry1);
}
};
@@ -192,8 +193,8 @@ struct intersection<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
visitor(Geometry1 const& geometry1,
GeometryOut& geometry_out)
- : m_geometry1(geometry1),
- m_geometry_out(geometry_out)
+ : m_geometry1(geometry1)
+ , m_geometry_out(geometry_out)
{}
template <typename Geometry2>
@@ -213,12 +214,11 @@ struct intersection<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
template <typename GeometryOut>
static inline bool
- apply(
- Geometry1 const& geometry1,
+ apply(Geometry1 const& geometry1,
const variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry2,
GeometryOut& geometry_out)
{
- return apply_visitor(visitor<GeometryOut>(geometry1, geometry_out), geometry2);
+ return boost::apply_visitor(visitor<GeometryOut>(geometry1, geometry_out), geometry2);
}
};
@@ -232,12 +232,11 @@ struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIAN
GeometryOut& m_geometry_out;
visitor(GeometryOut& geometry_out)
- : m_geometry_out(geometry_out)
+ : m_geometry_out(geometry_out)
{}
template <typename Geometry1, typename Geometry2>
- result_type operator()(
- Geometry1 const& geometry1,
+ result_type operator()(Geometry1 const& geometry1,
Geometry2 const& geometry2) const
{
return intersection
@@ -254,12 +253,11 @@ struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIAN
template <typename GeometryOut>
static inline bool
- apply(
- const variant<BOOST_VARIANT_ENUM_PARAMS(T1)>& geometry1,
+ apply(const variant<BOOST_VARIANT_ENUM_PARAMS(T1)>& geometry1,
const variant<BOOST_VARIANT_ENUM_PARAMS(T2)>& geometry2,
GeometryOut& geometry_out)
{
- return apply_visitor(visitor<GeometryOut>(geometry_out), geometry1, geometry2);
+ return boost::apply_visitor(visitor<GeometryOut>(geometry_out), geometry1, geometry2);
}
};
diff --git a/boost/geometry/algorithms/detail/intersection/multi.hpp b/boost/geometry/algorithms/detail/intersection/multi.hpp
index b1f13862fc..88b49b0167 100644
--- a/boost/geometry/algorithms/detail/intersection/multi.hpp
+++ b/boost/geometry/algorithms/detail/intersection/multi.hpp
@@ -1,9 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+// Modifications copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -36,8 +36,6 @@
#include <boost/geometry/algorithms/envelope.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
-// TODO: remove this after moving num_point from multi directory
-#include <boost/geometry/multi/algorithms/num_points.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/algorithms/detail/is_simple/linear.hpp b/boost/geometry/algorithms/detail/is_simple/linear.hpp
index 4f3e875eef..0f77a49498 100644
--- a/boost/geometry/algorithms/detail/is_simple/linear.hpp
+++ b/boost/geometry/algorithms/detail/is_simple/linear.hpp
@@ -13,9 +13,9 @@
#include <algorithm>
#include <deque>
-#include <boost/assert.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/point_type.hpp>
@@ -33,7 +33,7 @@
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
-#include <boost/geometry/algorithms/detail/signed_index_type.hpp>
+#include <boost/geometry/algorithms/detail/signed_size_type.hpp>
#include <boost/geometry/algorithms/detail/disjoint/linear_linear.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
@@ -60,7 +60,7 @@ namespace detail { namespace is_simple
template <typename Turn>
inline bool check_segment_indices(Turn const& turn,
- signed_index_type last_index)
+ signed_size_type last_index)
{
return
(turn.operations[0].seg_id.segment_index == 0
@@ -89,7 +89,7 @@ public:
template <typename Turn>
inline bool apply(Turn const& turn) const
{
- BOOST_ASSERT(boost::size(m_linestring) > 1);
+ BOOST_GEOMETRY_ASSERT(boost::size(m_linestring) > 1);
return m_is_closed
&& turn.method == overlay::method_none
&& check_segment_indices(turn, boost::size(m_linestring) - 2)
@@ -112,7 +112,7 @@ private:
static inline bool is_boundary_point_of(Point const& point,
Linestring const& linestring)
{
- BOOST_ASSERT(boost::size(linestring) > 1);
+ BOOST_GEOMETRY_ASSERT(boost::size(linestring) > 1);
return
! geometry::equals(range::front(linestring),
range::back(linestring))
@@ -125,7 +125,7 @@ private:
static inline bool is_closing_point_of(Turn const& turn,
Linestring const& linestring)
{
- BOOST_ASSERT(boost::size(linestring) > 1);
+ BOOST_GEOMETRY_ASSERT(boost::size(linestring) > 1);
return
turn.method == overlay::method_none
&&
diff --git a/boost/geometry/algorithms/detail/is_valid/box.hpp b/boost/geometry/algorithms/detail/is_valid/box.hpp
index 139502af78..e7a67252ba 100644
--- a/boost/geometry/algorithms/detail/is_valid/box.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/box.hpp
@@ -3,6 +3,7 @@
// Copyright (c) 2014-2015, 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
@@ -12,6 +13,8 @@
#include <cstddef>
+#include <boost/core/ignore_unused.hpp>
+
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
@@ -57,6 +60,8 @@ struct has_valid_corners<Box, 0>
template <typename VisitPolicy>
static inline bool apply(Box const&, VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
+
return visitor.template apply<no_failure>();
}
};
diff --git a/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp b/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp
index c59139a92e..f08e70242c 100644
--- a/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp
@@ -17,9 +17,9 @@
#include <utility>
#include <vector>
-#include <boost/assert.hpp>
#include <boost/core/addressof.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/policies/compare.hpp>
@@ -104,12 +104,12 @@ private:
, m_parent_id(num_nodes, -1)
{}
- inline signed_index_type parent_id(vertex_handle v) const
+ inline signed_size_type parent_id(vertex_handle v) const
{
return m_parent_id[v->id()];
}
- inline void set_parent_id(vertex_handle v, signed_index_type id)
+ inline void set_parent_id(vertex_handle v, signed_size_type id)
{
m_parent_id[v->id()] = id;
}
@@ -125,7 +125,7 @@ private:
}
private:
std::vector<bool> m_visited;
- std::vector<signed_index_type> m_parent_id;
+ std::vector<signed_size_type> m_parent_id;
};
@@ -145,7 +145,7 @@ private:
= m_neighbors[v->id()].begin();
nit != m_neighbors[v->id()].end(); ++nit)
{
- if ( static_cast<signed_index_type>((*nit)->id()) != data.parent_id(v) )
+ if ( static_cast<signed_size_type>((*nit)->id()) != data.parent_id(v) )
{
if ( data.visited(*nit) )
{
@@ -153,7 +153,7 @@ private:
}
else
{
- data.set_parent_id(*nit, static_cast<signed_index_type>(v->id()));
+ data.set_parent_id(*nit, static_cast<signed_size_type>(v->id()));
stack.push(*nit);
}
}
@@ -173,7 +173,7 @@ public:
// inserts a ring vertex in the graph and returns its handle
// ring id's are zero-based (so the first interior ring has id 1)
- inline vertex_handle add_vertex(signed_index_type id)
+ inline vertex_handle add_vertex(signed_size_type id)
{
return m_vertices.insert(vertex(static_cast<std::size_t>(id))).first;
}
@@ -197,8 +197,8 @@ public:
inline void add_edge(vertex_handle v1, vertex_handle v2)
{
- BOOST_ASSERT( v1 != m_vertices.end() );
- BOOST_ASSERT( v2 != m_vertices.end() );
+ BOOST_GEOMETRY_ASSERT( v1 != m_vertices.end() );
+ BOOST_GEOMETRY_ASSERT( v2 != m_vertices.end() );
m_neighbors[v1->id()].insert(v2);
m_neighbors[v2->id()].insert(v1);
}
diff --git a/boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp b/boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp
index 5878841e70..685a4aac35 100644
--- a/boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp
@@ -10,6 +10,7 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_DUPLICATES_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_DUPLICATES_HPP
+#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/closure.hpp>
@@ -35,8 +36,13 @@ struct has_duplicates
template <typename VisitPolicy>
static inline bool apply(Range const& range, VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
+
typedef typename closeable_view<Range const, Closure>::type view_type;
- typedef typename boost::range_iterator<view_type const>::type iterator;
+ typedef typename boost::range_const_iterator
+ <
+ view_type const
+ >::type const_iterator;
view_type view(range);
@@ -47,9 +53,10 @@ struct has_duplicates
geometry::equal_to<typename boost::range_value<Range>::type> equal;
- iterator it = boost::begin(view);
- iterator next = ++boost::begin(view);
- for (; next != boost::end(view); ++it, ++next)
+ const_iterator it = boost::const_begin(view);
+ const_iterator next = it;
+ ++next;
+ for (; next != boost::const_end(view); ++it, ++next)
{
if ( equal(*it, *next) )
{
diff --git a/boost/geometry/algorithms/detail/is_valid/has_spikes.hpp b/boost/geometry/algorithms/detail/is_valid/has_spikes.hpp
index 090c026e8b..aa90e52db6 100644
--- a/boost/geometry/algorithms/detail/is_valid/has_spikes.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/has_spikes.hpp
@@ -12,9 +12,11 @@
#include <algorithm>
+#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
#include <boost/type_traits/is_same.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -76,10 +78,23 @@ struct not_equal_to
template <typename Range, closure_selector Closure>
struct has_spikes
{
+ template <typename Iterator>
+ static inline Iterator find_different_from_first(Iterator first,
+ Iterator last)
+ {
+ typedef not_equal_to<typename point_type<Range>::type> not_equal;
+
+ BOOST_GEOMETRY_ASSERT(first != last);
+
+ Iterator second = first;
+ ++second;
+ return std::find_if(second, last, not_equal(*first));
+ }
+
template <typename VisitPolicy>
static inline bool apply(Range const& range, VisitPolicy& visitor)
{
- typedef not_equal_to<typename point_type<Range>::type> not_equal;
+ boost::ignore_unused(visitor);
typedef typename closeable_view<Range const, Closure>::type view_type;
typedef typename boost::range_iterator<view_type const>::type iterator;
@@ -91,23 +106,23 @@ struct has_spikes
iterator prev = boost::begin(view);
- iterator cur = std::find_if(prev, boost::end(view), not_equal(*prev));
- if ( cur == boost::end(view) )
+ iterator cur = find_different_from_first(prev, boost::end(view));
+ if (cur == boost::end(view))
{
// the range has only one distinct point, so it
// cannot have a spike
return ! visitor.template apply<no_failure>();
}
- iterator next = std::find_if(cur, boost::end(view), not_equal(*cur));
- if ( next == boost::end(view) )
+ iterator next = find_different_from_first(cur, boost::end(view));
+ if (next == boost::end(view))
{
// the range has only two distinct points, so it
// cannot have a spike
return ! visitor.template apply<no_failure>();
}
- while ( next != boost::end(view) )
+ while (next != boost::end(view))
{
if ( geometry::detail::point_is_spike_or_equal(*prev,
*next,
@@ -118,20 +133,19 @@ struct has_spikes
}
prev = cur;
cur = next;
- next = std::find_if(cur, boost::end(view), not_equal(*cur));
+ next = find_different_from_first(cur, boost::end(view));
}
- if ( geometry::equals(range::front(view), range::back(view)) )
+ if (geometry::equals(range::front(view), range::back(view)))
{
iterator cur = boost::begin(view);
typename boost::range_reverse_iterator
<
view_type const
- >::type prev = std::find_if(boost::rbegin(view),
- boost::rend(view),
- not_equal(range::back(view)));
- iterator next =
- std::find_if(cur, boost::end(view), not_equal(*cur));
+ >::type prev = find_different_from_first(boost::rbegin(view),
+ boost::rend(view));
+
+ iterator next = find_different_from_first(cur, boost::end(view));
if (detail::point_is_spike_or_equal(*prev, *next, *cur))
{
return
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 ecbc4782b2..0a81213743 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
@@ -12,9 +12,10 @@
#include <vector>
-#include <boost/assert.hpp>
+#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/policies/predicate_based_interrupt_policy.hpp>
@@ -73,6 +74,8 @@ public:
Turns& turns,
VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
+
rescale_policy_type robust_policy
= geometry::get_rescale_policy<rescale_policy_type>(geometry);
@@ -88,7 +91,7 @@ public:
if (interrupt_policy.has_intersections)
{
- BOOST_ASSERT(! boost::empty(turns));
+ BOOST_GEOMETRY_ASSERT(! boost::empty(turns));
return visitor.template apply<failure_self_intersections>(turns);
}
else
diff --git a/boost/geometry/algorithms/detail/is_valid/interface.hpp b/boost/geometry/algorithms/detail/is_valid/interface.hpp
index f83b09c437..0ec13b1b38 100644
--- a/boost/geometry/algorithms/detail/is_valid/interface.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/interface.hpp
@@ -97,7 +97,7 @@ template <typename Geometry>
inline bool is_valid(Geometry const& geometry)
{
is_valid_default_policy<> policy_visitor;
- return is_valid(geometry, policy_visitor);
+ return geometry::is_valid(geometry, policy_visitor);
}
@@ -121,7 +121,7 @@ template <typename Geometry>
inline bool is_valid(Geometry const& geometry, validity_failure_type& failure)
{
failure_type_policy<> policy_visitor;
- bool result = is_valid(geometry, policy_visitor);
+ bool result = geometry::is_valid(geometry, policy_visitor);
failure = policy_visitor.failure();
return result;
}
@@ -148,7 +148,7 @@ inline bool is_valid(Geometry const& geometry, std::string& message)
{
std::ostringstream stream;
failing_reason_policy<> policy_visitor(stream);
- bool result = is_valid(geometry, policy_visitor);
+ bool result = geometry::is_valid(geometry, policy_visitor);
message = stream.str();
return result;
}
diff --git a/boost/geometry/algorithms/detail/is_valid/linear.hpp b/boost/geometry/algorithms/detail/is_valid/linear.hpp
index 69243563ec..e30064faf0 100644
--- a/boost/geometry/algorithms/detail/is_valid/linear.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/linear.hpp
@@ -3,6 +3,7 @@
// Copyright (c) 2014-2015, 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
@@ -18,6 +19,7 @@
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/algorithms/equals.hpp>
@@ -138,7 +140,8 @@ public:
static inline bool apply(MultiLinestring const& multilinestring,
VisitPolicy& visitor)
{
- if (AllowEmptyMultiGeometries && boost::empty(multilinestring))
+ if (BOOST_GEOMETRY_CONDITION(
+ AllowEmptyMultiGeometries && boost::empty(multilinestring)))
{
return visitor.template apply<no_failure>();
}
diff --git a/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp b/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp
index 9362bfca0e..0025445c2c 100644
--- a/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp
@@ -3,6 +3,7 @@
// Copyright (c) 2014-2015, 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
@@ -13,6 +14,7 @@
#include <deque>
#include <vector>
+#include <boost/core/ignore_unused.hpp>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/range.hpp>
@@ -21,6 +23,7 @@
#include <boost/geometry/core/ring_type.hpp>
#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/geometries/box.hpp>
@@ -80,8 +83,10 @@ private:
TurnIterator turns_beyond,
VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
+
// collect all polygons that have turns
- std::set<signed_index_type> multi_indices;
+ std::set<signed_size_type> multi_indices;
for (TurnIterator tit = turns_first; tit != turns_beyond; ++tit)
{
multi_indices.insert(tit->operations[0].seg_id.multi_index);
@@ -90,7 +95,7 @@ private:
// put polygon iterators without turns in a vector
std::vector<PolygonIterator> polygon_iterators;
- signed_index_type multi_index = 0;
+ signed_size_type multi_index = 0;
for (PolygonIterator it = polygons_first; it != polygons_beyond;
++it, ++multi_index)
{
@@ -124,7 +129,7 @@ private:
class has_multi_index
{
public:
- has_multi_index(signed_index_type multi_index)
+ has_multi_index(signed_size_type multi_index)
: m_multi_index(multi_index)
{}
@@ -136,7 +141,7 @@ private:
}
private:
- signed_index_type const m_multi_index;
+ signed_size_type const m_multi_index;
};
@@ -156,7 +161,7 @@ private:
TurnIterator turns_beyond,
VisitPolicy& visitor)
{
- signed_index_type multi_index = 0;
+ signed_size_type multi_index = 0;
for (PolygonIterator it = polygons_first; it != polygons_beyond;
++it, ++multi_index)
{
@@ -250,7 +255,8 @@ public:
{
typedef debug_validity_phase<MultiPolygon> debug_phase;
- if (AllowEmptyMultiGeometries && boost::empty(multipolygon))
+ if (BOOST_GEOMETRY_CONDITION(
+ AllowEmptyMultiGeometries && boost::empty(multipolygon)))
{
return visitor.template apply<no_failure>();
}
diff --git a/boost/geometry/algorithms/detail/is_valid/pointlike.hpp b/boost/geometry/algorithms/detail/is_valid/pointlike.hpp
index 8e5ebaadcc..e51ab74643 100644
--- a/boost/geometry/algorithms/detail/is_valid/pointlike.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/pointlike.hpp
@@ -3,6 +3,7 @@
// Copyright (c) 2014-2015, 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
@@ -10,6 +11,7 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_POINTLIKE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_POINTLIKE_HPP
+#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -17,6 +19,8 @@
#include <boost/geometry/algorithms/validity_failure_type.hpp>
#include <boost/geometry/algorithms/dispatch/is_valid.hpp>
+#include <boost/geometry/util/condition.hpp>
+
namespace boost { namespace geometry
{
@@ -34,6 +38,7 @@ struct is_valid<Point, point_tag>
template <typename VisitPolicy>
static inline bool apply(Point const&, VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
return visitor.template apply<no_failure>();
}
};
@@ -51,7 +56,10 @@ struct is_valid<MultiPoint, multi_point_tag, AllowEmptyMultiGeometries>
static inline bool apply(MultiPoint const& multipoint,
VisitPolicy& visitor)
{
- if (AllowEmptyMultiGeometries || boost::size(multipoint) > 0)
+ boost::ignore_unused(multipoint, visitor);
+
+ if (BOOST_GEOMETRY_CONDITION(
+ AllowEmptyMultiGeometries || !boost::empty(multipoint)))
{
// we allow empty multi-geometries, so an empty multipoint
// is considered valid
diff --git a/boost/geometry/algorithms/detail/is_valid/polygon.hpp b/boost/geometry/algorithms/detail/is_valid/polygon.hpp
index 17eefd226f..6e87273aa1 100644
--- a/boost/geometry/algorithms/detail/is_valid/polygon.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/polygon.hpp
@@ -18,9 +18,10 @@
#include <set>
#include <vector>
-#include <boost/assert.hpp>
+#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/ring_type.hpp>
@@ -185,24 +186,26 @@ protected:
TurnIterator turns_beyond,
VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
+
// collect the interior ring indices that have turns with the
// exterior ring
- std::set<signed_index_type> ring_indices;
+ std::set<signed_size_type> ring_indices;
for (TurnIterator tit = turns_first; tit != turns_beyond; ++tit)
{
if (tit->operations[0].seg_id.ring_index == -1)
{
- BOOST_ASSERT(tit->operations[1].seg_id.ring_index != -1);
+ BOOST_GEOMETRY_ASSERT(tit->operations[1].seg_id.ring_index != -1);
ring_indices.insert(tit->operations[1].seg_id.ring_index);
}
else if (tit->operations[1].seg_id.ring_index == -1)
{
- BOOST_ASSERT(tit->operations[0].seg_id.ring_index != -1);
+ BOOST_GEOMETRY_ASSERT(tit->operations[0].seg_id.ring_index != -1);
ring_indices.insert(tit->operations[0].seg_id.ring_index);
}
}
- signed_index_type ring_index = 0;
+ signed_size_type ring_index = 0;
for (RingIterator it = rings_first; it != rings_beyond;
++it, ++ring_index)
{
@@ -303,6 +306,8 @@ protected:
TurnIterator beyond,
VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
+
typedef typename std::iterator_traits
<
TurnIterator
diff --git a/boost/geometry/algorithms/detail/is_valid/ring.hpp b/boost/geometry/algorithms/detail/is_valid/ring.hpp
index c663a96d28..c35e843418 100644
--- a/boost/geometry/algorithms/detail/is_valid/ring.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/ring.hpp
@@ -3,6 +3,7 @@
// Copyright (c) 2014-2015, 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
@@ -12,6 +13,8 @@
#include <deque>
+#include <boost/core/ignore_unused.hpp>
+
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/point_order.hpp>
@@ -53,6 +56,8 @@ struct is_topologically_closed
template <typename VisitPolicy>
static inline bool apply(Ring const&, VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
+
return visitor.template apply<no_failure>();
}
};
@@ -63,6 +68,8 @@ struct is_topologically_closed<Ring, closed>
template <typename VisitPolicy>
static inline bool apply(Ring const& ring, VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
+
if (geometry::equals(range::front(ring), range::back(ring)))
{
return visitor.template apply<no_failure>();
@@ -112,6 +119,8 @@ struct is_properly_oriented
template <typename VisitPolicy>
static inline bool apply(Ring const& ring, VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
+
typename ring_area_predicate
<
area_result_type, IsInteriorRing
diff --git a/boost/geometry/algorithms/detail/is_valid/segment.hpp b/boost/geometry/algorithms/detail/is_valid/segment.hpp
index 0b60890dc0..a93d2bfe9e 100644
--- a/boost/geometry/algorithms/detail/is_valid/segment.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/segment.hpp
@@ -3,6 +3,7 @@
// Copyright (c) 2014-2015, 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
@@ -10,6 +11,8 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_SEGMENT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_SEGMENT_HPP
+#include <boost/core/ignore_unused.hpp>
+
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -44,6 +47,8 @@ struct is_valid<Segment, segment_tag>
template <typename VisitPolicy>
static inline bool apply(Segment const& segment, VisitPolicy& visitor)
{
+ boost::ignore_unused(visitor);
+
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]);
diff --git a/boost/geometry/algorithms/detail/max_interval_gap.hpp b/boost/geometry/algorithms/detail/max_interval_gap.hpp
new file mode 100644
index 0000000000..e8a70a6b5f
--- /dev/null
+++ b/boost/geometry/algorithms/detail/max_interval_gap.hpp
@@ -0,0 +1,278 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_MAX_INTERVAL_GAP_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_MAX_INTERVAL_GAP_HPP
+
+#include <cstddef>
+#include <queue>
+#include <utility>
+#include <vector>
+
+#include <boost/core/ref.hpp>
+#include <boost/range.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/algorithms/detail/sweep.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace max_interval_gap
+{
+
+// the class Interval must provide the following:
+// * must define the type value_type
+// * must define the type difference_type
+// * must have the methods:
+// value_type get<Index>() const
+// difference_type length() const
+// where an Index value of 0 (resp., 1) refers to the left (resp.,
+// right) endpoint of the interval
+
+template <typename Interval>
+class sweep_event
+{
+public:
+ typedef Interval interval_type;
+ typedef typename Interval::value_type time_type;
+
+ sweep_event(Interval const& interval, bool start_event = true)
+ : m_interval(boost::cref(interval))
+ , m_start_event(start_event)
+ {}
+
+ inline bool is_start_event() const
+ {
+ return m_start_event;
+ }
+
+ inline interval_type const& interval() const
+ {
+ return m_interval;
+ }
+
+ inline time_type time() const
+ {
+ return (m_start_event)
+ ? interval().template get<0>()
+ : interval().template get<1>();
+ }
+
+ inline bool operator<(sweep_event const& other) const
+ {
+ if (! math::equals(time(), other.time()))
+ {
+ return time() < other.time();
+ }
+ // a start-event is before an end-event with the same event time
+ return is_start_event() && ! other.is_start_event();
+ }
+
+private:
+ boost::reference_wrapper<Interval const> m_interval;
+ bool m_start_event;
+};
+
+template <typename Event>
+struct event_greater
+{
+ inline bool operator()(Event const& event1, Event const& event2) const
+ {
+ return event2 < event1;
+ }
+};
+
+
+struct initialization_visitor
+{
+ template <typename Range, typename PriorityQueue, typename EventVisitor>
+ static inline void apply(Range const& range,
+ PriorityQueue& queue,
+ EventVisitor&)
+ {
+ BOOST_GEOMETRY_ASSERT(queue.empty());
+
+ // it is faster to build the queue directly from the entire
+ // range, rather than insert elements one after the other
+ PriorityQueue pq(boost::begin(range), boost::end(range));
+ std::swap(pq, queue);
+ }
+};
+
+
+template <typename Event>
+class event_visitor
+{
+ typedef typename Event::time_type event_time_type;
+ typedef typename Event::interval_type::difference_type difference_type;
+
+ typedef typename boost::remove_const
+ <
+ typename boost::remove_reference
+ <
+ event_time_type
+ >::type
+ >::type bare_time_type;
+
+
+public:
+ event_visitor()
+ : m_overlap_count(0)
+ , m_max_gap_left(0)
+ , m_max_gap_right(0)
+ {}
+
+ template <typename PriorityQueue>
+ inline void apply(Event const& event, PriorityQueue& queue)
+ {
+ if (event.is_start_event())
+ {
+ ++m_overlap_count;
+ queue.push(Event(event.interval(), false));
+ }
+ else
+ {
+ --m_overlap_count;
+ if (m_overlap_count == 0 && ! queue.empty())
+ {
+ // we may have a gap
+ BOOST_GEOMETRY_ASSERT(queue.top().is_start_event());
+
+ event_time_type next_event_time
+ = queue.top().interval().template get<0>();
+ difference_type gap = next_event_time - event.time();
+ if (gap > max_gap())
+ {
+ m_max_gap_left = event.time();
+ m_max_gap_right = next_event_time;
+ }
+ }
+ }
+ }
+
+ bare_time_type const& max_gap_left() const
+ {
+ return m_max_gap_left;
+ }
+
+ bare_time_type const& max_gap_right() const
+ {
+ return m_max_gap_right;
+ }
+
+ difference_type max_gap() const
+ {
+ return m_max_gap_right - m_max_gap_left;
+ }
+
+private:
+ std::size_t m_overlap_count;
+ bare_time_type m_max_gap_left, m_max_gap_right;
+};
+
+}} // namespace detail::max_interval_gap
+#endif // DOXYGEN_NO_DETAIL
+
+
+// Given a range of intervals I1, I2, ..., In, maximum_gap() returns
+// the maximum length of an interval M that satisfies the following
+// properties:
+//
+// 1. M.left >= min(I1, I2, ..., In)
+// 2. M.right <= max(I1, I2, ..., In)
+// 3. intersection(interior(M), Ik) is the empty set for all k=1, ..., n
+// 4. length(M) is maximal
+//
+// where M.left and M.right denote the left and right extreme values
+// for the interval M, and length(M) is equal to M.right - M.left.
+//
+// If M does not exist (or, alternatively, M is identified as the
+// empty set), 0 is returned.
+//
+// The algorithm proceeds for performing a sweep: the left endpoints
+// are inserted into a min-priority queue with the priority being the
+// value of the endpoint. The sweep algorithm maintains an "overlap
+// counter" that counts the number of overlaping intervals at any
+// specific sweep-time value.
+// There are two types of events encountered during the sweep:
+// (a) a start event: the left endpoint of an interval is found.
+// In this case the overlap count is increased by one and the
+// right endpoint of the interval in inserted into the event queue
+// (b) an end event: the right endpoint of an interval is found.
+// In this case the overlap count is decreased by one. If the
+// updated overlap count is 0, then we could expect to have a gap
+// in-between intervals. This gap is measured as the (absolute)
+// distance of the current interval right endpoint (being
+// processed) to the upcoming left endpoint of the next interval
+// to be processed (if such an interval exists). If the measured
+// gap is greater than the current maximum gap, it is recorded.
+// The initial maximum gap is initialized to 0. This value is returned
+// if no gap is found during the sweeping procedure.
+
+template <typename RangeOfIntervals, typename T>
+inline typename boost::range_value<RangeOfIntervals>::type::difference_type
+maximum_gap(RangeOfIntervals const& range_of_intervals,
+ T& max_gap_left, T& max_gap_right)
+{
+ typedef typename boost::range_value<RangeOfIntervals>::type interval_type;
+ typedef detail::max_interval_gap::sweep_event<interval_type> event_type;
+
+ // create a min-priority queue for the events
+ std::priority_queue
+ <
+ event_type,
+ std::vector<event_type>,
+ detail::max_interval_gap::event_greater<event_type>
+ > queue;
+
+ // define initialization and event-process visitors
+ detail::max_interval_gap::initialization_visitor init_visitor;
+ detail::max_interval_gap::event_visitor<event_type> sweep_visitor;
+
+ // perform the sweep
+ geometry::sweep(range_of_intervals,
+ queue,
+ init_visitor,
+ sweep_visitor);
+
+ max_gap_left = sweep_visitor.max_gap_left();
+ max_gap_right = sweep_visitor.max_gap_right();
+ return sweep_visitor.max_gap();
+}
+
+template <typename RangeOfIntervals>
+inline typename boost::range_value<RangeOfIntervals>::type::difference_type
+maximum_gap(RangeOfIntervals const& range_of_intervals)
+{
+ typedef typename boost::remove_const
+ <
+ typename boost::remove_reference
+ <
+ typename boost::range_value
+ <
+ RangeOfIntervals
+ >::type::value_type
+ >::type
+ >::type value_type;
+
+ value_type left, right;
+
+ return maximum_gap(range_of_intervals, left, right);
+}
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_MAX_INTERVAL_GAP_HPP
diff --git a/boost/geometry/algorithms/detail/normalize.hpp b/boost/geometry/algorithms/detail/normalize.hpp
new file mode 100644
index 0000000000..913fe324b7
--- /dev/null
+++ b/boost/geometry/algorithms/detail/normalize.hpp
@@ -0,0 +1,294 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_NORMALIZE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_NORMALIZE_HPP
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
+#include <boost/geometry/util/normalize_spheroidal_box_coordinates.hpp>
+
+#include <boost/geometry/views/detail/indexed_point_view.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace normalization
+{
+
+
+struct do_nothing
+{
+ template <typename GeometryIn, typename GeometryOut>
+ static inline void apply(GeometryIn const&, GeometryOut&)
+ {
+ }
+};
+
+
+template <std::size_t Dimension, std::size_t DimensionCount>
+struct assign_loop
+{
+ template <typename CoordinateType, typename PointIn, typename PointOut>
+ static inline void apply(CoordinateType const& longitude,
+ CoordinateType const& latitude,
+ PointIn const& point_in,
+ PointOut& point_out)
+ {
+ geometry::set<Dimension>(point_out, boost::numeric_cast
+ <
+ typename coordinate_type<PointOut>::type
+ >(geometry::get<Dimension>(point_in)));
+
+ assign_loop
+ <
+ Dimension + 1, DimensionCount
+ >::apply(longitude, latitude, point_in, point_out);
+ }
+};
+
+template <std::size_t DimensionCount>
+struct assign_loop<DimensionCount, DimensionCount>
+{
+ template <typename CoordinateType, typename PointIn, typename PointOut>
+ static inline void apply(CoordinateType const&,
+ CoordinateType const&,
+ PointIn const&,
+ PointOut&)
+ {
+ }
+};
+
+template <std::size_t DimensionCount>
+struct assign_loop<0, DimensionCount>
+{
+ template <typename CoordinateType, typename PointIn, typename PointOut>
+ static inline void apply(CoordinateType const& longitude,
+ CoordinateType const& latitude,
+ PointIn const& point_in,
+ PointOut& point_out)
+ {
+ geometry::set<0>(point_out, boost::numeric_cast
+ <
+ typename coordinate_type<PointOut>::type
+ >(longitude));
+
+ assign_loop
+ <
+ 1, DimensionCount
+ >::apply(longitude, latitude, point_in, point_out);
+ }
+};
+
+template <std::size_t DimensionCount>
+struct assign_loop<1, DimensionCount>
+{
+ template <typename CoordinateType, typename PointIn, typename PointOut>
+ static inline void apply(CoordinateType const& longitude,
+ CoordinateType const& latitude,
+ PointIn const& point_in,
+ PointOut& point_out)
+ {
+ geometry::set<1>(point_out, boost::numeric_cast
+ <
+ typename coordinate_type<PointOut>::type
+ >(latitude));
+
+ assign_loop
+ <
+ 2, DimensionCount
+ >::apply(longitude, latitude, point_in, point_out);
+ }
+};
+
+
+template <typename PointIn, typename PointOut>
+struct normalize_point
+{
+ static inline void apply(PointIn const& point_in, PointOut& point_out)
+ {
+ typedef typename coordinate_type<PointIn>::type in_coordinate_type;
+
+ in_coordinate_type longitude = geometry::get<0>(point_in);
+ in_coordinate_type latitude = geometry::get<1>(point_in);
+
+ math::normalize_spheroidal_coordinates
+ <
+ typename coordinate_system<PointIn>::type::units,
+ in_coordinate_type
+ >(longitude, latitude);
+
+ assign_loop
+ <
+ 0, dimension<PointIn>::value
+ >::apply(longitude, latitude, point_in, point_out);
+ }
+};
+
+
+template <typename BoxIn, typename BoxOut>
+class normalize_box
+{
+ template <typename UnitsIn, typename UnitsOut, typename CoordinateInType>
+ static inline void apply_to_coordinates(CoordinateInType& lon_min,
+ CoordinateInType& lat_min,
+ CoordinateInType& lon_max,
+ CoordinateInType& lat_max,
+ BoxIn const& box_in,
+ BoxOut& box_out)
+ {
+ detail::indexed_point_view<BoxOut, min_corner> p_min_out(box_out);
+ assign_loop
+ <
+ 0, dimension<BoxIn>::value
+ >::apply(lon_min,
+ lat_min,
+ detail::indexed_point_view
+ <
+ BoxIn const, min_corner
+ >(box_in),
+ p_min_out);
+
+ detail::indexed_point_view<BoxOut, max_corner> p_max_out(box_out);
+ assign_loop
+ <
+ 0, dimension<BoxIn>::value
+ >::apply(lon_max,
+ lat_max,
+ detail::indexed_point_view
+ <
+ BoxIn const, max_corner
+ >(box_in),
+ p_max_out);
+ }
+
+public:
+ static inline void apply(BoxIn const& box_in, BoxOut& box_out)
+ {
+ typedef typename coordinate_type<BoxIn>::type in_coordinate_type;
+
+ in_coordinate_type lon_min = geometry::get<min_corner, 0>(box_in);
+ in_coordinate_type lat_min = geometry::get<min_corner, 1>(box_in);
+ in_coordinate_type lon_max = geometry::get<max_corner, 0>(box_in);
+ in_coordinate_type lat_max = geometry::get<max_corner, 1>(box_in);
+
+ math::normalize_spheroidal_box_coordinates
+ <
+ typename coordinate_system<BoxIn>::type::units,
+ in_coordinate_type
+ >(lon_min, lat_min, lon_max, lat_max);
+
+ apply_to_coordinates
+ <
+ typename coordinate_system<BoxIn>::type::units,
+ typename coordinate_system<BoxOut>::type::units
+ >(lon_min, lat_min, lon_max, lat_max, box_in, box_out);
+ }
+};
+
+
+}} // namespace detail::normalization
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename GeometryIn,
+ typename GeometryOut,
+ typename TagIn = typename tag<GeometryIn>::type,
+ typename TagOut = typename tag<GeometryOut>::type,
+ typename CSTagIn = typename cs_tag<GeometryIn>::type,
+ typename CSTagOut = typename cs_tag<GeometryOut>::type
+>
+struct normalize : detail::normalization::do_nothing
+{};
+
+
+template <typename PointIn, typename PointOut>
+struct normalize
+ <
+ PointIn, PointOut, point_tag, point_tag,
+ spherical_equatorial_tag, spherical_equatorial_tag
+ > : detail::normalization::normalize_point<PointIn, PointOut>
+{};
+
+
+template <typename PointIn, typename PointOut>
+struct normalize
+ <
+ PointIn, PointOut, point_tag, point_tag, geographic_tag, geographic_tag
+ > : detail::normalization::normalize_point<PointIn, PointOut>
+{};
+
+
+template <typename BoxIn, typename BoxOut>
+struct normalize
+ <
+ BoxIn, BoxOut, box_tag, box_tag,
+ spherical_equatorial_tag, spherical_equatorial_tag
+ > : detail::normalization::normalize_box<BoxIn, BoxOut>
+{};
+
+
+template <typename BoxIn, typename BoxOut>
+struct normalize
+ <
+ BoxIn, BoxOut, box_tag, box_tag, geographic_tag, geographic_tag
+ > : detail::normalization::normalize_box<BoxIn, BoxOut>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+
+template <typename GeometryIn, typename GeometryOut>
+inline void normalize(GeometryIn const& geometry_in, GeometryOut& geometry_out)
+{
+ dispatch::normalize
+ <
+ GeometryIn, GeometryOut
+ >::apply(geometry_in, geometry_out);
+}
+
+template <typename GeometryOut, typename GeometryIn>
+inline GeometryOut return_normalized(GeometryIn const& geometry_in)
+{
+ GeometryOut geometry_out;
+ detail::normalize(geometry_in, geometry_out);
+ return geometry_out;
+}
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_NORMALIZE_HPP
diff --git a/boost/geometry/algorithms/detail/occupation_info.hpp b/boost/geometry/algorithms/detail/occupation_info.hpp
index 002c946170..4048d59d75 100644
--- a/boost/geometry/algorithms/detail/occupation_info.hpp
+++ b/boost/geometry/algorithms/detail/occupation_info.hpp
@@ -12,6 +12,7 @@
#include <algorithm>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/point_type.hpp>
@@ -36,7 +37,7 @@ struct angle_info
typedef Point point_type;
segment_identifier seg_id;
- int turn_index;
+ std::size_t turn_index;
int operation_index;
std::size_t cluster_index;
Point intersection_point;
@@ -57,7 +58,7 @@ class occupation_info
public :
typedef std::vector<AngleInfo> collection_type;
- int count;
+ std::size_t count;
inline occupation_info()
: count(0)
@@ -67,7 +68,7 @@ public :
inline void add(RobustPoint const& incoming_point,
RobustPoint const& outgoing_point,
RobustPoint const& intersection_point,
- int turn_index, int operation_index,
+ std::size_t turn_index, int operation_index,
segment_identifier const& seg_id)
{
geometry::equal_to<RobustPoint> comparator;
@@ -125,11 +126,19 @@ private :
};
template<typename Pieces>
-inline void move_index(Pieces const& pieces, int& index, int& piece_index, int direction)
+inline void move_index(Pieces const& pieces, signed_size_type& index, signed_size_type& piece_index, int direction)
{
- BOOST_ASSERT(direction == 1 || direction == -1);
- BOOST_ASSERT(piece_index >= 0 && piece_index < static_cast<int>(boost::size(pieces)) );
- BOOST_ASSERT(index >= 0 && index < static_cast<int>(boost::size(pieces[piece_index].robust_ring)));
+ BOOST_GEOMETRY_ASSERT(direction == 1 || direction == -1);
+ BOOST_GEOMETRY_ASSERT(
+ piece_index >= 0
+ && piece_index < static_cast<signed_size_type>(boost::size(pieces)) );
+ BOOST_GEOMETRY_ASSERT(
+ index >= 0
+ && index < static_cast<signed_size_type>(boost::size(pieces[piece_index].robust_ring)));
+
+ // NOTE: both index and piece_index must be in valid range
+ // this means that then they could be of type std::size_t
+ // if the code below was refactored
index += direction;
if (direction == -1 && index < 0)
@@ -142,10 +151,10 @@ inline void move_index(Pieces const& pieces, int& index, int& piece_index, int d
index = boost::size(pieces[piece_index].robust_ring) - 1;
}
if (direction == 1
- && index >= static_cast<int>(boost::size(pieces[piece_index].robust_ring)))
+ && index >= static_cast<signed_size_type>(boost::size(pieces[piece_index].robust_ring)))
{
piece_index++;
- if (piece_index >= static_cast<int>(boost::size(pieces)))
+ if (piece_index >= static_cast<signed_size_type>(boost::size(pieces)))
{
piece_index = 0;
}
@@ -176,8 +185,8 @@ inline void add_incoming_and_outgoing_angles(
RobustPoint direction_points[2];
for (int i = 0; i < 2; i++)
{
- int index = turn.operations[operation_index].index_in_robust_ring;
- int piece_index = turn.operations[operation_index].piece_index;
+ signed_size_type index = turn.operations[operation_index].index_in_robust_ring;
+ signed_size_type piece_index = turn.operations[operation_index].piece_index;
while(comparator(pieces[piece_index].robust_ring[index], intersection_point))
{
move_index(pieces, index, piece_index, i == 0 ? -1 : 1);
diff --git a/boost/geometry/algorithms/detail/overlay/add_rings.hpp b/boost/geometry/algorithms/detail/overlay/add_rings.hpp
index 5ff0b57d6e..fcb240941f 100644
--- a/boost/geometry/algorithms/detail/overlay/add_rings.hpp
+++ b/boost/geometry/algorithms/detail/overlay/add_rings.hpp
@@ -9,6 +9,8 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP
+#include <boost/range.hpp>
+
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/algorithms/area.hpp>
#include <boost/geometry/algorithms/detail/overlay/convert_ring.hpp>
diff --git a/boost/geometry/algorithms/detail/overlay/assign_parents.hpp b/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
index 178f3825d7..047eb4993e 100644
--- a/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
+++ b/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
@@ -9,6 +9,8 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ASSIGN_PARENTS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ASSIGN_PARENTS_HPP
+#include <boost/range.hpp>
+
#include <boost/geometry/algorithms/area.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
#include <boost/geometry/algorithms/expand.hpp>
diff --git a/boost/geometry/algorithms/detail/overlay/check_enrich.hpp b/boost/geometry/algorithms/detail/overlay/check_enrich.hpp
index 03be18e07a..25e442982b 100644
--- a/boost/geometry/algorithms/detail/overlay/check_enrich.hpp
+++ b/boost/geometry/algorithms/detail/overlay/check_enrich.hpp
@@ -12,12 +12,8 @@
#include <cstddef>
-
-#include <boost/assert.hpp>
#include <boost/range.hpp>
-
-
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
diff --git a/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp b/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp
index fc4f657322..b1a25c9f5e 100644
--- a/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp
+++ b/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp
@@ -1,6 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// 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.
+
+// Contributed and/or modified by Menelaos Karavelas, 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
@@ -160,10 +165,12 @@ template
typename OutputLinestring,
typename OutputIterator,
typename Range,
+ typename RobustPolicy,
typename Box,
typename Strategy
>
OutputIterator clip_range_with_box(Box const& b, Range const& range,
+ RobustPolicy const&,
OutputIterator out, Strategy const& strategy)
{
if (boost::begin(range) == boost::end(range))
diff --git a/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp b/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp
index 13e0a5a51e..dbf3770357 100644
--- a/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp
+++ b/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp
@@ -11,10 +11,10 @@
#include <boost/array.hpp>
-#include <boost/assert.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/ring_type.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
@@ -43,8 +43,8 @@ struct copy_segment_point_range
{
detail::normalized_view<Range const> view(range);
- signed_index_type const n = boost::size(view);
- signed_index_type index = seg_id.segment_index;
+ signed_size_type const n = boost::size(view);
+ signed_size_type index = seg_id.segment_index;
if (second)
{
index++;
@@ -54,7 +54,7 @@ struct copy_segment_point_range
}
}
- BOOST_ASSERT(index >= 0 && index < n);
+ BOOST_GEOMETRY_ASSERT(index >= 0 && index < n);
geometry::convert(*(boost::begin(view) + index), point);
return true;
@@ -95,7 +95,7 @@ struct copy_segment_point_box
SegmentIdentifier const& seg_id, bool second,
PointOut& point)
{
- signed_index_type index = seg_id.segment_index;
+ signed_size_type index = seg_id.segment_index;
if (second)
{
index++;
@@ -123,7 +123,7 @@ struct copy_segment_point_multi
PointOut& point)
{
- BOOST_ASSERT
+ BOOST_GEOMETRY_ASSERT
(
seg_id.multi_index >= 0
&& seg_id.multi_index < int(boost::size(multi))
@@ -306,7 +306,7 @@ inline bool copy_segment_point(Geometry1 const& geometry1, Geometry2 const& geom
concept::check<Geometry1 const>();
concept::check<Geometry2 const>();
- BOOST_ASSERT(seg_id.source_index == 0 || seg_id.source_index == 1);
+ BOOST_GEOMETRY_ASSERT(seg_id.source_index == 0 || seg_id.source_index == 1);
if (seg_id.source_index == 0)
{
diff --git a/boost/geometry/algorithms/detail/overlay/copy_segments.hpp b/boost/geometry/algorithms/detail/overlay/copy_segments.hpp
index ceeb1a3b8b..2eefa03c67 100644
--- a/boost/geometry/algorithms/detail/overlay/copy_segments.hpp
+++ b/boost/geometry/algorithms/detail/overlay/copy_segments.hpp
@@ -19,14 +19,11 @@
#include <vector>
#include <boost/array.hpp>
-#include <boost/assert.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/range.hpp>
#include <boost/type_traits/integral_constant.hpp>
-#include <boost/geometry/core/tags.hpp>
-
-#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/ring_type.hpp>
@@ -64,7 +61,7 @@ struct copy_segments_ring
>
static inline void apply(Ring const& ring,
SegmentIdentifier const& seg_id,
- signed_index_type to_index,
+ signed_size_type to_index,
RobustPolicy const& robust_policy,
RangeOut& current_output)
{
@@ -93,10 +90,10 @@ struct copy_segments_ring
// So we use the ever-circling iterator and determine when to step out
- signed_index_type const from_index = seg_id.segment_index + 1;
+ signed_size_type const from_index = seg_id.segment_index + 1;
// Sanity check
- BOOST_ASSERT(from_index < static_cast<signed_index_type>(boost::size(view)));
+ BOOST_GEOMETRY_ASSERT(from_index < static_cast<signed_size_type>(boost::size(view)));
ec_iterator it(boost::begin(view), boost::end(view),
boost::begin(view) + from_index);
@@ -104,12 +101,12 @@ struct copy_segments_ring
// [2..4] -> 4 - 2 + 1 = 3 -> {2,3,4} -> OK
// [4..2],size=6 -> 6 - 4 + 2 + 1 = 5 -> {4,5,0,1,2} -> OK
// [1..1], travel the whole ring round
- signed_index_type const count = from_index <= to_index
+ signed_size_type const count = from_index <= to_index
? to_index - from_index + 1
- : static_cast<signed_index_type>(boost::size(view))
+ : static_cast<signed_size_type>(boost::size(view))
- from_index + to_index + 1;
- for (signed_index_type i = 0; i < count; ++i, ++it)
+ for (signed_size_type i = 0; i < count; ++i, ++it)
{
detail::overlay::append_no_dups_or_spikes(current_output, *it, robust_policy);
}
@@ -151,26 +148,26 @@ public:
>
static inline void apply(LineString const& ls,
SegmentIdentifier const& seg_id,
- signed_index_type to_index,
+ signed_size_type to_index,
RobustPolicy const& robust_policy,
RangeOut& current_output)
{
- signed_index_type const from_index = seg_id.segment_index + 1;
+ signed_size_type const from_index = seg_id.segment_index + 1;
// Sanity check
if ( from_index > to_index
|| from_index < 0
- || to_index >= static_cast<signed_index_type>(boost::size(ls)) )
+ || to_index >= static_cast<signed_size_type>(boost::size(ls)) )
{
return;
}
- signed_index_type const count = to_index - from_index + 1;
+ signed_size_type const count = to_index - from_index + 1;
typename boost::range_iterator<LineString const>::type
it = boost::begin(ls) + from_index;
- for (signed_index_type i = 0; i < count; ++i, ++it)
+ for (signed_size_type i = 0; i < count; ++i, ++it)
{
append_to_output(current_output, *it, robust_policy,
boost::integral_constant<bool, RemoveSpikes>());
@@ -190,7 +187,7 @@ struct copy_segments_polygon
>
static inline void apply(Polygon const& polygon,
SegmentIdentifier const& seg_id,
- signed_index_type to_index,
+ signed_size_type to_index,
RobustPolicy const& robust_policy,
RangeOut& current_output)
{
@@ -220,14 +217,14 @@ struct copy_segments_box
>
static inline void apply(Box const& box,
SegmentIdentifier const& seg_id,
- signed_index_type to_index,
+ signed_size_type to_index,
RobustPolicy const& robust_policy,
RangeOut& current_output)
{
- signed_index_type index = seg_id.segment_index + 1;
- BOOST_ASSERT(index < 5);
+ signed_size_type index = seg_id.segment_index + 1;
+ BOOST_GEOMETRY_ASSERT(index < 5);
- signed_index_type const count = index <= to_index
+ signed_size_type const count = index <= to_index
? to_index - index + 1
: 5 - index + to_index + 1;
@@ -238,7 +235,7 @@ struct copy_segments_box
// (possibly cyclic) copy to output
// (see comments in ring-version)
- for (signed_index_type i = 0; i < count; i++, index++)
+ for (signed_size_type i = 0; i < count; i++, index++)
{
detail::overlay::append_no_dups_or_spikes(current_output,
bp[index % 5], robust_policy);
@@ -260,15 +257,15 @@ struct copy_segments_multi
>
static inline void apply(MultiGeometry const& multi_geometry,
SegmentIdentifier const& seg_id,
- signed_index_type to_index,
+ signed_size_type to_index,
RobustPolicy const& robust_policy,
RangeOut& current_output)
{
- BOOST_ASSERT
+ BOOST_GEOMETRY_ASSERT
(
seg_id.multi_index >= 0
- && seg_id.multi_index < int(boost::size(multi_geometry))
+ && static_cast<std::size_t>(seg_id.multi_index) < boost::size(multi_geometry)
);
// Call the single-version
@@ -348,7 +345,7 @@ template
>
inline void copy_segments(Geometry const& geometry,
SegmentIdentifier const& seg_id,
- signed_index_type to_index,
+ signed_size_type to_index,
RobustPolicy const& robust_policy,
RangeOut& range_out)
{
diff --git a/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp b/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp
index 7ed93f542a..3f81c4dca9 100644
--- a/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp
+++ b/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp
@@ -22,7 +22,6 @@
# define BOOST_GEOMETRY_DEBUG_IDENTIFIER
#endif
-#include <boost/assert.hpp>
#include <boost/range.hpp>
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
@@ -358,14 +357,14 @@ inline void enrich_assign(Container& operations,
= turn_points[it->turn_index].operations[it->operation_index];
prev_op.enriched.travels_to_ip_index
- = static_cast<int>(it->turn_index);
+ = static_cast<signed_size_type>(it->turn_index);
prev_op.enriched.travels_to_vertex_index
= it->subject->seg_id.segment_index;
if (! first
&& prev_op.seg_id.segment_index == op.seg_id.segment_index)
{
- prev_op.enriched.next_ip_index = static_cast<int>(it->turn_index);
+ prev_op.enriched.next_ip_index = static_cast<signed_size_type>(it->turn_index);
}
first = false;
}
diff --git a/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp b/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp
index ef32edeefa..5964f3ba44 100644
--- a/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp
+++ b/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp
@@ -37,13 +37,13 @@ struct enrichment_info
// vertex to which is free travel after this IP,
// so from "segment_index+1" to "travels_to_vertex_index", without IP-s,
// can be -1
- signed_index_type travels_to_vertex_index;
+ signed_size_type travels_to_vertex_index;
// same but now IP index, so "next IP index" but not on THIS segment
- int travels_to_ip_index;
+ signed_size_type travels_to_ip_index;
// index of next IP on this segment, -1 if there is no one
- int next_ip_index;
+ signed_size_type next_ip_index;
};
diff --git a/boost/geometry/algorithms/detail/overlay/follow.hpp b/boost/geometry/algorithms/detail/overlay/follow.hpp
index acf38d09ab..22807b5140 100644
--- a/boost/geometry/algorithms/detail/overlay/follow.hpp
+++ b/boost/geometry/algorithms/detail/overlay/follow.hpp
@@ -163,7 +163,7 @@ struct action_selector<overlay_intersection, RemoveSpikes>
static inline void enter(LineStringOut& current_piece,
LineString const& ,
segment_identifier& segment_id,
- signed_index_type , Point const& point,
+ signed_size_type , Point const& point,
Operation const& operation,
RobustPolicy const& ,
OutputIterator& )
@@ -186,7 +186,7 @@ struct action_selector<overlay_intersection, RemoveSpikes>
static inline void leave(LineStringOut& current_piece,
LineString const& linestring,
segment_identifier& segment_id,
- signed_index_type index, Point const& point,
+ signed_size_type index, Point const& point,
Operation const& ,
RobustPolicy const& robust_policy,
OutputIterator& out)
@@ -217,7 +217,7 @@ struct action_selector<overlay_intersection, RemoveSpikes>
static inline void isolated_point(LineStringOut&,
LineString const&,
segment_identifier&,
- signed_index_type, Point const& point,
+ signed_size_type, Point const& point,
Operation const& , OutputIterator& out)
{
LineStringOut isolated_point_ls;
@@ -268,7 +268,7 @@ struct action_selector<overlay_difference, RemoveSpikes>
static inline void enter(LineStringOut& current_piece,
LineString const& linestring,
segment_identifier& segment_id,
- signed_index_type index, Point const& point,
+ signed_size_type index, Point const& point,
Operation const& operation,
RobustPolicy const& robust_policy,
OutputIterator& out)
@@ -289,7 +289,7 @@ struct action_selector<overlay_difference, RemoveSpikes>
static inline void leave(LineStringOut& current_piece,
LineString const& linestring,
segment_identifier& segment_id,
- signed_index_type index, Point const& point,
+ signed_size_type index, Point const& point,
Operation const& operation,
RobustPolicy const& robust_policy,
OutputIterator& out)
@@ -309,7 +309,7 @@ struct action_selector<overlay_difference, RemoveSpikes>
static inline void isolated_point(LineStringOut&,
LineString const&,
segment_identifier&,
- signed_index_type, Point const&,
+ signed_size_type, Point const&,
Operation const&, OutputIterator&)
{
}
@@ -496,7 +496,7 @@ public :
false, RemoveSpikes
>::apply(linestring,
current_segment_id,
- static_cast<signed_index_type>(boost::size(linestring) - 1),
+ static_cast<signed_size_type>(boost::size(linestring) - 1),
robust_policy,
current_piece);
}
diff --git a/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp b/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp
index 7bcc0b951e..b2c3836712 100644
--- a/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp
+++ b/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp
@@ -14,9 +14,9 @@
#include <algorithm>
#include <iterator>
-#include <boost/assert.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -142,7 +142,7 @@ static inline bool is_isolated_point(Turn const& turn,
if ( turn.method == method_none )
{
- BOOST_ASSERT( operation.operation == operation_continue );
+ BOOST_GEOMETRY_ASSERT( operation.operation == operation_continue );
return true;
}
@@ -282,7 +282,7 @@ protected:
false, false // do not reverse; do not remove spikes
>::apply(linestring,
current_segment_id,
- static_cast<signed_index_type>(boost::size(linestring) - 1),
+ static_cast<signed_size_type>(boost::size(linestring) - 1),
robust_policy,
current_piece);
}
@@ -327,7 +327,7 @@ public:
throw inconsistent_turns_exception();
}
#else
- BOOST_ASSERT(enter_count == 0);
+ BOOST_GEOMETRY_ASSERT(enter_count == 0);
#endif
return process_end(entered, linestring,
@@ -404,7 +404,7 @@ protected:
};
template <typename TurnIterator>
- static inline signed_index_type get_multi_index(TurnIterator it)
+ static inline signed_size_type get_multi_index(TurnIterator it)
{
return boost::begin(it->operations)->seg_id.multi_index;
}
@@ -412,10 +412,10 @@ protected:
class has_other_multi_id
{
private:
- signed_index_type m_multi_id;
+ signed_size_type m_multi_id;
public:
- has_other_multi_id(signed_index_type multi_id)
+ has_other_multi_id(signed_size_type multi_id)
: m_multi_id(multi_id) {}
template <typename Turn>
@@ -433,7 +433,7 @@ public:
TurnIterator first, TurnIterator beyond,
OutputIterator oit)
{
- BOOST_ASSERT( first != beyond );
+ BOOST_GEOMETRY_ASSERT( first != beyond );
typedef copy_linestrings_in_range
<
@@ -446,7 +446,7 @@ public:
// Iterate through all intersection points (they are
// ordered along the each linestring)
- signed_index_type current_multi_id = get_multi_index(first);
+ signed_size_type current_multi_id = get_multi_index(first);
oit = copy_linestrings::apply(ls_first,
ls_first + current_multi_id,
@@ -463,7 +463,7 @@ public:
oit = Base::apply(*(ls_first + current_multi_id),
linear, per_ls_current, per_ls_next, oit);
- signed_index_type next_multi_id(-1);
+ signed_size_type next_multi_id = -1;
linestring_iterator ls_next = ls_beyond;
if ( per_ls_next != beyond )
{
diff --git a/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp b/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp
index 63011c7d48..4668189924 100644
--- a/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp
@@ -12,6 +12,9 @@
#include <cstddef>
+#include <boost/mpl/if.hpp>
+#include <boost/range.hpp>
+
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
diff --git a/boost/geometry/algorithms/detail/overlay/get_ring.hpp b/boost/geometry/algorithms/detail/overlay/get_ring.hpp
index 131d58d582..460c30def3 100644
--- a/boost/geometry/algorithms/detail/overlay/get_ring.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_ring.hpp
@@ -10,9 +10,9 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RING_HPP
-#include <boost/assert.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/ring_type.hpp>
@@ -82,7 +82,7 @@ struct get_ring<polygon_tag>
ring_identifier const& id,
Polygon const& polygon)
{
- BOOST_ASSERT
+ BOOST_GEOMETRY_ASSERT
(
id.ring_index >= -1
&& id.ring_index < int(boost::size(interior_rings(polygon)))
@@ -102,7 +102,7 @@ struct get_ring<multi_polygon_tag>
ring_identifier const& id,
MultiPolygon const& multi_polygon)
{
- BOOST_ASSERT
+ BOOST_GEOMETRY_ASSERT
(
id.multi_index >= 0
&& id.multi_index < int(boost::size(multi_polygon))
diff --git a/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp b/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp
index b3b1a06f68..717f0b47a9 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp
@@ -15,10 +15,10 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HPP
-#include <boost/assert.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/strategies/intersection.hpp>
#include <boost/geometry/algorithms/convert.hpp>
@@ -115,7 +115,7 @@ struct base_turn_handler
{
ti.method = method;
- BOOST_ASSERT(index < info.count);
+ BOOST_GEOMETRY_ASSERT(index < info.count);
geometry::convert(info.intersections[index], ti.point);
ti.operations[0].fraction = info.fractions[index].robust_ra;
@@ -597,7 +597,7 @@ struct collinear : public base_turn_handler
int const arrival = dir_info.arrival[0];
// Should not be 0, this is checked before
- BOOST_ASSERT(arrival != 0);
+ BOOST_GEOMETRY_ASSERT(arrival != 0);
int const side_p = side.pk_wrt_p1();
int const side_q = side.qk_wrt_q1();
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 4a3cacbedd..0b3cb72747 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
@@ -14,6 +14,7 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_FOR_ENDPOINT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_FOR_ENDPOINT_HPP
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
@@ -153,7 +154,7 @@ public:
}
else
{
- BOOST_ASSERT(result.template get<0>().count == 1);
+ BOOST_GEOMETRY_ASSERT(result.template get<0>().count == 1);
ips[0].p_operation = union_or_blocked_same_dirs(arrival_a, is_p_last);
ips[0].q_operation = union_or_blocked_same_dirs(arrival_b, is_q_last);
@@ -297,10 +298,10 @@ struct get_turn_info_for_endpoint
// may this give false positives for INTs?
typename IntersectionResult::point_type const&
inters_pt = result.template get<0>().intersections[ip_index];
- BOOST_ASSERT(ip_info.is_pi == equals::equals_point_point(pi, inters_pt));
- BOOST_ASSERT(ip_info.is_qi == equals::equals_point_point(qi, inters_pt));
- BOOST_ASSERT(ip_info.is_pj == equals::equals_point_point(pj, inters_pt));
- BOOST_ASSERT(ip_info.is_qj == equals::equals_point_point(qj, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_info.is_pi == equals::equals_point_point(pi, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_info.is_qi == equals::equals_point_point(qi, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_info.is_pj == equals::equals_point_point(pj, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_info.is_qj == equals::equals_point_point(qj, inters_pt));
#endif
// TODO - calculate first/last only if needed
@@ -412,8 +413,8 @@ struct get_turn_info_for_endpoint
// may this give false positives for INTs?
typename IntersectionResult::point_type const&
inters_pt = inters.i_info().intersections[ip_index];
- BOOST_ASSERT(ip_i2 == equals::equals_point_point(i2, inters_pt));
- BOOST_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_i2 == equals::equals_point_point(i2, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt));
#endif
if ( ip_i2 )
{
@@ -448,7 +449,7 @@ struct get_turn_info_for_endpoint
}
else
{
- BOOST_ASSERT(operations_combination(operations, operation_intersection, operation_union));
+ BOOST_GEOMETRY_ASSERT(operations_combination(operations, operation_intersection, operation_union));
//op1 = operation_union;
//op2 = operation_union;
}
@@ -463,8 +464,8 @@ struct get_turn_info_for_endpoint
// may this give false positives for INTs?
typename IntersectionResult::point_type const&
inters_pt = inters.i_info().intersections[ip_index];
- BOOST_ASSERT(ip_i2 == equals::equals_point_point(i2, inters_pt));
- BOOST_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_i2 == equals::equals_point_point(i2, inters_pt));
+ BOOST_GEOMETRY_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt));
#endif
if ( ip_i2 )
{
@@ -499,7 +500,7 @@ struct get_turn_info_for_endpoint
}
else
{
- BOOST_ASSERT(operations_combination(operations, operation_intersection, operation_union));
+ BOOST_GEOMETRY_ASSERT(operations_combination(operations, operation_intersection, operation_union));
//op1 = operation_blocked;
//op2 = operation_union;
}
@@ -560,7 +561,7 @@ struct get_turn_info_for_endpoint
// NOTE: is_collinear is NOT set for the first endpoint
// for which there is no preceding segment
- //BOOST_ASSERT( result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0 );
+ //BOOST_GEOMETRY_ASSERT( result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0 );
if ( ! is_p_first_ip )
{
tp.operations[0].is_collinear = op0 != operation_intersection
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 e0d75108b9..e4f8de42e1 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp
@@ -42,7 +42,8 @@ template <typename PointP, typename PointQ,
>
struct side_calculator
{
- typedef boost::geometry::strategy::side::side_by_triangle<> side; // todo: get from coordinate system
+ // todo: get from coordinate system
+ typedef boost::geometry::strategy::side::side_by_triangle<> side;
inline side_calculator(Pi const& pi, Pj const& pj, Pk const& pk,
Qi const& qi, Qj const& qj, Qk const& qk)
@@ -71,8 +72,9 @@ struct robust_points
{
typedef typename geometry::robust_point_type
<
- Point1, RobustPolicy
+ Point1, RobustPolicy
>::type robust_point1_type;
+
// TODO: define robust_point2_type using Point2?
typedef robust_point1_type robust_point2_type;
@@ -96,23 +98,23 @@ template <typename Point1, typename Point2, typename RobustPolicy>
class intersection_info_base
: private robust_points<Point1, Point2, RobustPolicy>
{
- typedef robust_points<Point1, Point2, RobustPolicy> base_t;
+ typedef robust_points<Point1, Point2, RobustPolicy> base;
public:
typedef Point1 point1_type;
typedef Point2 point2_type;
- typedef typename base_t::robust_point1_type robust_point1_type;
- typedef typename base_t::robust_point2_type robust_point2_type;
+ typedef typename base::robust_point1_type robust_point1_type;
+ typedef typename base::robust_point2_type robust_point2_type;
typedef side_calculator<robust_point1_type, robust_point2_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,
RobustPolicy const& robust_policy)
- : base_t(pi, pj, pk, qi, qj, qk, robust_policy)
- , m_side_calc(base_t::m_rpi, base_t::m_rpj, base_t::m_rpk,
- base_t::m_rqi, base_t::m_rqj, base_t::m_rqk)
+ : 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)
, m_pi(pi), m_pj(pj), m_pk(pk)
, m_qi(qi), m_qj(qj), m_qk(qk)
{}
@@ -125,13 +127,13 @@ public:
inline Point2 const& qj() const { return m_qj; }
inline Point2 const& qk() const { return m_qk; }
- inline robust_point1_type const& rpi() const { return base_t::m_rpi; }
- inline robust_point1_type const& rpj() const { return base_t::m_rpj; }
- inline robust_point1_type const& rpk() const { return base_t::m_rpk; }
+ inline robust_point1_type const& rpi() const { return base::m_rpi; }
+ inline robust_point1_type const& rpj() const { return base::m_rpj; }
+ inline robust_point1_type const& rpk() const { return base::m_rpk; }
- inline robust_point2_type const& rqi() const { return base_t::m_rqi; }
- inline robust_point2_type const& rqj() const { return base_t::m_rqj; }
- inline robust_point2_type const& rqk() const { return base_t::m_rqk; }
+ inline robust_point2_type const& rqi() const { return base::m_rqi; }
+ inline robust_point2_type const& rqj() const { return base::m_rqj; }
+ inline robust_point2_type const& rqk() const { return base::m_rqk; }
inline side_calculator_type const& sides() const { return m_side_calc; }
@@ -187,11 +189,17 @@ private:
};
-template <typename Point1, typename Point2, typename TurnPoint, typename RobustPolicy>
+template
+<
+ typename Point1,
+ typename Point2,
+ typename TurnPoint,
+ typename RobustPolicy
+>
class intersection_info
: public intersection_info_base<Point1, Point2, RobustPolicy>
{
- typedef intersection_info_base<Point1, Point2, RobustPolicy> base_t;
+ typedef intersection_info_base<Point1, Point2, RobustPolicy> base;
typedef typename strategy_intersection
<
@@ -205,7 +213,7 @@ class intersection_info
public:
typedef model::referring_segment<Point1 const> segment_type1;
typedef model::referring_segment<Point2 const> segment_type2;
- typedef typename base_t::side_calculator_type side_calculator_type;
+ typedef typename base::side_calculator_type side_calculator_type;
typedef typename strategy::return_type result_type;
typedef typename boost::tuples::element<0, result_type>::type i_info_type; // intersection_info
@@ -214,10 +222,12 @@ public:
intersection_info(Point1 const& pi, Point1 const& pj, Point1 const& pk,
Point2 const& qi, Point2 const& qj, Point2 const& qk,
RobustPolicy const& robust_policy)
- : base_t(pi, pj, pk, qi, qj, qk, 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))
+ robust_policy,
+ base::rpi(), base::rpj(),
+ base::rqi(), base::rqj()))
, m_robust_policy(robust_policy)
{}
@@ -228,19 +238,22 @@ public:
// TODO: it's more like is_spike_ip_p
inline bool is_spike_p() const
{
- if ( base_t::sides().pk_wrt_p1() == 0 )
+ if (base::sides().pk_wrt_p1() == 0)
{
- if ( ! is_ip_j<0>() )
+ if (! is_ip_j<0>())
+ {
return false;
+ }
- int const qk_p1 = base_t::sides().qk_wrt_p1();
- int const qk_p2 = base_t::sides().qk_wrt_p2();
+ int const qk_p1 = base::sides().qk_wrt_p1();
+ int const qk_p2 = base::sides().qk_wrt_p2();
- if ( qk_p1 == -qk_p2 )
+ if (qk_p1 == -qk_p2)
{
- if ( qk_p1 == 0 )
+ if (qk_p1 == 0)
{
- return is_spike_of_collinear(base_t::pi(), base_t::pj(), base_t::pk());
+ return is_spike_of_collinear(base::pi(), base::pj(),
+ base::pk());
}
return true;
@@ -253,19 +266,22 @@ public:
// TODO: it's more like is_spike_ip_q
inline bool is_spike_q() const
{
- if ( base_t::sides().qk_wrt_q1() == 0 )
+ if (base::sides().qk_wrt_q1() == 0)
{
- if ( ! is_ip_j<1>() )
+ if (! is_ip_j<1>())
+ {
return false;
+ }
- int const pk_q1 = base_t::sides().pk_wrt_q1();
- int const pk_q2 = base_t::sides().pk_wrt_q2();
+ int const pk_q1 = base::sides().pk_wrt_q1();
+ int const pk_q2 = base::sides().pk_wrt_q2();
- if ( pk_q1 == -pk_q2 )
+ if (pk_q1 == -pk_q2)
{
- if ( pk_q1 == 0 )
+ if (pk_q1 == 0)
{
- return is_spike_of_collinear(base_t::qi(), base_t::qj(), base_t::qk());
+ return is_spike_of_collinear(base::qi(), base::qj(),
+ base::qk());
}
return true;
@@ -277,9 +293,10 @@ public:
private:
template <typename Point>
- inline bool is_spike_of_collinear(Point const& i, Point const& j, Point const& k) const
+ inline bool is_spike_of_collinear(Point const& i, Point const& j,
+ Point const& k) const
{
- typedef model::referring_segment<Point const> seg_t;
+ typedef model::referring_segment<Point const> seg;
typedef strategy_intersection
<
@@ -289,7 +306,7 @@ private:
typedef typename si::segment_intersection_strategy_type strategy;
typename strategy::return_type result
- = strategy::apply(seg_t(i, j), seg_t(j, k), m_robust_policy);
+ = strategy::apply(seg(i, j), seg(j, k), m_robust_policy);
return result.template get<0>().count == 2;
}
@@ -300,9 +317,9 @@ private:
int arrival = d_info().arrival[OpId];
bool same_dirs = d_info().dir_a == 0 && d_info().dir_b == 0;
- if ( same_dirs )
+ if (same_dirs)
{
- if ( i_info().count == 2 )
+ if (i_info().count == 2)
{
return arrival != -1;
}
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 71946543ee..ccb42d4c92 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp
@@ -14,6 +14,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/geometry/core/assert.hpp>
+
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
@@ -569,7 +571,7 @@ struct get_turn_info_linear_areal
tp.operations[0].is_collinear = true;
//tp.operations[1].is_collinear = false;
- BOOST_ASSERT(inters.i_info().count > 1);
+ BOOST_GEOMETRY_ASSERT(inters.i_info().count > 1);
base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 1);
AssignPolicy::apply(tp, inters.pi(), inters.qi(), inters);
@@ -816,7 +818,7 @@ struct get_turn_info_linear_areal
if ( inters.i_info().count > 1 )
{
- //BOOST_ASSERT( result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0 );
+ //BOOST_GEOMETRY_ASSERT( result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0 );
tp.operations[0].is_collinear = true;
tp.operations[1].operation = opposite ? operation_continue : operation_union;
}
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 1ec88e54a0..19f0859cbb 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp
@@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_LL_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_LL_HPP
+#include <boost/geometry/core/assert.hpp>
+
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp>
@@ -579,7 +581,7 @@ struct get_turn_info_linear_linear
tp.operations[0].is_collinear = true;
tp.operations[1].is_collinear = false;
- BOOST_ASSERT(inters.i_info().count > 1);
+ BOOST_GEOMETRY_ASSERT(inters.i_info().count > 1);
base_turn_handler::assign_point(tp, method_touch_interior,
inters.i_info(), 1);
@@ -612,7 +614,7 @@ struct get_turn_info_linear_linear
tp.operations[0].is_collinear = false;
tp.operations[1].is_collinear = true;
- BOOST_ASSERT(inters.i_info().count > 0);
+ BOOST_GEOMETRY_ASSERT(inters.i_info().count > 0);
base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 0);
@@ -686,7 +688,7 @@ struct get_turn_info_linear_linear
operation_type & op0 = turn.operations[0].operation;
operation_type & op1 = turn.operations[1].operation;
- BOOST_ASSERT(op0 != operation_blocked || op1 != operation_blocked );
+ BOOST_GEOMETRY_ASSERT(op0 != operation_blocked || op1 != operation_blocked );
if ( op0 == operation_blocked )
{
diff --git a/boost/geometry/algorithms/detail/overlay/get_turns.hpp b/boost/geometry/algorithms/detail/overlay/get_turns.hpp
index a5d8f3f023..098c7b5642 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turns.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turns.hpp
@@ -22,6 +22,7 @@
#include <boost/array.hpp>
#include <boost/concept_check.hpp>
#include <boost/mpl/if.hpp>
+#include <boost/mpl/vector_c.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/access.hpp>
@@ -142,7 +143,7 @@ class get_turns_in_sections
template <typename Geometry, typename Section>
static inline bool neighbouring(Section const& section,
- int index1, int index2)
+ signed_size_type index1, signed_size_type index2)
{
// About n-2:
// (square: range_count=5, indices 0,1,2,3
@@ -150,7 +151,7 @@ class get_turns_in_sections
// Also tested for open polygons, and/or duplicates
// About first condition: will be optimized by compiler (static)
// It checks if it is areal (box,ring,(multi)polygon
- int const n = int(section.range_count);
+ signed_size_type const n = static_cast<signed_size_type>(section.range_count);
boost::ignore_unused_variable_warning(n);
boost::ignore_unused_variable_warning(index1);
@@ -207,8 +208,8 @@ public :
int const dir1 = sec1.directions[0];
int const dir2 = sec2.directions[0];
- int index1 = sec1.begin_index;
- int ndi1 = sec1.non_duplicate_index;
+ signed_size_type index1 = sec1.begin_index;
+ signed_size_type ndi1 = sec1.non_duplicate_index;
bool const same_source =
source_id1 == source_id2
@@ -236,8 +237,8 @@ public :
begin_range_1, end_range_1, next1, true);
advance_to_non_duplicate_next(nd_next1, it1, sec1, robust_policy);
- int index2 = sec2.begin_index;
- int ndi2 = sec2.non_duplicate_index;
+ signed_size_type index2 = sec2.begin_index;
+ signed_size_type ndi2 = sec2.non_duplicate_index;
range2_iterator prev2, it2, end2;
@@ -359,7 +360,7 @@ private :
typename boost::range_iterator<Range const>::type& it,
typename boost::range_iterator<Range const>::type& prev,
typename boost::range_iterator<Range const>::type& end,
- int& index, int& ndi,
+ signed_size_type& index, signed_size_type& ndi,
int dir, Box const& other_bounding_box, RobustPolicy const& robust_policy)
{
it = boost::begin(range) + section.begin_index;
@@ -524,8 +525,8 @@ struct get_turns_cs
RobustPolicy const& robust_policy,
Turns& turns,
InterruptPolicy& interrupt_policy,
- signed_index_type multi_index = -1,
- signed_index_type ring_index = -1)
+ signed_size_type multi_index = -1,
+ signed_size_type ring_index = -1)
{
if ( boost::size(range) <= 1)
{
@@ -552,7 +553,7 @@ struct get_turns_cs
//char previous_side[2] = {0, 0};
- signed_index_type index = 0;
+ signed_size_type index = 0;
for (iterator_type prev = it++;
it != boost::end(view);
@@ -696,7 +697,7 @@ struct get_turns_polygon_cs
int source_id2, Box const& box,
RobustPolicy const& robust_policy,
Turns& turns, InterruptPolicy& interrupt_policy,
- signed_index_type multi_index = -1)
+ signed_size_type multi_index = -1)
{
typedef typename geometry::ring_type<Polygon>::type ring_type;
@@ -714,7 +715,7 @@ struct get_turns_polygon_cs
turns, interrupt_policy,
multi_index, -1);
- signed_index_type i = 0;
+ signed_size_type i = 0;
typename interior_return_type<Polygon const>::type
rings = interior_rings(polygon);
@@ -753,7 +754,7 @@ struct get_turns_multi_polygon_cs
Multi const
>::type iterator_type;
- signed_index_type i = 0;
+ signed_size_type i = 0;
for (iterator_type it = boost::begin(multi);
it != boost::end(multi);
++it, ++i)
diff --git a/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp b/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp
index 3101de8c35..af0731f5a9 100644
--- a/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp
+++ b/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp
@@ -1,9 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2007-2015 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, 2015.
+// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -39,9 +39,11 @@
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
#include <boost/geometry/views/segment_view.hpp>
+#include <boost/geometry/views/detail/boundary_view.hpp>
#include <boost/geometry/algorithms/detail/overlay/linear_linear.hpp>
#include <boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp>
+#include <boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp>
#if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
#include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
@@ -283,7 +285,8 @@ namespace dispatch
template
<
// real types
- typename Geometry1, typename Geometry2,
+ typename Geometry1,
+ typename Geometry2,
typename GeometryOut,
overlay_type OverlayType,
// orientation
@@ -409,13 +412,13 @@ struct intersection_insert
template <typename RobustPolicy, typename OutputIterator, typename Strategy>
static inline OutputIterator apply(Linestring const& linestring,
Box const& box,
- RobustPolicy const& ,
+ RobustPolicy const& robust_policy,
OutputIterator out, Strategy const& )
{
typedef typename point_type<GeometryOut>::type point_type;
strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
return detail::intersection::clip_range_with_box
- <GeometryOut>(box, linestring, out, lb_strategy);
+ <GeometryOut>(box, linestring, robust_policy, out, lb_strategy);
}
};
@@ -487,7 +490,7 @@ struct intersection_insert
template <typename RobustPolicy, typename OutputIterator, typename Strategy>
static inline OutputIterator apply(Segment const& segment,
Box const& box,
- RobustPolicy const& ,// TODO: propagate to clip_range_with_box
+ RobustPolicy const& robust_policy,
OutputIterator out, Strategy const& )
{
geometry::segment_view<Segment> range(segment);
@@ -495,7 +498,7 @@ struct intersection_insert
typedef typename point_type<GeometryOut>::type point_type;
strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
return detail::intersection::clip_range_with_box
- <GeometryOut>(box, range, out, lb_strategy);
+ <GeometryOut>(box, range, robust_policy, out, lb_strategy);
}
};
@@ -573,6 +576,46 @@ struct intersection_insert_reversed
};
+// dispatch for intersection(areal, areal, linear)
+template
+<
+ typename Geometry1, typename Geometry2,
+ typename LinestringOut,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename Tag1, typename Tag2
+>
+struct intersection_insert
+ <
+ Geometry1, Geometry2,
+ LinestringOut,
+ overlay_intersection,
+ Reverse1, Reverse2, ReverseOut,
+ Tag1, Tag2, linestring_tag,
+ true, true, false
+ >
+{
+ template
+ <
+ typename RobustPolicy, typename OutputIterator, typename Strategy
+ >
+ static inline OutputIterator apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
+ OutputIterator oit,
+ Strategy const& strategy)
+ {
+ detail::boundary_view<Geometry1 const> view1(geometry1);
+ detail::boundary_view<Geometry2 const> view2(geometry2);
+
+ return detail::overlay::linear_linear_linestring
+ <
+ detail::boundary_view<Geometry1 const>,
+ detail::boundary_view<Geometry2 const>,
+ LinestringOut,
+ overlay_intersection
+ >::apply(view1, view2, robust_policy, oit, strategy);
+ }
+};
// dispatch for non-areal geometries
template
@@ -700,6 +743,79 @@ struct intersection_insert
{};
+// dispatch for difference/intersection of pointlike-linear geometries
+template
+<
+ typename Point, typename Linear, typename PointOut,
+ overlay_type OverlayType,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename Tag
+>
+struct intersection_insert
+ <
+ Point, Linear, PointOut, OverlayType,
+ Reverse1, Reverse2, ReverseOut,
+ point_tag, Tag, point_tag,
+ false, false, false
+ > : detail_dispatch::overlay::pointlike_linear_point
+ <
+ Point, Linear, PointOut, OverlayType,
+ point_tag, typename tag_cast<Tag, segment_tag, linear_tag>::type
+ >
+{};
+
+
+template
+<
+ typename MultiPoint, typename Linear, typename PointOut,
+ overlay_type OverlayType,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename Tag
+>
+struct intersection_insert
+ <
+ MultiPoint, Linear, PointOut, OverlayType,
+ Reverse1, Reverse2, ReverseOut,
+ multi_point_tag, Tag, point_tag,
+ false, false, false
+ > : detail_dispatch::overlay::pointlike_linear_point
+ <
+ MultiPoint, Linear, PointOut, OverlayType,
+ multi_point_tag,
+ typename tag_cast<Tag, segment_tag, linear_tag>::type
+ >
+{};
+
+
+template
+<
+ typename Linestring, typename MultiPoint, typename PointOut,
+ bool Reverse1, bool Reverse2, bool ReverseOut
+>
+struct intersection_insert
+ <
+ Linestring, MultiPoint, PointOut, overlay_intersection,
+ Reverse1, Reverse2, ReverseOut,
+ linestring_tag, multi_point_tag, point_tag,
+ false, false, false
+ >
+{
+ template <typename RobustPolicy, typename OutputIterator, typename Strategy>
+ static inline OutputIterator apply(Linestring const& linestring,
+ MultiPoint const& multipoint,
+ RobustPolicy const& robust_policy,
+ OutputIterator out,
+ Strategy const& strategy)
+ {
+ return detail_dispatch::overlay::pointlike_linear_point
+ <
+ MultiPoint, Linestring, PointOut, overlay_intersection,
+ multi_point_tag, linear_tag
+ >::apply(multipoint, linestring, robust_policy, out, strategy);
+ }
+};
+
+
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
diff --git a/boost/geometry/algorithms/detail/overlay/linear_linear.hpp b/boost/geometry/algorithms/detail/overlay/linear_linear.hpp
index d4ebcf296b..34517f6590 100644
--- a/boost/geometry/algorithms/detail/overlay/linear_linear.hpp
+++ b/boost/geometry/algorithms/detail/overlay/linear_linear.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -157,13 +157,18 @@ protected:
<
typename Turns,
typename LinearGeometry1,
- typename LinearGeometry2
+ typename LinearGeometry2,
+ typename RobustPolicy
>
static inline void compute_turns(Turns& turns,
LinearGeometry1 const& linear1,
- LinearGeometry2 const& linear2)
+ LinearGeometry2 const& linear2,
+ RobustPolicy const& robust_policy)
{
turns.clear();
+
+ detail::get_turns::no_interrupt_policy interrupt_policy;
+
geometry::detail::relate::turns::get_turns
<
LinearGeometry1,
@@ -173,8 +178,9 @@ protected:
LinearGeometry1,
LinearGeometry2,
assign_policy
- >
- >::apply(turns, linear1, linear2);
+ >,
+ RobustPolicy
+ >::apply(turns, linear1, linear2, interrupt_policy, robust_policy);
}
@@ -229,19 +235,27 @@ public:
>
static inline OutputIterator apply(Linear1 const& linear1,
Linear2 const& linear2,
- RobustPolicy const&,
+ RobustPolicy const& robust_policy,
OutputIterator oit,
Strategy const& )
{
typedef typename detail::relate::turns::get_turns
<
- Linear1, Linear2
+ Linear1,
+ Linear2,
+ detail::get_turns::get_turn_info_type
+ <
+ Linear1,
+ Linear2,
+ assign_policy
+ >,
+ RobustPolicy
>::turn_info turn_info;
typedef std::vector<turn_info> turns_container;
turns_container turns;
- compute_turns(turns, linear1, linear2);
+ compute_turns(turns, linear1, linear2, robust_policy);
if ( turns.empty() )
{
diff --git a/boost/geometry/algorithms/detail/overlay/overlay.hpp b/boost/geometry/algorithms/detail/overlay/overlay.hpp
index a2f52848d1..baf9d4777d 100644
--- a/boost/geometry/algorithms/detail/overlay/overlay.hpp
+++ b/boost/geometry/algorithms/detail/overlay/overlay.hpp
@@ -1,7 +1,12 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland
+// 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.
+
+// Contributed and/or modified by Menelaos Karavelas, 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
@@ -28,7 +33,7 @@
#include <boost/geometry/algorithms/detail/recalculate.hpp>
-#include <boost/geometry/algorithms/num_points.hpp>
+#include <boost/geometry/algorithms/is_empty.hpp>
#include <boost/geometry/algorithms/reverse.hpp>
#include <boost/geometry/algorithms/detail/overlay/add_rings.hpp>
@@ -125,8 +130,7 @@ inline OutputIterator return_if_one_input_is_empty(Geometry1 const& geometry1,
// Intersection: return nothing
// Difference: return first of them
if (Direction == overlay_intersection
- || (Direction == overlay_difference
- && geometry::num_points(geometry1) == 0))
+ || (Direction == overlay_difference && geometry::is_empty(geometry1)))
{
return out;
}
@@ -162,14 +166,15 @@ struct overlay
OutputIterator out,
Strategy const& )
{
- if ( geometry::num_points(geometry1) == 0
- && geometry::num_points(geometry2) == 0 )
+ bool const is_empty1 = geometry::is_empty(geometry1);
+ bool const is_empty2 = geometry::is_empty(geometry2);
+
+ if (is_empty1 && is_empty2)
{
return out;
}
- if ( geometry::num_points(geometry1) == 0
- || geometry::num_points(geometry2) == 0 )
+ if (is_empty1 || is_empty2)
{
return return_if_one_input_is_empty
<
diff --git a/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp b/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp
new file mode 100644
index 0000000000..156cb54867
--- /dev/null
+++ b/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp
@@ -0,0 +1,343 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, 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
+
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_POINTLIKE_LINEAR_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_POINTLIKE_LINEAR_HPP
+
+#include <iterator>
+#include <vector>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/geometries/box.hpp>
+
+#include <boost/geometry/iterators/segment_iterator.hpp>
+
+#include <boost/geometry/algorithms/disjoint.hpp>
+#include <boost/geometry/algorithms/envelope.hpp>
+#include <boost/geometry/algorithms/expand.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+#include <boost/geometry/algorithms/detail/not.hpp>
+#include <boost/geometry/algorithms/detail/partition.hpp>
+#include <boost/geometry/algorithms/detail/relate/less.hpp>
+#include <boost/geometry/algorithms/detail/disjoint/point_geometry.hpp>
+#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
+#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
+#include <boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+
+// action struct for pointlike-linear difference/intersection
+// it works the same as its pointlike-pointlike counterpart, hence the
+// derivation
+template <typename PointOut, overlay_type OverlayType>
+struct action_selector_pl_l
+ : action_selector_pl_pl<PointOut, OverlayType>
+{};
+
+// difference/intersection of point-linear
+template
+<
+ typename Point,
+ typename Linear,
+ typename PointOut,
+ overlay_type OverlayType,
+ typename Policy
+>
+struct point_linear_point
+{
+ template <typename RobustPolicy, typename OutputIterator, typename Strategy>
+ static inline OutputIterator apply(Point const& point,
+ Linear const& linear,
+ RobustPolicy const&,
+ OutputIterator oit,
+ Strategy const&)
+ {
+ action_selector_pl_l
+ <
+ PointOut, OverlayType
+ >::apply(point, Policy::apply(point, linear), oit);
+ return oit;
+ }
+};
+
+// difference/intersection of multipoint-segment
+template
+<
+ typename MultiPoint,
+ typename Segment,
+ typename PointOut,
+ overlay_type OverlayType,
+ typename Policy
+>
+struct multipoint_segment_point
+{
+ template <typename RobustPolicy, typename OutputIterator, typename Strategy>
+ static inline OutputIterator apply(MultiPoint const& multipoint,
+ Segment const& segment,
+ RobustPolicy const&,
+ OutputIterator oit,
+ Strategy const&)
+ {
+ for (typename boost::range_iterator<MultiPoint const>::type
+ it = boost::begin(multipoint);
+ it != boost::end(multipoint);
+ ++it)
+ {
+ action_selector_pl_l
+ <
+ PointOut, OverlayType
+ >::apply(*it, Policy::apply(*it, segment), oit);
+ }
+
+ return oit;
+ }
+};
+
+
+// difference/intersection of multipoint-linear
+template
+<
+ typename MultiPoint,
+ typename Linear,
+ typename PointOut,
+ overlay_type OverlayType,
+ typename Policy
+>
+class multipoint_linear_point
+{
+private:
+ // structs for partition -- start
+ struct expand_box
+ {
+ template <typename Box, typename Geometry>
+ static inline void apply(Box& total, Geometry const& geometry)
+ {
+ geometry::expand(total, geometry::return_envelope<Box>(geometry));
+ }
+
+ };
+
+ struct overlaps_box
+ {
+ template <typename Box, typename Geometry>
+ static inline bool apply(Box const& box, Geometry const& geometry)
+ {
+ return ! geometry::disjoint(geometry, box);
+ }
+ };
+
+ template <typename OutputIterator>
+ class item_visitor_type
+ {
+ public:
+ item_visitor_type(OutputIterator& oit) : m_oit(oit) {}
+
+ template <typename Item1, typename Item2>
+ inline void apply(Item1 const& item1, Item2 const& item2)
+ {
+ action_selector_pl_l
+ <
+ PointOut, overlay_intersection
+ >::apply(item1, Policy::apply(item1, item2), m_oit);
+ }
+
+ private:
+ OutputIterator& m_oit;
+ };
+ // structs for partition -- end
+
+ class segment_range
+ {
+ public:
+ typedef geometry::segment_iterator<Linear const> const_iterator;
+ typedef const_iterator iterator;
+
+ segment_range(Linear const& linear)
+ : m_linear(linear)
+ {}
+
+ const_iterator begin() const
+ {
+ return geometry::segments_begin(m_linear);
+ }
+
+ const_iterator end() const
+ {
+ return geometry::segments_end(m_linear);
+ }
+
+ private:
+ Linear const& m_linear;
+ };
+
+ template <typename OutputIterator>
+ static inline OutputIterator get_common_points(MultiPoint const& multipoint,
+ Linear const& linear,
+ OutputIterator oit)
+ {
+ item_visitor_type<OutputIterator> item_visitor(oit);
+
+ segment_range rng(linear);
+
+ geometry::partition
+ <
+ geometry::model::box
+ <
+ typename boost::range_value<MultiPoint>::type
+ >,
+ expand_box,
+ overlaps_box
+ >::apply(multipoint, rng, item_visitor);
+
+ return oit;
+ }
+
+public:
+ template <typename RobustPolicy, typename OutputIterator, typename Strategy>
+ static inline OutputIterator apply(MultiPoint const& multipoint,
+ Linear const& linear,
+ RobustPolicy const& robust_policy,
+ OutputIterator oit,
+ Strategy const& strategy)
+ {
+ typedef std::vector
+ <
+ typename boost::range_value<MultiPoint>::type
+ > point_vector_type;
+
+ point_vector_type common_points;
+
+ // compute the common points
+ get_common_points(multipoint, linear,
+ std::back_inserter(common_points));
+
+ return multipoint_multipoint_point
+ <
+ MultiPoint, point_vector_type, PointOut, OverlayType
+ >::apply(multipoint, common_points, robust_policy, oit, strategy);
+ }
+};
+
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace detail_dispatch { namespace overlay
+{
+
+// dispatch struct for pointlike-linear difference/intersection computation
+template
+<
+ typename PointLike,
+ typename Linear,
+ typename PointOut,
+ overlay_type OverlayType,
+ typename Tag1,
+ typename Tag2
+>
+struct pointlike_linear_point
+ : not_implemented<PointLike, Linear, PointOut>
+{};
+
+
+template
+<
+ typename Point,
+ typename Linear,
+ typename PointOut,
+ overlay_type OverlayType
+>
+struct pointlike_linear_point
+ <
+ Point, Linear, PointOut, OverlayType, point_tag, linear_tag
+ > : detail::overlay::point_linear_point
+ <
+ Point, Linear, PointOut, OverlayType,
+ detail::not_<detail::disjoint::reverse_covered_by>
+ >
+{};
+
+
+template
+<
+ typename Point,
+ typename Segment,
+ typename PointOut,
+ overlay_type OverlayType
+>
+struct pointlike_linear_point
+ <
+ Point, Segment, PointOut, OverlayType, point_tag, segment_tag
+ > : detail::overlay::point_linear_point
+ <
+ Point, Segment, PointOut, OverlayType,
+ detail::not_<detail::disjoint::reverse_covered_by>
+ >
+{};
+
+
+template
+<
+ typename MultiPoint,
+ typename Linear,
+ typename PointOut,
+ overlay_type OverlayType
+>
+struct pointlike_linear_point
+ <
+ MultiPoint, Linear, PointOut, OverlayType, multi_point_tag, linear_tag
+ > : detail::overlay::multipoint_linear_point
+ <
+ MultiPoint, Linear, PointOut, OverlayType,
+ detail::not_<detail::disjoint::reverse_covered_by>
+ >
+{};
+
+
+template
+<
+ typename MultiPoint,
+ typename Segment,
+ typename PointOut,
+ overlay_type OverlayType
+>
+struct pointlike_linear_point
+ <
+ MultiPoint, Segment, PointOut, OverlayType, multi_point_tag, segment_tag
+ > : detail::overlay::multipoint_segment_point
+ <
+ MultiPoint, Segment, PointOut, OverlayType,
+ detail::not_<detail::disjoint::reverse_covered_by>
+ >
+{};
+
+
+}} // namespace detail_dispatch::overlay
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_POINTLIKE_LINEAR_HPP
diff --git a/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp b/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp
index 0af062d271..438a377876 100644
--- a/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp
+++ b/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -14,9 +14,9 @@
#include <algorithm>
#include <vector>
-#include <boost/assert.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -182,7 +182,7 @@ struct multipoint_point_point
OutputIterator oit,
Strategy const&)
{
- BOOST_ASSERT( OverlayType == overlay_difference );
+ BOOST_GEOMETRY_ASSERT( OverlayType == overlay_difference );
for (typename boost::range_iterator<MultiPoint const>::type
it = boost::begin(multipoint);
@@ -264,7 +264,7 @@ struct multipoint_multipoint_point
>::apply(multipoint2, multipoint1, robust_policy, oit, strategy);
}
- std::vector<typename point_type<MultiPoint2>::type>
+ std::vector<typename boost::range_value<MultiPoint2>::type>
points2(boost::begin(multipoint2), boost::end(multipoint2));
std::sort(points2.begin(), points2.end(), detail::relate::less());
diff --git a/boost/geometry/algorithms/detail/overlay/ring_properties.hpp b/boost/geometry/algorithms/detail/overlay/ring_properties.hpp
index b469052c84..0f2da67b62 100644
--- a/boost/geometry/algorithms/detail/overlay/ring_properties.hpp
+++ b/boost/geometry/algorithms/detail/overlay/ring_properties.hpp
@@ -29,6 +29,8 @@ struct ring_properties
typedef Point point_type;
typedef typename default_area_result<Point>::type area_type;
+ bool valid;
+
// Filled by "select_rings"
Point point;
area_type area;
@@ -43,7 +45,8 @@ struct ring_properties
std::vector<ring_identifier> children;
inline ring_properties()
- : area(area_type())
+ : valid(false)
+ , area(area_type())
, reversed(false)
, discarded(false)
, parent_area(-1)
@@ -59,7 +62,7 @@ struct ring_properties
// We should take a point somewhere in the middle of the ring,
// to avoid taking a point on a (self)tangency,
// in cases where multiple points come together
- geometry::point_on_border(this->point, ring_or_box, true);
+ valid = geometry::point_on_border(this->point, ring_or_box, true);
}
inline area_type get_area() const
diff --git a/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp b/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp
index 516ec349e8..e77a163dd5 100644
--- a/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp
+++ b/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp
@@ -19,7 +19,7 @@
#endif
-#include <boost/geometry/algorithms/detail/signed_index_type.hpp>
+#include <boost/geometry/algorithms/detail/signed_size_type.hpp>
namespace boost { namespace geometry
@@ -40,10 +40,10 @@ struct segment_identifier
, segment_index(-1)
{}
- inline segment_identifier(signed_index_type src,
- signed_index_type mul,
- signed_index_type rin,
- signed_index_type seg)
+ inline segment_identifier(signed_size_type src,
+ signed_size_type mul,
+ signed_size_type rin,
+ signed_size_type seg)
: source_index(src)
, multi_index(mul)
, ring_index(rin)
@@ -81,10 +81,10 @@ struct segment_identifier
}
#endif
- signed_index_type source_index;
- signed_index_type multi_index;
- signed_index_type ring_index;
- signed_index_type segment_index;
+ signed_size_type source_index;
+ signed_size_type multi_index;
+ signed_size_type ring_index;
+ signed_size_type segment_index;
};
diff --git a/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp b/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp
index b1f984ffe1..a74cb83f77 100644
--- a/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp
+++ b/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp
@@ -12,6 +12,7 @@
#include <cstddef>
+#include <boost/mpl/vector_c.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/access.hpp>
diff --git a/boost/geometry/algorithms/detail/overlay/traverse.hpp b/boost/geometry/algorithms/detail/overlay/traverse.hpp
index 59d2ba703e..803a164711 100644
--- a/boost/geometry/algorithms/detail/overlay/traverse.hpp
+++ b/boost/geometry/algorithms/detail/overlay/traverse.hpp
@@ -18,6 +18,7 @@
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
@@ -116,8 +117,8 @@ inline bool assign_next_ip(G1 const& g1, G2 const& g2,
return false;
}
- BOOST_ASSERT(info.enriched.travels_to_vertex_index >= 0);
- BOOST_ASSERT(info.enriched.travels_to_ip_index >= 0);
+ BOOST_GEOMETRY_ASSERT(info.enriched.travels_to_vertex_index >= 0);
+ BOOST_GEOMETRY_ASSERT(info.enriched.travels_to_ip_index >= 0);
if (info.seg_id.source_index == 0)
{
@@ -150,8 +151,8 @@ inline bool assign_next_ip(G1 const& g1, G2 const& g2,
inline bool select_source(operation_type operation,
- signed_index_type source1,
- signed_index_type source2)
+ signed_size_type source1,
+ signed_size_type source2)
{
return (operation == operation_intersection && source1 != source2)
|| (operation == operation_union && source1 == source2)
diff --git a/boost/geometry/algorithms/detail/partition.hpp b/boost/geometry/algorithms/detail/partition.hpp
index 25a34ba2ec..8b19add479 100644
--- a/boost/geometry/algorithms/detail/partition.hpp
+++ b/boost/geometry/algorithms/detail/partition.hpp
@@ -1,6 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2011-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// 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.
+
+// Contributed and/or modified by Menelaos Karavelas, 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
@@ -9,10 +14,13 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_PARTITION_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_PARTITION_HPP
+#include <cstddef>
#include <vector>
-#include <boost/range/algorithm/copy.hpp>
-#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/range.hpp>
+#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/algorithms/assign.hpp>
+
namespace boost { namespace geometry
{
@@ -20,8 +28,6 @@ namespace boost { namespace geometry
namespace detail { namespace partition
{
-typedef std::vector<std::size_t> index_vector_type;
-
template <int Dimension, typename Box>
inline void divide_box(Box const& box, Box& lower_box, Box& upper_box)
{
@@ -38,31 +44,26 @@ inline void divide_box(Box const& box, Box& lower_box, Box& upper_box)
geometry::set<min_corner, Dimension>(upper_box, mid);
}
-// Divide collection into three subsets: lower, upper and oversized
+// Divide forward_range into three subsets: lower, upper and oversized
// (not-fitting)
// (lower == left or bottom, upper == right or top)
-template <typename OverlapsPolicy, typename InputCollection, typename Box>
+template <typename OverlapsPolicy, typename Box, typename IteratorVector>
inline void divide_into_subsets(Box const& lower_box,
Box const& upper_box,
- InputCollection const& collection,
- index_vector_type const& input,
- index_vector_type& lower,
- index_vector_type& upper,
- index_vector_type& exceeding)
+ IteratorVector const& input,
+ IteratorVector& lower,
+ IteratorVector& upper,
+ IteratorVector& exceeding)
{
- typedef boost::range_iterator
+ typedef typename boost::range_iterator
<
- index_vector_type const
- >::type index_iterator_type;
+ IteratorVector const
+ >::type it_type;
- for(index_iterator_type it = boost::begin(input);
- it != boost::end(input);
- ++it)
+ for(it_type it = boost::begin(input); it != boost::end(input); ++it)
{
- bool const lower_overlapping = OverlapsPolicy::apply(lower_box,
- collection[*it]);
- bool const upper_overlapping = OverlapsPolicy::apply(upper_box,
- collection[*it]);
+ bool const lower_overlapping = OverlapsPolicy::apply(lower_box, **it);
+ bool const upper_overlapping = OverlapsPolicy::apply(upper_box, **it);
if (lower_overlapping && upper_overlapping)
{
@@ -84,99 +85,109 @@ inline void divide_into_subsets(Box const& lower_box,
}
}
-template <typename ExpandPolicy, typename Box, typename InputCollection>
-inline void expand_with_elements(Box& total,
- InputCollection const& collection,
- index_vector_type const& input)
+template
+<
+ typename ExpandPolicy,
+ typename Box,
+ typename IteratorVector
+>
+inline void expand_with_elements(Box& total, IteratorVector const& input)
{
- typedef boost::range_iterator<index_vector_type const>::type it_type;
+ 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, collection[*it]);
+ ExpandPolicy::apply(total, **it);
}
}
-// Match collection with itself
-template <typename InputCollection, typename Policy>
-inline void handle_one(InputCollection const& collection,
- index_vector_type const& input,
- Policy& policy)
+// Match forward_range with itself
+template <typename Policy, typename IteratorVector>
+inline void handle_one(IteratorVector const& input, Policy& policy)
{
if (boost::size(input) == 0)
{
return;
}
- typedef boost::range_iterator<index_vector_type const>::type
- index_iterator_type;
+ typedef typename boost::range_iterator<IteratorVector const>::type it_type;
// Quadratic behaviour at lowest level (lowest quad, or all exceeding)
- for(index_iterator_type it1 = boost::begin(input);
- it1 != boost::end(input);
- ++it1)
+ for (it_type it1 = boost::begin(input); it1 != boost::end(input); ++it1)
{
- index_iterator_type it2 = it1;
- for(++it2; it2 != boost::end(input); ++it2)
+ it_type it2 = it1;
+ for (++it2; it2 != boost::end(input); ++it2)
{
- policy.apply(collection[*it1], collection[*it2]);
+ policy.apply(**it1, **it2);
}
}
}
-// Match collection 1 with collection 2
+// Match forward range 1 with forward range 2
template
<
- typename InputCollection1,
- typename InputCollection2,
- typename Policy
+ typename Policy,
+ typename IteratorVector1,
+ typename IteratorVector2
>
-inline void handle_two(
- InputCollection1 const& collection1, index_vector_type const& input1,
- InputCollection2 const& collection2, index_vector_type const& input2,
+inline void handle_two(IteratorVector1 const& input1,
+ IteratorVector2 const& input2,
Policy& policy)
{
+ typedef typename boost::range_iterator
+ <
+ IteratorVector1 const
+ >::type iterator_type1;
+
+ typedef typename boost::range_iterator
+ <
+ IteratorVector2 const
+ >::type iterator_type2;
+
if (boost::size(input1) == 0 || boost::size(input2) == 0)
{
return;
}
- typedef boost::range_iterator
- <
- index_vector_type const
- >::type index_iterator_type;
-
- for(index_iterator_type it1 = boost::begin(input1);
+ for(iterator_type1 it1 = boost::begin(input1);
it1 != boost::end(input1);
++it1)
{
- for(index_iterator_type it2 = boost::begin(input2);
+ for(iterator_type2 it2 = boost::begin(input2);
it2 != boost::end(input2);
++it2)
{
- policy.apply(collection1[*it1], collection2[*it2]);
+ policy.apply(**it1, **it2);
}
}
}
-inline bool recurse_ok(index_vector_type const& input,
+template <typename IteratorVector>
+inline bool recurse_ok(IteratorVector const& input,
std::size_t min_elements, std::size_t level)
{
return boost::size(input) >= min_elements
&& level < 100;
}
-inline bool recurse_ok(index_vector_type const& input1,
- index_vector_type const& input2,
+template <typename IteratorVector1, typename IteratorVector2>
+inline bool recurse_ok(IteratorVector1 const& input1,
+ IteratorVector2 const& input2,
std::size_t min_elements, std::size_t level)
{
return boost::size(input1) >= min_elements
&& recurse_ok(input2, min_elements, level);
}
-inline bool recurse_ok(index_vector_type const& input1,
- index_vector_type const& input2,
- index_vector_type const& input3,
+template
+<
+ typename IteratorVector1,
+ typename IteratorVector2,
+ typename IteratorVector3
+>
+inline bool recurse_ok(IteratorVector1 const& input1,
+ IteratorVector2 const& input2,
+ IteratorVector3 const& input3,
std::size_t min_elements, std::size_t level)
{
return boost::size(input1) >= min_elements
@@ -193,7 +204,7 @@ template
typename ExpandPolicy2,
typename VisitBoxPolicy
>
-class partition_two_collections;
+class partition_two_ranges;
template
@@ -204,79 +215,71 @@ template
typename ExpandPolicy,
typename VisitBoxPolicy
>
-class partition_one_collection
+class partition_one_range
{
- typedef std::vector<std::size_t> index_vector_type;
-
- template <typename InputCollection>
- static inline Box get_new_box(InputCollection const& collection,
- index_vector_type const& input)
+ template <typename IteratorVector>
+ static inline Box get_new_box(IteratorVector const& input)
{
Box box;
geometry::assign_inverse(box);
- expand_with_elements<ExpandPolicy>(box, collection, input);
+ expand_with_elements<ExpandPolicy>(box, input);
return box;
}
- template <typename InputCollection, typename Policy>
+ template <typename Policy, typename IteratorVector>
static inline void next_level(Box const& box,
- InputCollection const& collection,
- index_vector_type const& input,
+ IteratorVector const& input,
std::size_t level, std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
{
if (recurse_ok(input, min_elements, level))
{
- partition_one_collection
+ partition_one_range
<
1 - Dimension,
Box,
OverlapsPolicy,
ExpandPolicy,
VisitBoxPolicy
- >::apply(box, collection, input,
- level + 1, min_elements, policy, box_policy);
+ >::apply(box, input, level + 1, min_elements, policy, box_policy);
}
else
{
- handle_one(collection, input, policy);
+ handle_one(input, policy);
}
}
- // Function to switch to two collections if there are geometries exceeding
- // the separation line
- template <typename InputCollection, typename Policy>
+ // Function to switch to two forward ranges if there are
+ // geometries exceeding the separation line
+ template <typename Policy, typename IteratorVector>
static inline void next_level2(Box const& box,
- InputCollection const& collection,
- index_vector_type const& input1,
- index_vector_type const& input2,
+ IteratorVector const& input1,
+ IteratorVector const& input2,
std::size_t level, std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
{
-
if (recurse_ok(input1, input2, min_elements, level))
{
- partition_two_collections
+ partition_two_ranges
<
1 - Dimension,
Box,
OverlapsPolicy, OverlapsPolicy,
ExpandPolicy, ExpandPolicy,
VisitBoxPolicy
- >::apply(box, collection, input1, collection, input2,
- level + 1, min_elements, policy, box_policy);
+ >::apply(box, input1, input2, level + 1, min_elements,
+ policy, box_policy);
}
else
{
- handle_two(collection, input1, collection, input2, policy);
+ handle_two(input1, input2, policy);
}
}
public :
- template <typename InputCollection, typename Policy>
+ template <typename Policy, typename IteratorVector>
static inline void apply(Box const& box,
- InputCollection const& collection,
- index_vector_type const& input,
+ IteratorVector const& input,
std::size_t level,
std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
@@ -286,33 +289,31 @@ public :
Box lower_box, upper_box;
divide_box<Dimension>(box, lower_box, upper_box);
- index_vector_type lower, upper, exceeding;
- divide_into_subsets<OverlapsPolicy>(lower_box, upper_box, collection,
+ IteratorVector lower, upper, exceeding;
+ divide_into_subsets<OverlapsPolicy>(lower_box, upper_box,
input, lower, upper, exceeding);
if (boost::size(exceeding) > 0)
{
// Get the box of exceeding-only
- Box exceeding_box = get_new_box(collection, exceeding);
+ Box exceeding_box = get_new_box(exceeding);
// Recursively do exceeding elements only, in next dimension they
// will probably be less exceeding within the new box
- next_level(exceeding_box, collection, exceeding, level,
- min_elements, policy, box_policy);
-
- // Switch to two collections, combine exceeding with lower resp upper
- // but not lower/lower, upper/upper
- next_level2(exceeding_box, collection, exceeding, lower, level,
- min_elements, policy, box_policy);
- next_level2(exceeding_box, collection, exceeding, upper, level,
- min_elements, policy, box_policy);
+ next_level(exceeding_box, exceeding, level, min_elements,
+ 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);
+ next_level2(exceeding_box, exceeding, upper, level, min_elements,
+ policy, box_policy);
}
// Recursively call operation both parts
- next_level(lower_box, collection, lower, level, min_elements,
- policy, box_policy);
- next_level(upper_box, collection, upper, level, min_elements,
- policy, box_policy);
+ next_level(lower_box, lower, level, min_elements, policy, box_policy);
+ next_level(upper_box, upper, level, min_elements, policy, box_policy);
}
};
@@ -326,25 +327,21 @@ template
typename ExpandPolicy2,
typename VisitBoxPolicy
>
-class partition_two_collections
+class partition_two_ranges
{
- typedef std::vector<std::size_t> index_vector_type;
-
template
<
- typename InputCollection1,
- typename InputCollection2,
- typename Policy
+ typename Policy,
+ typename IteratorVector1,
+ typename IteratorVector2
>
static inline void next_level(Box const& box,
- InputCollection1 const& collection1,
- index_vector_type const& input1,
- InputCollection2 const& collection2,
- index_vector_type const& input2,
+ IteratorVector1 const& input1,
+ IteratorVector2 const& input2,
std::size_t level, std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
{
- partition_two_collections
+ partition_two_ranges
<
1 - Dimension,
Box,
@@ -353,50 +350,38 @@ class partition_two_collections
ExpandPolicy1,
ExpandPolicy2,
VisitBoxPolicy
- >::apply(box, collection1, input1, collection2, input2,
- level + 1, min_elements,
- policy, box_policy);
+ >::apply(box, input1, input2, level + 1, min_elements,
+ policy, box_policy);
}
- template
- <
- typename ExpandPolicy,
- typename InputCollection
- >
- static inline Box get_new_box(InputCollection const& collection,
- index_vector_type const& input)
+ template <typename ExpandPolicy, typename IteratorVector>
+ static inline Box get_new_box(IteratorVector const& input)
{
Box box;
geometry::assign_inverse(box);
- expand_with_elements<ExpandPolicy>(box, collection, input);
+ expand_with_elements<ExpandPolicy>(box, input);
return box;
}
- template
- <
- typename InputCollection1,
- typename InputCollection2
- >
- static inline Box get_new_box(InputCollection1 const& collection1,
- index_vector_type const& input1,
- InputCollection2 const& collection2,
- index_vector_type const& input2)
+ template <typename IteratorVector1, typename IteratorVector2>
+ static inline Box get_new_box(IteratorVector1 const& input1,
+ IteratorVector2 const& input2)
{
- Box box = get_new_box<ExpandPolicy1>(collection1, input1);
- expand_with_elements<ExpandPolicy2>(box, collection2, input2);
+ Box box = get_new_box<ExpandPolicy1>(input1);
+ expand_with_elements<ExpandPolicy2>(box, input2);
return box;
}
public :
template
<
- typename InputCollection1,
- typename InputCollection2,
- typename Policy
+ typename Policy,
+ typename IteratorVector1,
+ typename IteratorVector2
>
static inline void apply(Box const& box,
- InputCollection1 const& collection1, index_vector_type const& input1,
- InputCollection2 const& collection2, index_vector_type const& input2,
+ IteratorVector1 const& input1,
+ IteratorVector2 const& input2,
std::size_t level,
std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
@@ -406,11 +391,11 @@ public :
Box lower_box, upper_box;
divide_box<Dimension>(box, lower_box, upper_box);
- index_vector_type lower1, upper1, exceeding1;
- index_vector_type lower2, upper2, exceeding2;
- divide_into_subsets<OverlapsPolicy1>(lower_box, upper_box, collection1,
+ 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, collection2,
+ divide_into_subsets<OverlapsPolicy2>(lower_box, upper_box,
input2, lower2, upper2, exceeding2);
if (boost::size(exceeding1) > 0)
@@ -419,35 +404,31 @@ public :
if (recurse_ok(exceeding1, exceeding2, min_elements, level))
{
- Box exceeding_box = get_new_box(collection1, exceeding1,
- collection2, exceeding2);
- next_level(exceeding_box, collection1, exceeding1,
- collection2, exceeding2, level,
- min_elements, policy, box_policy);
+ Box exceeding_box = get_new_box(exceeding1, exceeding2);
+ next_level(exceeding_box, exceeding1, exceeding2, level,
+ min_elements, policy, box_policy);
}
else
{
- handle_two(collection1, exceeding1, collection2, exceeding2,
- policy);
+ handle_two(exceeding1, exceeding2, policy);
}
// All exceeding from 1 with lower and upper of 2:
- // (Check sizes of all three collections to avoid recurse into
+ // (Check sizes of all three forward ranges to avoid recurse into
// the same combinations again and again)
if (recurse_ok(lower2, upper2, exceeding1, min_elements, level))
{
- Box exceeding_box
- = get_new_box<ExpandPolicy1>(collection1, exceeding1);
- next_level(exceeding_box, collection1, exceeding1,
- collection2, lower2, level, min_elements, policy, box_policy);
- next_level(exceeding_box, collection1, exceeding1,
- collection2, upper2, level, min_elements, policy, box_policy);
+ Box exceeding_box = get_new_box<ExpandPolicy1>(exceeding1);
+ next_level(exceeding_box, exceeding1, lower2, level,
+ min_elements, policy, box_policy);
+ next_level(exceeding_box, exceeding1, upper2, level,
+ min_elements, policy, box_policy);
}
else
{
- handle_two(collection1, exceeding1, collection2, lower2, policy);
- handle_two(collection1, exceeding1, collection2, upper2, policy);
+ handle_two(exceeding1, lower2, policy);
+ handle_two(exceeding1, upper2, policy);
}
}
@@ -456,37 +437,36 @@ 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>(collection2, exceeding2);
- next_level(exceeding_box, collection1, lower1,
- collection2, exceeding2, level, min_elements, policy, box_policy);
- next_level(exceeding_box, collection1, upper1,
- collection2, exceeding2, level, min_elements, policy, box_policy);
+ Box exceeding_box = get_new_box<ExpandPolicy2>(exceeding2);
+ next_level(exceeding_box, lower1, exceeding2, level,
+ min_elements, policy, box_policy);
+ next_level(exceeding_box, upper1, exceeding2, level,
+ min_elements, policy, box_policy);
}
else
{
- handle_two(collection1, lower1, collection2, exceeding2, policy);
- handle_two(collection1, upper1, collection2, exceeding2, policy);
+ handle_two(lower1, exceeding2, policy);
+ handle_two(upper1, exceeding2, policy);
}
}
if (recurse_ok(lower1, lower2, min_elements, level))
{
- next_level(lower_box, collection1, lower1, collection2, lower2, level,
- min_elements, policy, box_policy);
+ next_level(lower_box, lower1, lower2, level,
+ min_elements, policy, box_policy);
}
else
{
- handle_two(collection1, lower1, collection2, lower2, policy);
+ handle_two(lower1, lower2, policy);
}
if (recurse_ok(upper1, upper2, min_elements, level))
{
- next_level(upper_box, collection1, upper1, collection2, upper2, level,
- min_elements, policy, box_policy);
+ next_level(upper_box, upper1, upper2, level,
+ min_elements, policy, box_policy);
}
else
{
- handle_two(collection1, upper1, collection2, upper2, policy);
+ handle_two(upper1, upper2, policy);
}
}
};
@@ -523,63 +503,67 @@ template
>
class partition
{
- typedef std::vector<std::size_t> index_vector_type;
-
- template <typename ExpandPolicy, typename IncludePolicy, typename InputCollection>
- static inline void expand_to_collection(InputCollection const& collection,
- Box& total, index_vector_type& index_vector)
+ template
+ <
+ typename ExpandPolicy,
+ typename IncludePolicy,
+ typename ForwardRange,
+ typename IteratorVector
+ >
+ static inline void expand_to_range(ForwardRange const& forward_range,
+ Box& total, IteratorVector& iterator_vector)
{
- std::size_t index = 0;
- for(typename boost::range_iterator<InputCollection const>::type it
- = boost::begin(collection);
- it != boost::end(collection);
- ++it, ++index)
+ 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);
- index_vector.push_back(index);
+ iterator_vector.push_back(it);
}
}
}
public :
- template <typename InputCollection, typename VisitPolicy>
- static inline void apply(InputCollection const& collection,
+ template <typename ForwardRange, typename VisitPolicy>
+ static inline void apply(ForwardRange const& forward_range,
VisitPolicy& visitor,
std::size_t min_elements = 16,
VisitBoxPolicy box_visitor = detail::partition::visit_no_policy()
)
{
- if (std::size_t(boost::size(collection)) > min_elements)
+ typedef typename boost::range_iterator
+ <
+ ForwardRange const
+ >::type iterator_type;
+
+ if (std::size_t(boost::size(forward_range)) > min_elements)
{
- index_vector_type index_vector;
+ std::vector<iterator_type> iterator_vector;
Box total;
assign_inverse(total);
- expand_to_collection<ExpandPolicy1, IncludePolicy1>(collection,
- total, index_vector);
+ expand_to_range<ExpandPolicy1, IncludePolicy1>(forward_range,
+ total, iterator_vector);
- detail::partition::partition_one_collection
+ detail::partition::partition_one_range
<
0, Box,
OverlapsPolicy1,
ExpandPolicy1,
VisitBoxPolicy
- >::apply(total, collection, index_vector, 0, min_elements,
- visitor, box_visitor);
+ >::apply(total, iterator_vector, 0, min_elements,
+ visitor, box_visitor);
}
else
{
- typedef typename boost::range_iterator
- <
- InputCollection const
- >::type iterator_type;
- for(iterator_type it1 = boost::begin(collection);
- it1 != boost::end(collection);
+ for(iterator_type it1 = boost::begin(forward_range);
+ it1 != boost::end(forward_range);
++it1)
{
iterator_type it2 = it1;
- for(++it2; it2 != boost::end(collection); ++it2)
+ for(++it2; it2 != boost::end(forward_range); ++it2)
{
visitor.apply(*it1, *it2);
}
@@ -589,53 +573,55 @@ public :
template
<
- typename InputCollection1,
- typename InputCollection2,
+ typename ForwardRange1,
+ typename ForwardRange2,
typename VisitPolicy
>
- static inline void apply(InputCollection1 const& collection1,
- InputCollection2 const& collection2,
+ 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()
+ VisitBoxPolicy box_visitor
+ = detail::partition::visit_no_policy()
)
{
- if (std::size_t(boost::size(collection1)) > min_elements
- && std::size_t(boost::size(collection2)) > min_elements)
+ typedef typename boost::range_iterator
+ <
+ ForwardRange1 const
+ >::type iterator_type1;
+
+ typedef typename boost::range_iterator
+ <
+ ForwardRange2 const
+ >::type iterator_type2;
+
+ if (std::size_t(boost::size(forward_range1)) > min_elements
+ && std::size_t(boost::size(forward_range2)) > min_elements)
{
- index_vector_type index_vector1, index_vector2;
+ std::vector<iterator_type1> iterator_vector1;
+ std::vector<iterator_type2> iterator_vector2;
Box total;
assign_inverse(total);
- expand_to_collection<ExpandPolicy1, IncludePolicy1>(collection1,
- total, index_vector1);
- expand_to_collection<ExpandPolicy2, IncludePolicy2>(collection2,
- total, index_vector2);
+ expand_to_range<ExpandPolicy1, IncludePolicy1>(forward_range1,
+ total, iterator_vector1);
+ expand_to_range<ExpandPolicy2, IncludePolicy2>(forward_range2,
+ total, iterator_vector2);
- detail::partition::partition_two_collections
+ detail::partition::partition_two_ranges
<
0, Box, OverlapsPolicy1, OverlapsPolicy2,
ExpandPolicy1, ExpandPolicy2, VisitBoxPolicy
- >::apply(total,
- collection1, index_vector1,
- collection2, index_vector2,
- 0, min_elements, visitor, box_visitor);
+ >::apply(total, iterator_vector1, iterator_vector2,
+ 0, min_elements, visitor, box_visitor);
}
else
{
- typedef typename boost::range_iterator
- <
- InputCollection1 const
- >::type iterator_type1;
- typedef typename boost::range_iterator
- <
- InputCollection2 const
- >::type iterator_type2;
- for(iterator_type1 it1 = boost::begin(collection1);
- it1 != boost::end(collection1);
+ for(iterator_type1 it1 = boost::begin(forward_range1);
+ it1 != boost::end(forward_range1);
++it1)
{
- for(iterator_type2 it2 = boost::begin(collection2);
- it2 != boost::end(collection2);
+ for(iterator_type2 it2 = boost::begin(forward_range2);
+ it2 != boost::end(forward_range2);
++it2)
{
visitor.apply(*it1, *it2);
diff --git a/boost/geometry/algorithms/detail/recalculate.hpp b/boost/geometry/algorithms/detail/recalculate.hpp
index 2c3ea7413b..056f7c6e1d 100644
--- a/boost/geometry/algorithms/detail/recalculate.hpp
+++ b/boost/geometry/algorithms/detail/recalculate.hpp
@@ -21,6 +21,7 @@
#include <boost/mpl/if.hpp>
#include <boost/numeric/conversion/bounds.hpp>
#include <boost/numeric/conversion/cast.hpp>
+#include <boost/range.hpp>
#include <boost/type_traits.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
diff --git a/boost/geometry/algorithms/detail/relate/areal_areal.hpp b/boost/geometry/algorithms/detail/relate/areal_areal.hpp
index 2859841de4..cc9c1b67ca 100644
--- a/boost/geometry/algorithms/detail/relate/areal_areal.hpp
+++ b/boost/geometry/algorithms/detail/relate/areal_areal.hpp
@@ -88,7 +88,7 @@ public:
// TODO: This is O(N)
// Run in a loop O(NM) - optimize!
int const pig = detail::within::point_in_geometry(pt, m_other_areal);
- //BOOST_ASSERT( pig != 0 );
+ //BOOST_GEOMETRY_ASSERT( pig != 0 );
// inside
if ( pig > 0 )
@@ -104,9 +104,9 @@ public:
// Check if any interior ring is outside
ring_identifier ring_id(0, -1, 0);
- int const irings_count = boost::numeric_cast<int>(
- geometry::num_interior_rings(areal) );
- for ( ; ring_id.ring_index < irings_count ; ++ring_id.ring_index )
+ std::size_t const irings_count = geometry::num_interior_rings(areal);
+ for ( ; static_cast<std::size_t>(ring_id.ring_index) < irings_count ;
+ ++ring_id.ring_index )
{
typename detail::sub_range_return_type<Areal const>::type
range_ref = detail::sub_range(areal, ring_id);
@@ -140,9 +140,9 @@ public:
// Check if any interior ring is inside
ring_identifier ring_id(0, -1, 0);
- int const irings_count = boost::numeric_cast<int>(
- geometry::num_interior_rings(areal) );
- for ( ; ring_id.ring_index < irings_count ; ++ring_id.ring_index )
+ std::size_t const irings_count = geometry::num_interior_rings(areal);
+ for ( ; static_cast<std::size_t>(ring_id.ring_index) < irings_count ;
+ ++ring_id.ring_index )
{
typename detail::sub_range_return_type<Areal const>::type
range_ref = detail::sub_range(areal, ring_id);
@@ -405,7 +405,7 @@ struct areal_areal
typename TurnIt>
void apply(Result & result, TurnIt it)
{
- //BOOST_ASSERT( it != last );
+ //BOOST_GEOMETRY_ASSERT( it != last );
overlay::operation_type const op = it->operations[op_id].operation;
@@ -498,7 +498,7 @@ struct areal_areal
template <typename Result>
void apply(Result & result)
{
- //BOOST_ASSERT( first != last );
+ //BOOST_GEOMETRY_ASSERT( first != last );
if ( m_exit_detected /*m_previous_operation == overlay::operation_union*/ )
{
@@ -618,7 +618,7 @@ struct areal_areal
// O(N) - running it in a loop gives O(NM)
int const pig = detail::within::point_in_geometry(range::front(range_ref), other_geometry);
- //BOOST_ASSERT(pig != 0);
+ //BOOST_GEOMETRY_ASSERT(pig != 0);
if ( pig > 0 )
{
update<interior, interior, '2', transpose_result>(m_result);
@@ -793,8 +793,8 @@ struct areal_areal
{
segment_identifier const& seg_id = turn.operations[OpId].seg_id;
- signed_index_type
- count = boost::numeric_cast<signed_index_type>(
+ signed_size_type
+ count = boost::numeric_cast<signed_size_type>(
geometry::num_interior_rings(
detail::single_geometry(analyser.geometry, seg_id)));
@@ -804,8 +804,8 @@ struct areal_areal
template <typename Analyser, typename Turn>
static inline void for_no_turns_rings(Analyser & analyser,
Turn const& turn,
- signed_index_type first,
- signed_index_type last)
+ signed_size_type first,
+ signed_size_type last)
{
segment_identifier seg_id = turn.operations[OpId].seg_id;
diff --git a/boost/geometry/algorithms/detail/relate/boundary_checker.hpp b/boost/geometry/algorithms/detail/relate/boundary_checker.hpp
index f98c3e9b82..9de1bacb7d 100644
--- a/boost/geometry/algorithms/detail/relate/boundary_checker.hpp
+++ b/boost/geometry/algorithms/detail/relate/boundary_checker.hpp
@@ -47,7 +47,7 @@ public:
boost::ignore_unused_variable_warning(pt);
#ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER
// may give false positives for INT
- BOOST_ASSERT( (BoundaryQuery == boundary_front || BoundaryQuery == boundary_any)
+ BOOST_GEOMETRY_ASSERT( (BoundaryQuery == boundary_front || BoundaryQuery == boundary_any)
&& detail::equals::equals_point_point(pt, range::front(geometry))
|| (BoundaryQuery == boundary_back || BoundaryQuery == boundary_any)
&& detail::equals::equals_point_point(pt, range::back(geometry)) );
diff --git a/boost/geometry/algorithms/detail/relate/de9im.hpp b/boost/geometry/algorithms/detail/relate/de9im.hpp
new file mode 100644
index 0000000000..713a3fc8f0
--- /dev/null
+++ b/boost/geometry/algorithms/detail/relate/de9im.hpp
@@ -0,0 +1,439 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// 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.
+
+// 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_RELATE_DE9IM_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_DE9IM_HPP
+
+#include <boost/mpl/is_sequence.hpp>
+#include <boost/mpl/push_back.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/vector_c.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/tuple/tuple.hpp>
+
+#include <boost/geometry/algorithms/detail/relate/result.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
+#include <boost/geometry/core/topological_dimension.hpp>
+#include <boost/geometry/core/tag.hpp>
+
+// TEMP - move this header to geometry/detail
+#include <boost/geometry/index/detail/tuples.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace de9im
+{
+
+/*!
+\brief DE-9IM model intersection matrix.
+\ingroup de9im
+\details This matrix can be used to express spatial relations as defined in
+ Dimensionally Extended 9-Intersection Model.
+
+\qbk{[heading See also]}
+\qbk{* [link geometry.reference.algorithms.relation relation]}
+ */
+class matrix
+ : public detail::relate::matrix<3, 3>
+{
+#ifdef DOXYGEN_INVOKED
+public:
+ /*!
+ \brief Initializes all of the matrix elements to F
+ */
+ matrix();
+ /*!
+ \brief Subscript operator
+ \param index The index of the element
+ \return The element
+ */
+ char operator[](std::size_t index) const;
+ /*!
+ \brief Returns the iterator to the first element
+ \return const RandomAccessIterator
+ */
+ const_iterator begin() const;
+ /*!
+ \brief Returns the iterator past the last element
+ \return const RandomAccessIterator
+ */
+ const_iterator end() const;
+ /*!
+ \brief Returns the number of elements
+ \return 9
+ */
+ static std::size_t size();
+ /*!
+ \brief Returns raw pointer to elements
+ \return const pointer to array of elements
+ */
+ inline const char * data() const;
+ /*!
+ \brief Returns std::string containing elements
+ \return string containing elements
+ */
+ inline std::string str() const;
+#endif
+};
+
+/*!
+\brief DE-9IM model intersection mask.
+\ingroup de9im
+\details This mask can be used to check spatial relations as defined in
+ Dimensionally Extended 9-Intersection Model.
+
+\qbk{[heading See also]}
+\qbk{* [link geometry.reference.algorithms.relate relate]}
+ */
+class mask
+ : public detail::relate::mask<3, 3>
+{
+ typedef detail::relate::mask<3, 3> base_type;
+
+public:
+ /*!
+ \brief The constructor.
+ \param code The mask pattern.
+ */
+ inline explicit mask(const char* code)
+ : base_type(code)
+ {}
+
+ /*!
+ \brief The constructor.
+ \param code The mask pattern.
+ */
+ inline explicit mask(std::string const& code)
+ : base_type(code.c_str(), code.size())
+ {}
+};
+
+// static_mask
+
+/*!
+\brief DE-9IM model intersection mask (static version).
+\ingroup de9im
+\details This mask can be used to check spatial relations as defined in
+ Dimensionally Extended 9-Intersection Model.
+\tparam II Interior/Interior intersection mask element
+\tparam IB Interior/Boundary intersection mask element
+\tparam IE Interior/Exterior intersection mask element
+\tparam BI Boundary/Interior intersection mask element
+\tparam BB Boundary/Boundary intersection mask element
+\tparam BE Boundary/Exterior intersection mask element
+\tparam EI Exterior/Interior intersection mask element
+\tparam EB Exterior/Boundary intersection mask element
+\tparam EE Exterior/Exterior intersection mask element
+
+\qbk{[heading See also]}
+\qbk{* [link geometry.reference.algorithms.relate relate]}
+ */
+template
+<
+ char II = '*', char IB = '*', char IE = '*',
+ char BI = '*', char BB = '*', char BE = '*',
+ char EI = '*', char EB = '*', char EE = '*'
+>
+class static_mask
+ : public detail::relate::static_mask
+ <
+ boost::mpl::vector_c
+ <
+ char, II, IB, IE, BI, BB, BE, EI, EB, EE
+ >,
+ 3, 3
+ >
+{};
+
+} // namespace de9im
+
+namespace detail { namespace de9im
+{
+
+// a small helper util for ORing static masks
+
+template
+<
+ typename Seq,
+ typename T,
+ bool IsSeq = boost::mpl::is_sequence<Seq>::value
+>
+struct push_back
+{
+ typedef typename boost::mpl::push_back
+ <
+ Seq,
+ T
+ >::type type;
+};
+
+template <typename Seq, typename T>
+struct push_back<Seq, T, false>
+{};
+
+}} // namespace detail::de9im
+
+namespace de9im
+{
+
+inline
+boost::tuples::cons
+ <
+ mask,
+ boost::tuples::cons<mask, boost::tuples::null_type>
+ >
+operator||(mask const& m1, mask const& m2)
+{
+ namespace bt = boost::tuples;
+
+ return bt::cons<mask, bt::cons<mask, bt::null_type> >
+ ( m1, bt::cons<mask, bt::null_type>(m2, bt::null_type()) );
+}
+
+template <typename Tail>
+inline
+typename index::detail::tuples::push_back
+ <
+ boost::tuples::cons<mask, Tail>,
+ mask
+ >::type
+operator||(boost::tuples::cons<mask, Tail> const& t, mask const& m)
+{
+ namespace bt = boost::tuples;
+
+ return index::detail::tuples::push_back
+ <
+ bt::cons<mask, Tail>,
+ mask
+ >::apply(t, m);
+}
+
+template
+<
+ char II1, char IB1, char IE1,
+ char BI1, char BB1, char BE1,
+ char EI1, char EB1, char EE1,
+ char II2, char IB2, char IE2,
+ char BI2, char BB2, char BE2,
+ char EI2, char EB2, char EE2
+>
+inline
+boost::mpl::vector<
+ static_mask<II1, IB1, IE1, BI1, BB1, BE1, EI1, EB1, EE1>,
+ static_mask<II2, IB2, IE2, BI2, BB2, BE2, EI2, EB2, EE2>
+>
+operator||(static_mask<II1, IB1, IE1, BI1, BB1, BE1, EI1, EB1, EE1> const& ,
+ static_mask<II2, IB2, IE2, BI2, BB2, BE2, EI2, EB2, EE2> const& )
+{
+ return boost::mpl::vector
+ <
+ static_mask<II1, IB1, IE1, BI1, BB1, BE1, EI1, EB1, EE1>,
+ static_mask<II2, IB2, IE2, BI2, BB2, BE2, EI2, EB2, EE2>
+ >();
+}
+
+template
+<
+ typename Seq,
+ char II, char IB, char IE,
+ char BI, char BB, char BE,
+ char EI, char EB, char EE
+>
+inline
+typename detail::de9im::push_back
+ <
+ Seq,
+ static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>
+ >::type
+operator||(Seq const& ,
+ static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE> const& )
+{
+ return typename detail::de9im::push_back
+ <
+ Seq,
+ static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>
+ >::type();
+}
+
+} // namespace de9im
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace de9im
+{
+
+// PREDEFINED MASKS
+
+// TODO:
+// 1. specialize for simplified masks if available
+// e.g. for TOUCHES use 1 mask for A/A
+// 2. Think about dimensions > 2 e.g. should TOUCHES be true
+// if the interior of the Areal overlaps the boundary of the Volumetric
+// like it's true for Linear/Areal
+
+// EQUALS
+template <typename Geometry1, typename Geometry2>
+struct static_mask_equals_type
+{
+ typedef geometry::de9im::static_mask<'T', '*', 'F', '*', '*', 'F', 'F', 'F', '*'> type; // wikipedia
+ //typedef geometry::de9im::static_mask<'T', 'F', 'F', 'F', 'T', 'F', 'F', 'F', 'T'> type; // OGC
+};
+
+// DISJOINT
+template <typename Geometry1, typename Geometry2>
+struct static_mask_disjoint_type
+{
+ typedef geometry::de9im::static_mask<'F', 'F', '*', 'F', 'F', '*', '*', '*', '*'> type;
+};
+
+// TOUCHES - NOT P/P
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ std::size_t Dim1 = geometry::topological_dimension<Geometry1>::value,
+ std::size_t Dim2 = geometry::topological_dimension<Geometry2>::value
+>
+struct static_mask_touches_impl
+{
+ typedef boost::mpl::vector
+ <
+ geometry::de9im::static_mask<'F', 'T', '*', '*', '*', '*', '*', '*', '*'>,
+ geometry::de9im::static_mask<'F', '*', '*', 'T', '*', '*', '*', '*', '*'>,
+ geometry::de9im::static_mask<'F', '*', '*', '*', 'T', '*', '*', '*', '*'>
+ > type;
+};
+// According to OGC, doesn't apply to P/P
+// Using the above mask the result would be always false
+template <typename Geometry1, typename Geometry2>
+struct static_mask_touches_impl<Geometry1, Geometry2, 0, 0>
+ : not_implemented<typename geometry::tag<Geometry1>::type,
+ typename geometry::tag<Geometry2>::type>
+{};
+
+template <typename Geometry1, typename Geometry2>
+struct static_mask_touches_type
+ : static_mask_touches_impl<Geometry1, Geometry2>
+{};
+
+// WITHIN
+template <typename Geometry1, typename Geometry2>
+struct static_mask_within_type
+{
+ typedef geometry::de9im::static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'> type;
+};
+
+// COVERED_BY (non OGC)
+template <typename Geometry1, typename Geometry2>
+struct static_mask_covered_by_type
+{
+ typedef boost::mpl::vector
+ <
+ geometry::de9im::static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'>,
+ geometry::de9im::static_mask<'*', 'T', 'F', '*', '*', 'F', '*', '*', '*'>,
+ geometry::de9im::static_mask<'*', '*', 'F', 'T', '*', 'F', '*', '*', '*'>,
+ geometry::de9im::static_mask<'*', '*', 'F', '*', 'T', 'F', '*', '*', '*'>
+ > type;
+};
+
+// CROSSES
+// dim(G1) < dim(G2) - P/L P/A L/A
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ std::size_t Dim1 = geometry::topological_dimension<Geometry1>::value,
+ std::size_t Dim2 = geometry::topological_dimension<Geometry2>::value,
+ bool D1LessD2 = (Dim1 < Dim2)
+>
+struct static_mask_crosses_impl
+{
+ typedef geometry::de9im::static_mask<'T', '*', 'T', '*', '*', '*', '*', '*', '*'> type;
+};
+// TODO: I'm not sure if this one below should be available!
+// dim(G1) > dim(G2) - L/P A/P A/L
+template
+<
+ typename Geometry1, typename Geometry2, std::size_t Dim1, std::size_t Dim2
+>
+struct static_mask_crosses_impl<Geometry1, Geometry2, Dim1, Dim2, false>
+{
+ typedef geometry::de9im::static_mask<'T', '*', '*', '*', '*', '*', 'T', '*', '*'> type;
+};
+// dim(G1) == dim(G2) - P/P A/A
+template
+<
+ typename Geometry1, typename Geometry2, std::size_t Dim
+>
+struct static_mask_crosses_impl<Geometry1, Geometry2, Dim, Dim, false>
+ : not_implemented
+ <
+ typename geometry::tag<Geometry1>::type,
+ typename geometry::tag<Geometry2>::type
+ >
+{};
+// dim(G1) == 1 && dim(G2) == 1 - L/L
+template <typename Geometry1, typename Geometry2>
+struct static_mask_crosses_impl<Geometry1, Geometry2, 1, 1, false>
+{
+ typedef geometry::de9im::static_mask<'0', '*', '*', '*', '*', '*', '*', '*', '*'> type;
+};
+
+template <typename Geometry1, typename Geometry2>
+struct static_mask_crosses_type
+ : static_mask_crosses_impl<Geometry1, Geometry2>
+{};
+
+// OVERLAPS
+
+// dim(G1) != dim(G2) - NOT P/P, L/L, A/A
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ std::size_t Dim1 = geometry::topological_dimension<Geometry1>::value,
+ std::size_t Dim2 = geometry::topological_dimension<Geometry2>::value
+>
+struct static_mask_overlaps_impl
+ : not_implemented
+ <
+ typename geometry::tag<Geometry1>::type,
+ typename geometry::tag<Geometry2>::type
+ >
+{};
+// dim(G1) == D && dim(G2) == D - P/P A/A
+template <typename Geometry1, typename Geometry2, std::size_t Dim>
+struct static_mask_overlaps_impl<Geometry1, Geometry2, Dim, Dim>
+{
+ typedef geometry::de9im::static_mask<'T', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
+};
+// dim(G1) == 1 && dim(G2) == 1 - L/L
+template <typename Geometry1, typename Geometry2>
+struct static_mask_overlaps_impl<Geometry1, Geometry2, 1, 1>
+{
+ typedef geometry::de9im::static_mask<'1', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
+};
+
+template <typename Geometry1, typename Geometry2>
+struct static_mask_overlaps_type
+ : static_mask_overlaps_impl<Geometry1, Geometry2>
+{};
+
+}} // namespace detail::de9im
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_DE9IM_HPP
diff --git a/boost/geometry/algorithms/detail/relate/follow_helpers.hpp b/boost/geometry/algorithms/detail/relate/follow_helpers.hpp
index 2c44b009e7..20122471e5 100644
--- a/boost/geometry/algorithms/detail/relate/follow_helpers.hpp
+++ b/boost/geometry/algorithms/detail/relate/follow_helpers.hpp
@@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_FOLLOW_HELPERS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_FOLLOW_HELPERS_HPP
+#include <boost/geometry/core/assert.hpp>
+
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/range.hpp>
//#include <boost/geometry/algorithms/detail/sub_range.hpp>
@@ -89,7 +91,7 @@ struct for_each_disjoint_geometry_if<OpId, Geometry, Tag, true>
Geometry const& geometry,
Pred & pred)
{
- BOOST_ASSERT(first != last);
+ BOOST_GEOMETRY_ASSERT(first != last);
const std::size_t count = boost::size(geometry);
boost::ignore_unused_variable_warning(count);
@@ -99,10 +101,10 @@ struct for_each_disjoint_geometry_if<OpId, Geometry, Tag, true>
std::vector<bool> detected_intersections(count, false);
for ( TurnIt it = first ; it != last ; ++it )
{
- signed_index_type multi_index = it->operations[OpId].seg_id.multi_index;
- BOOST_ASSERT(multi_index >= 0);
+ signed_size_type multi_index = it->operations[OpId].seg_id.multi_index;
+ BOOST_GEOMETRY_ASSERT(multi_index >= 0);
std::size_t const index = static_cast<std::size_t>(multi_index);
- BOOST_ASSERT(index < count);
+ BOOST_GEOMETRY_ASSERT(index < count);
detected_intersections[index] = true;
}
@@ -141,12 +143,12 @@ public:
{}
segment_identifier const& seg_id() const
{
- BOOST_ASSERT(sid_ptr);
+ BOOST_GEOMETRY_ASSERT(sid_ptr);
return *sid_ptr;
}
Point const& point() const
{
- BOOST_ASSERT(pt_ptr);
+ BOOST_GEOMETRY_ASSERT(pt_ptr);
return *pt_ptr;
}
@@ -300,15 +302,15 @@ public:
point_type const& get_exit_point() const
{
- BOOST_ASSERT(m_exit_operation != overlay::operation_none);
- BOOST_ASSERT(m_exit_turn_ptr);
+ BOOST_GEOMETRY_ASSERT(m_exit_operation != overlay::operation_none);
+ BOOST_GEOMETRY_ASSERT(m_exit_turn_ptr);
return m_exit_turn_ptr->point;
}
TurnInfo const& get_exit_turn() const
{
- BOOST_ASSERT(m_exit_operation != overlay::operation_none);
- BOOST_ASSERT(m_exit_turn_ptr);
+ BOOST_GEOMETRY_ASSERT(m_exit_operation != overlay::operation_none);
+ BOOST_GEOMETRY_ASSERT(m_exit_turn_ptr);
return *m_exit_turn_ptr;
}
diff --git a/boost/geometry/algorithms/detail/relate/implementation.hpp b/boost/geometry/algorithms/detail/relate/implementation.hpp
new file mode 100644
index 0000000000..a6f1545ed1
--- /dev/null
+++ b/boost/geometry/algorithms/detail/relate/implementation.hpp
@@ -0,0 +1,110 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// 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.
+
+// 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_RELATE_IMPLEMENTATION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_IMPLEMENTATION_HPP
+
+
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/detail/relate/interface.hpp>
+
+#include <boost/geometry/algorithms/detail/relate/point_point.hpp>
+#include <boost/geometry/algorithms/detail/relate/point_geometry.hpp>
+#include <boost/geometry/algorithms/detail/relate/linear_linear.hpp>
+#include <boost/geometry/algorithms/detail/relate/linear_areal.hpp>
+#include <boost/geometry/algorithms/detail/relate/areal_areal.hpp>
+
+
+namespace boost { namespace geometry {
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+template <typename Point1, typename Point2>
+struct relate<Point1, Point2, point_tag, point_tag, 0, 0, false>
+ : detail::relate::point_point<Point1, Point2>
+{};
+
+template <typename Point, typename MultiPoint>
+struct relate<Point, MultiPoint, point_tag, multi_point_tag, 0, 0, false>
+ : detail::relate::point_multipoint<Point, MultiPoint>
+{};
+
+template <typename MultiPoint, typename Point>
+struct relate<MultiPoint, Point, multi_point_tag, point_tag, 0, 0, false>
+ : detail::relate::multipoint_point<MultiPoint, Point>
+{};
+
+template <typename MultiPoint1, typename MultiPoint2>
+struct relate<MultiPoint1, MultiPoint2, multi_point_tag, multi_point_tag, 0, 0, false>
+ : detail::relate::multipoint_multipoint<MultiPoint1, MultiPoint2>
+{};
+
+// TODO - for now commented out because before implementing it we must consider:
+// 1. how the Box degenerated to a Point should be treated
+// 2. what should be the definition of a Box degenerated to a Point
+// 3. what fields should the matrix/mask contain for dimension > 2 and dimension > 9
+//
+//template <typename Point, typename Box, int TopDim2>
+//struct relate<Point, Box, point_tag, box_tag, 0, TopDim2, false>
+// : detail::relate::point_box<Point, Box>
+//{};
+//
+//template <typename Box, typename Point, int TopDim1>
+//struct relate<Box, Point, box_tag, point_tag, TopDim1, 0, false>
+// : detail::relate::box_point<Box, Point>
+//{};
+
+
+template <typename Point, typename Geometry, typename Tag2, int TopDim2>
+struct relate<Point, Geometry, point_tag, Tag2, 0, TopDim2, true>
+ : detail::relate::point_geometry<Point, Geometry>
+{};
+
+template <typename Geometry, typename Point, typename Tag1, int TopDim1>
+struct relate<Geometry, Point, Tag1, point_tag, TopDim1, 0, true>
+ : detail::relate::geometry_point<Geometry, Point>
+{};
+
+
+template <typename Linear1, typename Linear2, typename Tag1, typename Tag2>
+struct relate<Linear1, Linear2, Tag1, Tag2, 1, 1, true>
+ : detail::relate::linear_linear<Linear1, Linear2>
+{};
+
+
+template <typename Linear, typename Areal, typename Tag1, typename Tag2>
+struct relate<Linear, Areal, Tag1, Tag2, 1, 2, true>
+ : detail::relate::linear_areal<Linear, Areal>
+{};
+
+template <typename Areal, typename Linear, typename Tag1, typename Tag2>
+struct relate<Areal, Linear, Tag1, Tag2, 2, 1, true>
+ : detail::relate::areal_linear<Areal, Linear>
+{};
+
+
+template <typename Areal1, typename Areal2, typename Tag1, typename Tag2>
+struct relate<Areal1, Areal2, Tag1, Tag2, 2, 2, true>
+ : detail::relate::areal_areal<Areal1, Areal2>
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_IMPLEMENTATION_HPP
diff --git a/boost/geometry/algorithms/detail/relate/interface.hpp b/boost/geometry/algorithms/detail/relate/interface.hpp
new file mode 100644
index 0000000000..e2c067b68d
--- /dev/null
+++ b/boost/geometry/algorithms/detail/relate/interface.hpp
@@ -0,0 +1,348 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// 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.
+
+// 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_RELATE_INTERFACE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_INTERFACE_HPP
+
+
+#include <boost/type_traits/is_same.hpp>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/core/topological_dimension.hpp>
+
+#include <boost/geometry/algorithms/detail/relate/de9im.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/strategies/default_strategy.hpp>
+
+
+namespace boost { namespace geometry {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace relate {
+
+// Those are used only to allow dispatch::relate to produce compile-time error
+
+template <typename Geometry,
+ typename Tag = typename geometry::tag<Geometry>::type>
+struct is_supported_by_generic
+{
+ static const bool value
+ = boost::is_same<Tag, linestring_tag>::value
+ || boost::is_same<Tag, multi_linestring_tag>::value
+ || boost::is_same<Tag, ring_tag>::value
+ || boost::is_same<Tag, polygon_tag>::value
+ || boost::is_same<Tag, multi_polygon_tag>::value;
+};
+
+template <typename Geometry1,
+ typename Geometry2,
+ typename Tag1 = typename geometry::tag<Geometry1>::type,
+ typename Tag2 = typename geometry::tag<Geometry2>::type>
+struct is_generic
+{
+ static const bool value = is_supported_by_generic<Geometry1>::value
+ && is_supported_by_generic<Geometry2>::value;
+};
+
+
+template <typename Point, typename Geometry, typename Tag>
+struct is_generic<Point, Geometry, point_tag, Tag>
+{
+ static const bool value = is_supported_by_generic<Geometry>::value;
+};
+
+template <typename Geometry, typename Point, typename Tag>
+struct is_generic<Geometry, Point, Tag, point_tag>
+{
+ static const bool value = is_supported_by_generic<Geometry>::value;
+};
+
+template <typename Point1, typename Point2>
+struct is_generic<Point1, Point2, point_tag, point_tag>
+{
+ static const bool value = false;
+};
+
+
+}} // namespace detail::relate
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+
+template <typename Geometry1,
+ typename Geometry2,
+ typename Tag1 = typename geometry::tag<Geometry1>::type,
+ typename Tag2 = typename geometry::tag<Geometry2>::type,
+ int TopDim1 = geometry::topological_dimension<Geometry1>::value,
+ int TopDim2 = geometry::topological_dimension<Geometry2>::value,
+ bool IsGeneric = detail::relate::is_generic<Geometry1, Geometry2>::value
+>
+struct relate : not_implemented<Tag1, Tag2>
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace relate {
+
+template <typename Geometry1, typename Geometry2>
+struct interruption_enabled
+{
+ static const bool value =
+ dispatch::relate<Geometry1, Geometry2>::interruption_enabled;
+};
+
+template <typename Geometry1,
+ typename Geometry2,
+ typename Result,
+ bool IsSequence = boost::mpl::is_sequence<Result>::value>
+struct result_handler_type
+ : not_implemented<Result>
+{};
+
+template <typename Geometry1, typename Geometry2>
+struct result_handler_type<Geometry1, Geometry2, geometry::de9im::mask, false>
+{
+ typedef mask_handler
+ <
+ geometry::de9im::mask,
+ interruption_enabled
+ <
+ Geometry1,
+ Geometry2
+ >::value
+ > type;
+};
+
+template <typename Geometry1, typename Geometry2, typename Head, typename Tail>
+struct result_handler_type<Geometry1, Geometry2, boost::tuples::cons<Head, Tail>, false>
+{
+ typedef mask_handler
+ <
+ boost::tuples::cons<Head, Tail>,
+ interruption_enabled
+ <
+ Geometry1,
+ Geometry2
+ >::value
+ > type;
+};
+
+template <typename Geometry1, typename Geometry2,
+ char II, char IB, char IE,
+ char BI, char BB, char BE,
+ char EI, char EB, char EE>
+struct result_handler_type
+ <
+ Geometry1,
+ Geometry2,
+ geometry::de9im::static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>,
+ false
+ >
+{
+ typedef static_mask_handler
+ <
+ geometry::de9im::static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>,
+ interruption_enabled
+ <
+ Geometry1,
+ Geometry2
+ >::value
+ > type;
+};
+
+template <typename Geometry1, typename Geometry2, typename StaticSequence>
+struct result_handler_type<Geometry1, Geometry2, StaticSequence, true>
+{
+ typedef static_mask_handler
+ <
+ StaticSequence,
+ interruption_enabled
+ <
+ Geometry1,
+ Geometry2
+ >::value
+ > type;
+};
+
+}} // namespace detail::relate
+#endif // DOXYGEN_NO_DETAIL
+
+namespace resolve_variant {
+
+template <typename Geometry1, typename Geometry2>
+struct relate
+{
+ template <typename Mask>
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Mask const& mask)
+ {
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+ assert_dimension_equal<Geometry1, Geometry2>();
+
+ typename detail::relate::result_handler_type
+ <
+ Geometry1,
+ Geometry2,
+ Mask
+ >::type handler(mask);
+
+ dispatch::relate
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, handler);
+
+ return handler.result();
+ }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
+struct relate<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
+{
+ template <typename Mask>
+ struct visitor : boost::static_visitor<bool>
+ {
+ Geometry2 const& m_geometry2;
+ Mask const& m_mask;
+
+ visitor(Geometry2 const& geometry2, Mask const& mask)
+ : m_geometry2(geometry2), m_mask(mask) {}
+
+ template <typename Geometry1>
+ bool operator()(Geometry1 const& geometry1) const
+ {
+ return relate<Geometry1, Geometry2>
+ ::apply(geometry1, m_geometry2, m_mask);
+ }
+ };
+
+ template <typename Mask>
+ static inline bool
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
+ Geometry2 const& geometry2,
+ Mask const& mask)
+ {
+ return boost::apply_visitor(visitor<Mask>(geometry2, mask), geometry1);
+ }
+};
+
+template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct relate<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ template <typename Mask>
+ struct visitor : boost::static_visitor<bool>
+ {
+ Geometry1 const& m_geometry1;
+ Mask const& m_mask;
+
+ visitor(Geometry1 const& geometry1, Mask const& mask)
+ : m_geometry1(geometry1), m_mask(mask) {}
+
+ template <typename Geometry2>
+ bool operator()(Geometry2 const& geometry2) const
+ {
+ return relate<Geometry1, Geometry2>
+ ::apply(m_geometry1, geometry2, m_mask);
+ }
+ };
+
+ template <typename Mask>
+ static inline bool
+ apply(Geometry1 const& geometry1,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
+ Mask const& mask)
+ {
+ return boost::apply_visitor(visitor<Mask>(geometry1, mask), geometry2);
+ }
+};
+
+template <
+ BOOST_VARIANT_ENUM_PARAMS(typename T1),
+ BOOST_VARIANT_ENUM_PARAMS(typename T2)
+>
+struct relate<
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
+>
+{
+ template <typename Mask>
+ struct visitor : boost::static_visitor<bool>
+ {
+ Mask const& m_mask;
+
+ visitor(Mask const& mask)
+ : m_mask(mask) {}
+
+ template <typename Geometry1, typename Geometry2>
+ bool operator()(Geometry1 const& geometry1,
+ Geometry2 const& geometry2) const
+ {
+ return relate<Geometry1, Geometry2>
+ ::apply(geometry1, geometry2, m_mask);
+ }
+ };
+
+ template <typename Mask>
+ 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)
+ {
+ return boost::apply_visitor(visitor<Mask>(mask), geometry1, geometry2);
+ }
+};
+
+} // namespace resolve_variant
+
+/*!
+\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.
+\return true if the relation is compatible with the mask, false otherwise.
+
+\qbk{[include reference/algorithms/relate.qbk]}
+ */
+template <typename Geometry1, typename Geometry2, typename Mask>
+inline bool relate(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Mask const& mask)
+{
+ return resolve_variant::relate
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, mask);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_INTERFACE_HPP
diff --git a/boost/geometry/algorithms/detail/relate/less.hpp b/boost/geometry/algorithms/detail/relate/less.hpp
index 3f11d4e87d..462fcc35f1 100644
--- a/boost/geometry/algorithms/detail/relate/less.hpp
+++ b/boost/geometry/algorithms/detail/relate/less.hpp
@@ -14,6 +14,10 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LESS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LESS_HPP
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/util/math.hpp>
+
namespace boost { namespace geometry
{
diff --git a/boost/geometry/algorithms/detail/relate/linear_areal.hpp b/boost/geometry/algorithms/detail/relate/linear_areal.hpp
index 7d85a1d9a1..e7cbf6f6c2 100644
--- a/boost/geometry/algorithms/detail/relate/linear_areal.hpp
+++ b/boost/geometry/algorithms/detail/relate/linear_areal.hpp
@@ -15,7 +15,9 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LINEAR_AREAL_HPP
#include <boost/core/ignore_unused.hpp>
+#include <boost/range/size.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/topological_dimension.hpp>
#include <boost/geometry/util/condition.hpp>
@@ -97,7 +99,7 @@ public:
}
int const pig = detail::within::point_in_geometry(range::front(linestring), m_geometry2);
- //BOOST_ASSERT_MSG(pig != 0, "There should be no IPs");
+ //BOOST_GEOMETRY_ASSERT_MSG(pig != 0, "There should be no IPs");
if ( pig > 0 )
{
@@ -323,8 +325,8 @@ struct linear_areal
// if there was some previous ring
if ( prev_seg_id_ptr != NULL )
{
- signed_index_type const next_ring_index = prev_seg_id_ptr->ring_index + 1;
- BOOST_ASSERT(next_ring_index >= 0);
+ signed_size_type const next_ring_index = prev_seg_id_ptr->ring_index + 1;
+ BOOST_GEOMETRY_ASSERT(next_ring_index >= 0);
// if one of the last rings of previous single geometry was ommited
if ( static_cast<std::size_t>(next_ring_index)
@@ -394,8 +396,8 @@ struct linear_areal
// if there was some previous ring
if ( prev_seg_id_ptr != NULL )
{
- signed_index_type const next_ring_index = prev_seg_id_ptr->ring_index + 1;
- BOOST_ASSERT(next_ring_index >= 0);
+ signed_size_type const next_ring_index = prev_seg_id_ptr->ring_index + 1;
+ BOOST_GEOMETRY_ASSERT(next_ring_index >= 0);
// if one of the last rings of previous single geometry was ommited
if ( static_cast<std::size_t>(next_ring_index)
@@ -456,7 +458,7 @@ struct linear_areal
template <typename TurnIt>
void operator()(TurnIt first, TurnIt last) const
{
- BOOST_ASSERT(first != last);
+ BOOST_GEOMETRY_ASSERT(first != last);
static OpToPriority op_to_priority;
// find the operation with the least priority
int least_priority = op_to_priority(first->operations[0]);
@@ -736,6 +738,8 @@ struct linear_areal
// handle the interior overlap
if ( m_interior_detected )
{
+ BOOST_GEOMETRY_ASSERT_MSG(m_previous_turn_ptr, "non-NULL ptr expected");
+
// real interior overlap
if ( ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it) )
{
@@ -745,21 +749,16 @@ struct linear_areal
// new range detected - reset previous state and check the boundary
if ( first_in_range )
{
- // actually it should be != NULL if m_interior_detected
- // so an assert could be checked here
- if ( m_previous_turn_ptr )
- {
- segment_identifier const& prev_seg_id = m_previous_turn_ptr->operations[op_id].seg_id;
+ segment_identifier const& prev_seg_id = m_previous_turn_ptr->operations[op_id].seg_id;
- bool const prev_back_b = is_endpoint_on_boundary<boundary_back>(
- range::back(sub_range(geometry, prev_seg_id)),
- boundary_checker);
+ bool const prev_back_b = is_endpoint_on_boundary<boundary_back>(
+ range::back(sub_range(geometry, prev_seg_id)),
+ boundary_checker);
- // if there is a boundary on the last point
- if ( prev_back_b )
- {
- update<boundary, interior, '0', TransposeResult>(res);
- }
+ // if there is a boundary on the last point
+ if ( prev_back_b )
+ {
+ update<boundary, interior, '0', TransposeResult>(res);
}
// The exit_watcher is reset below
@@ -1002,7 +1001,7 @@ struct linear_areal
/*&& ( op == overlay::operation_blocked
|| op == overlay::operation_union )*/ ) // if we're here it's u or x
{
- BOOST_ASSERT(m_first_from_unknown);
+ BOOST_GEOMETRY_ASSERT(m_first_from_unknown);
m_first_from_unknown_boundary_detected = true;
}
else
@@ -1043,7 +1042,7 @@ struct linear_areal
BoundaryChecker const& boundary_checker)
{
boost::ignore_unused(first, last);
- //BOOST_ASSERT( first != last );
+ //BOOST_GEOMETRY_ASSERT( first != last );
// For MultiPolygon many x/u operations may be generated as a first IP
// if for all turns x/u was generated and any of the Polygons doesn't contain the LineString
@@ -1071,8 +1070,8 @@ struct linear_areal
// for sure
update<interior, exterior, '1', TransposeResult>(res);
- BOOST_ASSERT(first != last);
- BOOST_ASSERT(m_previous_turn_ptr);
+ BOOST_GEOMETRY_ASSERT(first != last);
+ BOOST_GEOMETRY_ASSERT(m_previous_turn_ptr);
segment_identifier const& prev_seg_id = m_previous_turn_ptr->operations[op_id].seg_id;
@@ -1094,8 +1093,8 @@ struct linear_areal
update<interior, interior, '1', TransposeResult>(res);
m_interior_detected = false;
- BOOST_ASSERT(first != last);
- BOOST_ASSERT(m_previous_turn_ptr);
+ BOOST_GEOMETRY_ASSERT(first != last);
+ BOOST_GEOMETRY_ASSERT(m_previous_turn_ptr);
segment_identifier const& prev_seg_id = m_previous_turn_ptr->operations[op_id].seg_id;
@@ -1112,7 +1111,7 @@ struct linear_areal
// This condition may be false if the Linestring is lying on the Polygon's collinear spike
// if Polygon's spikes are not handled in get_turns() or relate() (they currently aren't)
- //BOOST_ASSERT_MSG(m_previous_operation != overlay::operation_continue,
+ //BOOST_GEOMETRY_ASSERT_MSG(m_previous_operation != overlay::operation_continue,
// "Unexpected operation! Probably the error in get_turns(L,A) or relate(L,A)");
// Currently one c/c turn is generated for the exit
// when a Linestring is going out on a collinear spike
@@ -1160,16 +1159,16 @@ struct linear_areal
typedef typename boost::range_iterator<range2_type>::type range2_iterator;
range2_type range2(sub_range(geometry2, turn.operations[other_op_id].seg_id));
- BOOST_ASSERT(boost::size(range1));
+ BOOST_GEOMETRY_ASSERT(boost::size(range1));
std::size_t const s2 = boost::size(range2);
- BOOST_ASSERT(s2 > 2);
+ BOOST_GEOMETRY_ASSERT(s2 > 2);
std::size_t const seg_count2 = s2 - 1;
std::size_t const p_seg_ij = static_cast<std::size_t>(turn.operations[op_id].seg_id.segment_index);
std::size_t const q_seg_ij = static_cast<std::size_t>(turn.operations[other_op_id].seg_id.segment_index);
- BOOST_ASSERT(p_seg_ij + 1 < boost::size(range1));
- BOOST_ASSERT(q_seg_ij + 1 < s2);
+ BOOST_GEOMETRY_ASSERT(p_seg_ij + 1 < boost::size(range1));
+ BOOST_GEOMETRY_ASSERT(q_seg_ij + 1 < s2);
point1_type const& pi = range::at(range1, p_seg_ij);
point2_type const& qi = range::at(range2, q_seg_ij);
@@ -1178,8 +1177,8 @@ struct linear_areal
geometry::convert(qi, qi_conv);
bool const is_ip_qj = equals::equals_point_point(turn.point, qj);
// TODO: test this!
-// BOOST_ASSERT(!equals::equals_point_point(turn.point, pi));
-// BOOST_ASSERT(!equals::equals_point_point(turn.point, qi));
+// BOOST_GEOMETRY_ASSERT(!equals::equals_point_point(turn.point, pi));
+// BOOST_GEOMETRY_ASSERT(!equals::equals_point_point(turn.point, qi));
point1_type new_pj;
geometry::convert(turn.point, new_pj);
@@ -1211,7 +1210,7 @@ struct linear_areal
template <typename It>
static inline It find_next_non_duplicated(It first, It current, It last)
{
- BOOST_ASSERT( current != last );
+ BOOST_GEOMETRY_ASSERT( current != last );
It it = current;
@@ -1332,8 +1331,8 @@ struct linear_areal
if ( first == last )
return last;
- signed_index_type const multi_index = first->operations[1].seg_id.multi_index;
- signed_index_type const ring_index = first->operations[1].seg_id.ring_index;
+ signed_size_type const multi_index = first->operations[1].seg_id.multi_index;
+ signed_size_type const ring_index = first->operations[1].seg_id.ring_index;
fun(*first);
++first;
@@ -1379,7 +1378,7 @@ struct linear_areal
if ( is_union_detected )
{
- BOOST_ASSERT(m_previous_turn_ptr != NULL);
+ BOOST_GEOMETRY_ASSERT(m_previous_turn_ptr != NULL);
if ( !detail::equals::equals_point_point(it->point, m_previous_turn_ptr->point) )
{
// break
diff --git a/boost/geometry/algorithms/detail/relate/linear_linear.hpp b/boost/geometry/algorithms/detail/relate/linear_linear.hpp
index 20a22c3018..7a3f373e03 100644
--- a/boost/geometry/algorithms/detail/relate/linear_linear.hpp
+++ b/boost/geometry/algorithms/detail/relate/linear_linear.hpp
@@ -14,7 +14,12 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LINEAR_LINEAR_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LINEAR_LINEAR_HPP
+#include <algorithm>
+
#include <boost/core/ignore_unused.hpp>
+#include <boost/range/size.hpp>
+
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/range.hpp>
@@ -23,6 +28,7 @@
#include <boost/geometry/algorithms/detail/single_geometry.hpp>
#include <boost/geometry/algorithms/detail/relate/point_geometry.hpp>
+#include <boost/geometry/algorithms/detail/relate/result.hpp>
#include <boost/geometry/algorithms/detail/relate/turns.hpp>
#include <boost/geometry/algorithms/detail/relate/boundary_checker.hpp>
#include <boost/geometry/algorithms/detail/relate/follow_helpers.hpp>
@@ -576,7 +582,7 @@ struct linear_linear
OtherBoundaryChecker const& /*other_boundary_checker*/)
{
boost::ignore_unused(first, last);
- //BOOST_ASSERT( first != last );
+ //BOOST_GEOMETRY_ASSERT( first != last );
// here, the possible exit is the real one
// we know that we entered and now we exit
@@ -586,7 +592,7 @@ struct linear_linear
{
update<interior, exterior, '1', transpose_result>(res);
- BOOST_ASSERT(first != last);
+ BOOST_GEOMETRY_ASSERT(first != last);
const TurnInfo * turn_ptr = NULL;
if ( m_degenerated_turn_ptr )
@@ -598,7 +604,7 @@ struct linear_linear
{
segment_identifier const& prev_seg_id = turn_ptr->operations[op_id].seg_id;
- //BOOST_ASSERT(!boost::empty(sub_range(geometry, prev_seg_id)));
+ //BOOST_GEOMETRY_ASSERT(!boost::empty(sub_range(geometry, prev_seg_id)));
bool const prev_back_b = is_endpoint_on_boundary<boundary_back>(
range::back(sub_range(geometry, prev_seg_id)),
boundary_checker);
@@ -688,7 +694,7 @@ struct linear_linear
if ( first_in_range )
{
- //BOOST_ASSERT(!boost::empty(ls1_ref));
+ //BOOST_GEOMETRY_ASSERT(!boost::empty(ls1_ref));
bool const front_b = is_endpoint_on_boundary<boundary_front>(
range::front(ls1_ref), boundary_checker);
if ( front_b )
@@ -717,7 +723,7 @@ struct linear_linear
if ( first_in_range )
{
- //BOOST_ASSERT(!boost::empty(ls1_ref));
+ //BOOST_GEOMETRY_ASSERT(!boost::empty(ls1_ref));
bool const front_b = is_endpoint_on_boundary<boundary_front>(
range::front(ls1_ref), boundary_checker);
if ( front_b )
diff --git a/boost/geometry/algorithms/detail/relate/point_geometry.hpp b/boost/geometry/algorithms/detail/relate/point_geometry.hpp
index 62ab100919..be08016a16 100644
--- a/boost/geometry/algorithms/detail/relate/point_geometry.hpp
+++ b/boost/geometry/algorithms/detail/relate/point_geometry.hpp
@@ -18,6 +18,7 @@
//#include <boost/geometry/algorithms/within.hpp>
//#include <boost/geometry/algorithms/covered_by.hpp>
+#include <boost/geometry/algorithms/detail/relate/result.hpp>
#include <boost/geometry/algorithms/detail/relate/topology_check.hpp>
#include <boost/geometry/util/condition.hpp>
@@ -43,18 +44,18 @@ struct point_geometry
if ( pig > 0 ) // within
{
- set<interior, interior, '0', Transpose>(result);
+ relate::set<interior, interior, '0', Transpose>(result);
}
else if ( pig == 0 )
{
- set<interior, boundary, '0', Transpose>(result);
+ relate::set<interior, boundary, '0', Transpose>(result);
}
else // pig < 0 - not within
{
- set<interior, exterior, '0', Transpose>(result);
+ relate::set<interior, exterior, '0', Transpose>(result);
}
- set<exterior, exterior, result_dimension<Point>::value, Transpose>(result);
+ relate::set<exterior, exterior, result_dimension<Point>::value, Transpose>(result);
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
@@ -69,9 +70,9 @@ struct point_geometry
typedef detail::relate::topology_check<Geometry> tc_t;
//tc_t tc(geometry, point);
//if ( tc.has_interior )
- set<exterior, interior, tc_t::interior, Transpose>(result);
+ relate::set<exterior, interior, tc_t::interior, Transpose>(result);
//if ( tc.has_boundary )
- set<exterior, boundary, tc_t::boundary, Transpose>(result);
+ relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
}
else
{
@@ -79,9 +80,9 @@ struct point_geometry
typedef detail::relate::topology_check<Geometry> tc_t;
tc_t tc(geometry);
if ( tc.has_interior )
- set<exterior, interior, tc_t::interior, Transpose>(result);
+ relate::set<exterior, interior, tc_t::interior, Transpose>(result);
if ( tc.has_boundary )
- set<exterior, boundary, tc_t::boundary, Transpose>(result);
+ relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
}
}
};
diff --git a/boost/geometry/algorithms/detail/relate/point_point.hpp b/boost/geometry/algorithms/detail/relate/point_point.hpp
index e623868b92..e55be08225 100644
--- a/boost/geometry/algorithms/detail/relate/point_point.hpp
+++ b/boost/geometry/algorithms/detail/relate/point_point.hpp
@@ -17,9 +17,12 @@
#include <algorithm>
#include <vector>
+#include <boost/range/empty.hpp>
+
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
#include <boost/geometry/algorithms/detail/relate/less.hpp>
+#include <boost/geometry/algorithms/detail/relate/result.hpp>
namespace boost { namespace geometry
{
@@ -38,15 +41,15 @@ struct point_point
bool equal = detail::equals::equals_point_point(point1, point2);
if ( equal )
{
- set<interior, interior, '0'>(result);
+ relate::set<interior, interior, '0'>(result);
}
else
{
- set<interior, exterior, '0'>(result);
- set<exterior, interior, '0'>(result);
+ relate::set<interior, exterior, '0'>(result);
+ relate::set<exterior, interior, '0'>(result);
}
- set<exterior, exterior, result_dimension<Point1>::value>(result);
+ relate::set<exterior, exterior, result_dimension<Point1>::value>(result);
}
};
@@ -89,7 +92,7 @@ struct point_multipoint
if ( boost::empty(multi_point) )
{
// TODO: throw on empty input?
- set<interior, exterior, '0', Transpose>(result);
+ relate::set<interior, exterior, '0', Transpose>(result);
return;
}
@@ -97,20 +100,20 @@ struct point_multipoint
if ( rel.first ) // some point of MP is equal to P
{
- set<interior, interior, '0', Transpose>(result);
+ relate::set<interior, interior, '0', Transpose>(result);
if ( rel.second ) // a point of MP was found outside P
{
- set<exterior, interior, '0', Transpose>(result);
+ relate::set<exterior, interior, '0', Transpose>(result);
}
}
else
{
- set<interior, exterior, '0', Transpose>(result);
- set<exterior, interior, '0', Transpose>(result);
+ relate::set<interior, exterior, '0', Transpose>(result);
+ relate::set<exterior, interior, '0', Transpose>(result);
}
- set<exterior, exterior, result_dimension<Point>::value, Transpose>(result);
+ relate::set<exterior, exterior, result_dimension<Point>::value, Transpose>(result);
}
};
@@ -144,12 +147,12 @@ struct multipoint_multipoint
}
else if ( empty1 )
{
- set<exterior, interior, '0'>(result);
+ relate::set<exterior, interior, '0'>(result);
return;
}
else if ( empty2 )
{
- set<interior, exterior, '0'>(result);
+ relate::set<interior, exterior, '0'>(result);
return;
}
}
@@ -165,7 +168,7 @@ struct multipoint_multipoint
// NlogN + MlogN
bool all_handled = search<false>(multi_point1, multi_point2, result);
- if ( all_handled || result.interrupt )
+ if ( BOOST_GEOMETRY_CONDITION(all_handled || result.interrupt) )
return;
// MlogM + NlogM
@@ -212,23 +215,23 @@ struct multipoint_multipoint
// TODO: if I/I is set for one MPt, this won't be changed when the other one in analysed
// so if e.g. only I/I must be analysed we musn't check the other MPt
- set<interior, interior, '0', Transpose>(result);
+ relate::set<interior, interior, '0', Transpose>(result);
if ( found_outside ) // some point of MP2 was found outside of MP1
{
- set<exterior, interior, '0', Transpose>(result);
+ relate::set<exterior, interior, '0', Transpose>(result);
}
}
else
{
- set<interior, exterior, '0', Transpose>(result);
- set<exterior, interior, '0', Transpose>(result);
+ relate::set<interior, exterior, '0', Transpose>(result);
+ relate::set<exterior, interior, '0', Transpose>(result);
// if no point is intersecting the other MPt then we musn't analyse the reversed case
all_handled = true;
}
- set<exterior, exterior, result_dimension<point_type>::value, Transpose>(result);
+ relate::set<exterior, exterior, result_dimension<point_type>::value, Transpose>(result);
return all_handled;
}
diff --git a/boost/geometry/algorithms/detail/relate/relate.hpp b/boost/geometry/algorithms/detail/relate/relate.hpp
deleted file mode 100644
index 946653452a..0000000000
--- a/boost/geometry/algorithms/detail/relate/relate.hpp
+++ /dev/null
@@ -1,339 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// 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.
-
-// 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_RELATE_HPP
-#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RELATE_HPP
-
-#include <cstddef>
-
-#include <boost/concept_check.hpp>
-#include <boost/range.hpp>
-
-#include <boost/mpl/if.hpp>
-#include <boost/mpl/or.hpp>
-#include <boost/type_traits/is_base_of.hpp>
-
-#include <boost/geometry/algorithms/make.hpp>
-#include <boost/geometry/algorithms/not_implemented.hpp>
-
-#include <boost/geometry/core/access.hpp>
-#include <boost/geometry/core/closure.hpp>
-#include <boost/geometry/core/cs.hpp>
-#include <boost/geometry/core/exterior_ring.hpp>
-#include <boost/geometry/core/interior_rings.hpp>
-#include <boost/geometry/core/point_order.hpp>
-#include <boost/geometry/core/ring_type.hpp>
-#include <boost/geometry/core/interior_rings.hpp>
-#include <boost/geometry/core/tags.hpp>
-
-#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/util/math.hpp>
-#include <boost/geometry/util/order_as_direction.hpp>
-#include <boost/geometry/views/closeable_view.hpp>
-#include <boost/geometry/views/reversible_view.hpp>
-
-#include <boost/geometry/algorithms/detail/relate/result.hpp>
-
-#include <boost/geometry/algorithms/detail/relate/point_point.hpp>
-#include <boost/geometry/algorithms/detail/relate/point_geometry.hpp>
-#include <boost/geometry/algorithms/detail/relate/linear_linear.hpp>
-#include <boost/geometry/algorithms/detail/relate/linear_areal.hpp>
-#include <boost/geometry/algorithms/detail/relate/areal_areal.hpp>
-
-namespace boost { namespace geometry
-{
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace relate {
-
-// Those are used only to allow dispatch::relate to produce compile-time error
-
-template <typename Geometry,
- typename Tag = typename geometry::tag<Geometry>::type>
-struct is_supported_by_generic
-{
- static const bool value
- = boost::is_same<Tag, linestring_tag>::value
- || boost::is_same<Tag, multi_linestring_tag>::value
- || boost::is_same<Tag, ring_tag>::value
- || boost::is_same<Tag, polygon_tag>::value
- || boost::is_same<Tag, multi_polygon_tag>::value;
-};
-
-template <typename Geometry1,
- typename Geometry2,
- typename Tag1 = typename geometry::tag<Geometry1>::type,
- typename Tag2 = typename geometry::tag<Geometry2>::type>
-struct is_generic
-{
- static const bool value = is_supported_by_generic<Geometry1>::value
- && is_supported_by_generic<Geometry2>::value;
-};
-
-
-template <typename Point, typename Geometry, typename Tag>
-struct is_generic<Point, Geometry, point_tag, Tag>
-{
- static const bool value = is_supported_by_generic<Geometry>::value;
-};
-
-template <typename Geometry, typename Point, typename Tag>
-struct is_generic<Geometry, Point, Tag, point_tag>
-{
- static const bool value = is_supported_by_generic<Geometry>::value;
-};
-
-template <typename Point1, typename Point2>
-struct is_generic<Point1, Point2, point_tag, point_tag>
-{
- static const bool value = false;
-};
-
-
-}} // namespace detail::relate
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace detail_dispatch { namespace relate {
-
-
-template <typename Geometry1,
- typename Geometry2,
- typename Tag1 = typename geometry::tag<Geometry1>::type,
- typename Tag2 = typename geometry::tag<Geometry2>::type,
- int TopDim1 = geometry::topological_dimension<Geometry1>::value,
- int TopDim2 = geometry::topological_dimension<Geometry2>::value,
- bool IsGeneric = detail::relate::is_generic<Geometry1, Geometry2>::value
->
-struct relate : not_implemented<Tag1, Tag2>
-{};
-
-
-template <typename Point1, typename Point2>
-struct relate<Point1, Point2, point_tag, point_tag, 0, 0, false>
- : detail::relate::point_point<Point1, Point2>
-{};
-
-template <typename Point, typename MultiPoint>
-struct relate<Point, MultiPoint, point_tag, multi_point_tag, 0, 0, false>
- : detail::relate::point_multipoint<Point, MultiPoint>
-{};
-
-template <typename MultiPoint, typename Point>
-struct relate<MultiPoint, Point, multi_point_tag, point_tag, 0, 0, false>
- : detail::relate::multipoint_point<MultiPoint, Point>
-{};
-
-template <typename MultiPoint1, typename MultiPoint2>
-struct relate<MultiPoint1, MultiPoint2, multi_point_tag, multi_point_tag, 0, 0, false>
- : detail::relate::multipoint_multipoint<MultiPoint1, MultiPoint2>
-{};
-
-//template <typename Point, typename Box, int TopDim2>
-//struct relate<Point, Box, point_tag, box_tag, 0, TopDim2, false>
-// : detail::relate::point_box<Point, Box>
-//{};
-//
-//template <typename Box, typename Point, int TopDim1>
-//struct relate<Box, Point, box_tag, point_tag, TopDim1, 0, false>
-// : detail::relate::box_point<Box, Point>
-//{};
-
-
-template <typename Point, typename Geometry, typename Tag2, int TopDim2>
-struct relate<Point, Geometry, point_tag, Tag2, 0, TopDim2, true>
- : detail::relate::point_geometry<Point, Geometry>
-{};
-
-template <typename Geometry, typename Point, typename Tag1, int TopDim1>
-struct relate<Geometry, Point, Tag1, point_tag, TopDim1, 0, true>
- : detail::relate::geometry_point<Geometry, Point>
-{};
-
-
-template <typename Linear1, typename Linear2, typename Tag1, typename Tag2>
-struct relate<Linear1, Linear2, Tag1, Tag2, 1, 1, true>
- : detail::relate::linear_linear<Linear1, Linear2>
-{};
-
-
-template <typename Linear, typename Areal, typename Tag1, typename Tag2>
-struct relate<Linear, Areal, Tag1, Tag2, 1, 2, true>
- : detail::relate::linear_areal<Linear, Areal>
-{};
-
-template <typename Areal, typename Linear, typename Tag1, typename Tag2>
-struct relate<Areal, Linear, Tag1, Tag2, 2, 1, true>
- : detail::relate::areal_linear<Areal, Linear>
-{};
-
-
-template <typename Areal1, typename Areal2, typename Tag1, typename Tag2>
-struct relate<Areal1, Areal2, Tag1, Tag2, 2, 2, true>
- : detail::relate::areal_areal<Areal1, Areal2>
-{};
-
-
-}} // namespace detail_dispatch::relate
-#endif // DOXYGEN_NO_DISPATCH
-
-namespace detail { namespace relate {
-
-template <typename Geometry1, typename Geometry2>
-struct interruption_enabled
-{
- static const bool value =
- detail_dispatch::relate::relate<Geometry1, Geometry2>::interruption_enabled;
-};
-
-template <typename Geometry1,
- typename Geometry2,
- typename Result,
- bool IsSequence = boost::mpl::is_sequence<Result>::value>
-struct result_handler_type
- : not_implemented<Result>
-{};
-
-template <typename Geometry1, typename Geometry2>
-struct result_handler_type<Geometry1, Geometry2, matrix9, false>
-{
- typedef matrix_handler<matrix9> type;
-};
-
-template <typename Geometry1, typename Geometry2>
-struct result_handler_type<Geometry1, Geometry2, mask9, false>
-{
- typedef mask_handler
- <
- mask9,
- interruption_enabled
- <
- Geometry1,
- Geometry2
- >::value
- > type;
-};
-
-template <typename Geometry1, typename Geometry2, typename Head, typename Tail>
-struct result_handler_type<Geometry1, Geometry2, boost::tuples::cons<Head, Tail>, false>
-{
- typedef mask_handler
- <
- boost::tuples::cons<Head, Tail>,
- interruption_enabled
- <
- Geometry1,
- Geometry2
- >::value
- > type;
-};
-
-template <typename Geometry1, typename Geometry2,
- char II, char IB, char IE,
- char BI, char BB, char BE,
- char EI, char EB, char EE>
-struct result_handler_type<Geometry1, Geometry2, static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>, false>
-{
- typedef static_mask_handler
- <
- static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>,
- interruption_enabled
- <
- Geometry1,
- Geometry2
- >::value
- > type;
-};
-
-template <typename Geometry1, typename Geometry2, typename StaticSequence>
-struct result_handler_type<Geometry1, Geometry2, StaticSequence, true>
-{
- typedef static_mask_handler
- <
- StaticSequence,
- interruption_enabled
- <
- Geometry1,
- Geometry2
- >::value
- > type;
-};
-
-template <typename MatrixOrMask, typename Geometry1, typename Geometry2>
-inline
-typename result_handler_type
- <
- Geometry1,
- Geometry2,
- MatrixOrMask
- >::type::result_type
-relate(Geometry1 const& geometry1,
- Geometry2 const& geometry2,
- MatrixOrMask const& matrix_or_mask = MatrixOrMask())
-{
- typedef typename result_handler_type
- <
- Geometry1,
- Geometry2,
- MatrixOrMask
- >::type handler_type;
-
- handler_type handler(matrix_or_mask);
- detail_dispatch::relate::relate<Geometry1, Geometry2>::apply(geometry1, geometry2, handler);
- return handler.result();
-}
-
-struct implemented_tag {};
-
-template <template <typename, typename> class StaticMaskTrait,
- typename Geometry1,
- typename Geometry2>
-struct relate_base
- : boost::mpl::if_
- <
- boost::mpl::or_
- <
- boost::is_base_of
- <
- nyi::not_implemented_tag,
- StaticMaskTrait<Geometry1, Geometry2>
- >,
- boost::is_base_of
- <
- nyi::not_implemented_tag,
- detail_dispatch::relate::relate<Geometry1, Geometry2>
- >
- >,
- not_implemented
- <
- typename geometry::tag<Geometry1>::type,
- typename geometry::tag<Geometry2>::type
- >,
- implemented_tag
- >::type
-{
- static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
- {
- typedef typename StaticMaskTrait<Geometry1, Geometry2>::type static_mask;
- return detail::relate::relate<static_mask>(g1, g2);
- }
-};
-
-}} // namespace detail::relate
-#endif // DOXYGEN_NO_DETAIL
-
-}} // namespace boost::geometry
-
-#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RELATE_HPP
diff --git a/boost/geometry/algorithms/detail/relate/relate_impl.hpp b/boost/geometry/algorithms/detail/relate/relate_impl.hpp
new file mode 100644
index 0000000000..e8e422993d
--- /dev/null
+++ b/boost/geometry/algorithms/detail/relate/relate_impl.hpp
@@ -0,0 +1,80 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// 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.
+
+// 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_RELATE_RELATE_IMPL_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RELATE_IMPL_HPP
+
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+
+#include <boost/geometry/algorithms/detail/relate/interface.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
+#include <boost/geometry/core/tag.hpp>
+
+namespace boost { namespace geometry {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace relate {
+
+struct implemented_tag {};
+
+template <template <typename, typename> class StaticMaskTrait,
+ typename Geometry1,
+ typename Geometry2>
+struct relate_impl
+ : boost::mpl::if_
+ <
+ boost::mpl::or_
+ <
+ boost::is_base_of
+ <
+ nyi::not_implemented_tag,
+ StaticMaskTrait<Geometry1, Geometry2>
+ >,
+ boost::is_base_of
+ <
+ nyi::not_implemented_tag,
+ dispatch::relate<Geometry1, Geometry2>
+ >
+ >,
+ not_implemented
+ <
+ typename geometry::tag<Geometry1>::type,
+ typename geometry::tag<Geometry2>::type
+ >,
+ implemented_tag
+ >::type
+{
+ static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
+ {
+ typename detail::relate::result_handler_type
+ <
+ Geometry1,
+ Geometry2,
+ typename StaticMaskTrait<Geometry1, Geometry2>::type
+ >::type handler;
+
+ dispatch::relate<Geometry1, Geometry2>::apply(g1, g2, handler);
+
+ return handler.result();
+ }
+};
+
+}} // namespace detail::relate
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RELATE_IMPL_HPP
diff --git a/boost/geometry/algorithms/detail/relate/result.hpp b/boost/geometry/algorithms/detail/relate/result.hpp
index e26bda67f2..b7b9264449 100644
--- a/boost/geometry/algorithms/detail/relate/result.hpp
+++ b/boost/geometry/algorithms/detail/relate/result.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// 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.
@@ -14,21 +14,24 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP
-#include <boost/tuple/tuple.hpp>
+#include <cstddef>
-#include <boost/mpl/is_sequence.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/at.hpp>
#include <boost/mpl/begin.hpp>
+#include <boost/mpl/deref.hpp>
#include <boost/mpl/end.hpp>
+#include <boost/mpl/is_sequence.hpp>
#include <boost/mpl/next.hpp>
-#include <boost/mpl/at.hpp>
-#include <boost/mpl/vector_c.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/type_traits/integral_constant.hpp>
-#include <boost/geometry/core/topological_dimension.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/exception.hpp>
#include <boost/geometry/util/condition.hpp>
-// TEMP - move this header to geometry/detail
-#include <boost/geometry/index/detail/tuples.hpp>
-
namespace boost { namespace geometry {
#ifndef DOXYGEN_NO_DETAIL
@@ -42,125 +45,110 @@ enum field { interior = 0, boundary = 1, exterior = 2 };
// but for safety reasons (STATIC_ASSERT) we should check if parameter D is valid and set() doesn't do that
// so some additional function could be added, e.g. set_dim()
-// matrix
+// --------------- MATRIX ----------------
-// TODO add height?
+// matrix
-template <std::size_t Width>
+template <std::size_t Height, std::size_t Width = Height>
class matrix
{
- BOOST_STATIC_ASSERT(Width == 2 || Width == 3);
-
public:
-
- static const std::size_t size = Width * Width;
+ typedef char value_type;
+ typedef std::size_t size_type;
+ typedef const char * const_iterator;
+ typedef const_iterator iterator;
+
+ static const std::size_t static_width = Width;
+ static const std::size_t static_height = Height;
+ static const std::size_t static_size = Width * Height;
inline matrix()
{
- ::memset(m_array, 'F', size);
+ ::memset(m_array, 'F', static_size);
}
template <field F1, field F2>
inline char get() const
{
- static const bool in_bounds = F1 * Width + F2 < size;
- return get_dispatch<F1, F2>(integral_constant<bool, in_bounds>());
+ BOOST_STATIC_ASSERT(F1 < Height && F2 < Width);
+ static const std::size_t index = F1 * Width + F2;
+ BOOST_STATIC_ASSERT(index < static_size);
+ return m_array[index];
}
template <field F1, field F2, char V>
inline void set()
{
- static const bool in_bounds = F1 * Width + F2 < size;
- set_dispatch<F1, F2, V>(integral_constant<bool, in_bounds>());
+ BOOST_STATIC_ASSERT(F1 < Height && F2 < Width);
+ static const std::size_t index = F1 * Width + F2;
+ BOOST_STATIC_ASSERT(index < static_size);
+ m_array[index] = V;
}
- template <field F1, field F2, char D>
- inline void update()
+ inline char operator[](std::size_t index) const
{
- static const bool in_bounds = F1 * Width + F2 < size;
- update_dispatch<F1, F2, D>(integral_constant<bool, in_bounds>());
+ BOOST_GEOMETRY_ASSERT(index < static_size);
+ return m_array[index];
}
-
- inline const char * data() const
+
+ inline const_iterator begin() const
{
return m_array;
}
-private:
- template <field F1, field F2>
- inline char get_dispatch(integral_constant<bool, true>) const
+ inline const_iterator end() const
{
- return m_array[F1 * Width + F2];
+ return m_array + static_size;
}
- template <field F1, field F2>
- inline char get_dispatch(integral_constant<bool, false>) const
+
+ inline static std::size_t size()
{
- return 'F';
+ return static_size;
}
-
- template <field F1, field F2, char V>
- inline void set_dispatch(integral_constant<bool, true>)
+
+ inline const char * data() const
{
- BOOST_STATIC_ASSERT(('0' <= V && V <= '9') || V == 'T' || V == 'F');
- m_array[F1 * Width + F2] = V;
+ return m_array;
}
- template <field F1, field F2, char V>
- inline void set_dispatch(integral_constant<bool, false>)
- {}
- template <field F1, field F2, char D>
- inline void update_dispatch(integral_constant<bool, true>)
+ inline std::string str() const
{
- BOOST_STATIC_ASSERT('0' <= D && D <= '9');
- char c = m_array[F1 * Width + F2];
- if ( D > c || c > '9')
- m_array[F1 * Width + F2] = D;
+ return std::string(m_array, static_size);
}
- template <field F1, field F2, char D>
- inline void update_dispatch(integral_constant<bool, false>)
- {}
- char m_array[size];
-};
-
-// TODO add EnableDimensions parameter?
-
-struct matrix9 {};
-//struct matrix4 {};
-
-// matrix_width
-
-template <typename MatrixOrMask>
-struct matrix_width
- : not_implemented<MatrixOrMask>
-{};
-
-template <>
-struct matrix_width<matrix9>
-{
- static const std::size_t value = 3;
+private:
+ char m_array[static_size];
};
// matrix_handler
template <typename Matrix>
class matrix_handler
- : private matrix<matrix_width<Matrix>::value>
{
- typedef matrix<matrix_width<Matrix>::value> base_t;
-
public:
- typedef std::string result_type;
+ typedef Matrix result_type;
static const bool interrupt = false;
+ matrix_handler()
+ {}
+
matrix_handler(Matrix const&)
{}
- result_type result() const
+ result_type const& result() const
{
- return std::string(this->data(),
- this->data() + base_t::size);
+ return m_matrix;
+ }
+
+ result_type const& matrix() const
+ {
+ return m_matrix;
+ }
+
+ result_type & matrix()
+ {
+ return m_matrix;
}
template <field F1, field F2, char D>
@@ -168,53 +156,124 @@ public:
{
BOOST_STATIC_ASSERT('0' <= D && D <= '9');
- char const c = static_cast<base_t const&>(*this).template get<F1, F2>();
+ char const c = m_matrix.template get<F1, F2>();
return D > c || c > '9';
}
- //template <field F1, field F2>
- //inline char get() const
- //{
- // return static_cast<base_t const&>(*this).template get<F1, F2>();
- //}
-
template <field F1, field F2, char V>
inline void set()
{
- static_cast<base_t&>(*this).template set<F1, F2, V>();
+ static const bool in_bounds = F1 < Matrix::static_height
+ && F2 < Matrix::static_width;
+ typedef boost::integral_constant<bool, in_bounds> in_bounds_t;
+ set_dispatch<F1, F2, V>(in_bounds_t());
}
template <field F1, field F2, char D>
inline void update()
{
- static_cast<base_t&>(*this).template update<F1, F2, D>();
+ static const bool in_bounds = F1 < Matrix::static_height
+ && F2 < Matrix::static_width;
+ typedef boost::integral_constant<bool, in_bounds> in_bounds_t;
+ update_dispatch<F1, F2, D>(in_bounds_t());
}
+
+private:
+ template <field F1, field F2, char V>
+ inline void set_dispatch(integral_constant<bool, true>)
+ {
+ static const std::size_t index = F1 * Matrix::static_width + F2;
+ BOOST_STATIC_ASSERT(index < Matrix::static_size);
+ BOOST_STATIC_ASSERT(('0' <= V && V <= '9') || V == 'T' || V == 'F');
+ m_matrix.template set<F1, F2, V>();
+ }
+ template <field F1, field F2, char V>
+ inline void set_dispatch(integral_constant<bool, false>)
+ {}
+
+ template <field F1, field F2, char D>
+ inline void update_dispatch(integral_constant<bool, true>)
+ {
+ static const std::size_t index = F1 * Matrix::static_width + F2;
+ BOOST_STATIC_ASSERT(index < Matrix::static_size);
+ BOOST_STATIC_ASSERT('0' <= D && D <= '9');
+ char const c = m_matrix.template get<F1, F2>();
+ if ( D > c || c > '9')
+ m_matrix.template set<F1, F2, D>();
+ }
+ template <field F1, field F2, char D>
+ inline void update_dispatch(integral_constant<bool, false>)
+ {}
+
+ Matrix m_matrix;
};
-// RUN-TIME MASKS
+// --------------- RUN-TIME MASK ----------------
-// mask9
+// run-time mask
-class mask9
+template <std::size_t Height, std::size_t Width = Height>
+class mask
{
public:
- static const std::size_t width = 3; // TEMP
+ static const std::size_t static_width = Width;
+ static const std::size_t static_height = Height;
+ static const std::size_t static_size = Width * Height;
+
+ inline mask(const char * s)
+ {
+ char * it = m_array;
+ char * const last = m_array + static_size;
+ for ( ; it != last && *s != '\0' ; ++it, ++s )
+ {
+ char c = *s;
+ check_char(c);
+ *it = c;
+ }
+ if ( it != last )
+ {
+ ::memset(it, '*', last - it);
+ }
+ }
- inline mask9(std::string const& de9im_mask)
+ inline mask(const char * s, std::size_t count)
{
- // TODO: throw an exception here?
- BOOST_ASSERT(de9im_mask.size() == 9);
- ::memcpy(m_mask, de9im_mask.c_str(), 9);
+ if ( count > static_size )
+ {
+ count = static_size;
+ }
+ if ( count > 0 )
+ {
+ std::for_each(s, s + count, check_char);
+ ::memcpy(m_array, s, count);
+ }
+ if ( count < static_size )
+ {
+ ::memset(m_array + count, '*', static_size - count);
+ }
}
template <field F1, field F2>
inline char get() const
{
- return m_mask[F1 * 3 + F2];
+ BOOST_STATIC_ASSERT(F1 < Height && F2 < Width);
+ static const std::size_t index = F1 * Width + F2;
+ BOOST_STATIC_ASSERT(index < static_size);
+ return m_array[index];
}
private:
- char m_mask[9];
+ static inline void check_char(char c)
+ {
+ bool const is_valid = c == '*' || c == 'T' || c == 'F'
+ || ( c >= '0' && c <= '9' );
+ if ( !is_valid )
+ {
+ throw geometry::invalid_input_exception();
+ }
+ }
+
+ char m_array[static_size];
};
// interrupt()
@@ -277,18 +336,18 @@ struct interrupt_dispatch_tuple<Masks, N, N>
}
};
-template <typename T0, typename T1, typename T2, typename T3, typename T4,
- typename T5, typename T6, typename T7, typename T8, typename T9>
-struct interrupt_dispatch<boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>, true>
-{
- typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
+//template <typename T0, typename T1, typename T2, typename T3, typename T4,
+// typename T5, typename T6, typename T7, typename T8, typename T9>
+//struct interrupt_dispatch<boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>, true>
+//{
+// typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
- template <field F1, field F2, char V>
- static inline bool apply(mask_type const& mask)
- {
- return interrupt_dispatch_tuple<mask_type>::template apply<F1, F2, V>(mask);
- }
-};
+// template <field F1, field F2, char V>
+// static inline bool apply(mask_type const& mask)
+// {
+// return interrupt_dispatch_tuple<mask_type>::template apply<F1, F2, V>(mask);
+// }
+//};
template <typename Head, typename Tail>
struct interrupt_dispatch<boost::tuples::cons<Head, Tail>, true>
@@ -363,18 +422,18 @@ struct may_update_dispatch_tuple<Masks, N, N>
}
};
-template <typename T0, typename T1, typename T2, typename T3, typename T4,
- typename T5, typename T6, typename T7, typename T8, typename T9>
-struct may_update_dispatch< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
-{
- typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
+//template <typename T0, typename T1, typename T2, typename T3, typename T4,
+// typename T5, typename T6, typename T7, typename T8, typename T9>
+//struct may_update_dispatch< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
+//{
+// typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
- template <field F1, field F2, char D, typename Matrix>
- static inline bool apply(mask_type const& mask, Matrix const& matrix)
- {
- return may_update_dispatch_tuple<mask_type>::template apply<F1, F2, D>(mask, matrix);
- }
-};
+// template <field F1, field F2, char D, typename Matrix>
+// static inline bool apply(mask_type const& mask, Matrix const& matrix)
+// {
+// return may_update_dispatch_tuple<mask_type>::template apply<F1, F2, D>(mask, matrix);
+// }
+//};
template <typename Head, typename Tail>
struct may_update_dispatch< boost::tuples::cons<Head, Tail> >
@@ -460,18 +519,18 @@ struct check_dispatch_tuple<Masks, N, N>
}
};
-template <typename T0, typename T1, typename T2, typename T3, typename T4,
- typename T5, typename T6, typename T7, typename T8, typename T9>
-struct check_dispatch< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
-{
- typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
+//template <typename T0, typename T1, typename T2, typename T3, typename T4,
+// typename T5, typename T6, typename T7, typename T8, typename T9>
+//struct check_dispatch< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
+//{
+// typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
- template <typename Matrix>
- static inline bool apply(mask_type const& mask, Matrix const& matrix)
- {
- return check_dispatch_tuple<mask_type>::apply(mask, matrix);
- }
-};
+// template <typename Matrix>
+// static inline bool apply(mask_type const& mask, Matrix const& matrix)
+// {
+// return check_dispatch_tuple<mask_type>::apply(mask, matrix);
+// }
+//};
template <typename Head, typename Tail>
struct check_dispatch< boost::tuples::cons<Head, Tail> >
@@ -493,10 +552,10 @@ inline bool check_matrix(Mask const& mask, Matrix const& matrix)
// matrix_width
-template <>
-struct matrix_width<mask9>
+template <typename MatrixOrMask>
+struct matrix_width
{
- static const std::size_t value = 3;
+ static const std::size_t value = MatrixOrMask::static_width;
};
template <typename Tuple,
@@ -526,20 +585,30 @@ struct matrix_width< boost::tuples::cons<Head, Tail> >
value = matrix_width_tuple< boost::tuples::cons<Head, Tail> >::value;
};
-// matrix_handler
+// mask_handler
template <typename Mask, bool Interrupt>
class mask_handler
- : private matrix<matrix_width<Mask>::value>
+ : private matrix_handler
+ <
+ relate::matrix<matrix_width<Mask>::value>
+ >
{
- typedef matrix<matrix_width<Mask>::value> base_t;
+ typedef matrix_handler
+ <
+ relate::matrix<matrix_width<Mask>::value>
+ > base_t;
public:
typedef bool result_type;
bool interrupt;
- inline mask_handler(Mask const& m)
+ inline mask_handler()
+ : interrupt(false)
+ {}
+
+ inline explicit mask_handler(Mask const& m)
: interrupt(false)
, m_mask(m)
{}
@@ -547,23 +616,17 @@ public:
result_type result() const
{
return !interrupt
- && check_matrix(m_mask, static_cast<base_t const&>(*this));
+ && check_matrix(m_mask, base_t::matrix());
}
template <field F1, field F2, char D>
inline bool may_update() const
{
return detail::relate::may_update<F1, F2, D>(
- m_mask, static_cast<base_t const&>(*this)
+ m_mask, base_t::matrix()
);
}
- //template <field F1, field F2>
- //inline char get() const
- //{
- // return static_cast<base_t const&>(*this).template get<F1, F2>();
- //}
-
template <field F1, field F2, char V>
inline void set()
{
@@ -594,29 +657,65 @@ private:
Mask const& m_mask;
};
-// STATIC MASKS
+// --------------- COMPILE-TIME MASK ----------------
+
+// static_check_characters
+template
+<
+ typename Seq,
+ typename First = typename boost::mpl::begin<Seq>::type,
+ typename Last = typename boost::mpl::end<Seq>::type
+>
+struct static_check_characters
+ : static_check_characters
+ <
+ Seq,
+ typename boost::mpl::next<First>::type
+ >
+{
+ typedef typename boost::mpl::deref<First>::type type;
+ static const char value = type::value;
+ static const bool is_valid = (value >= '0' && value <= '9')
+ || value == 'T' || value == 'F' || value == '*';
+ BOOST_MPL_ASSERT_MSG((is_valid),
+ INVALID_STATIC_MASK_CHARACTER,
+ (type));
+};
+
+template <typename Seq, typename Last>
+struct static_check_characters<Seq, Last, Last>
+{};
// static_mask
-template <char II, char IB, char IE,
- char BI, char BB, char BE,
- char EI, char EB, char EE>
-class static_mask
+template
+<
+ typename Seq,
+ std::size_t Height,
+ std::size_t Width = Height
+>
+struct static_mask
{
- typedef boost::mpl::vector_c
- <
- char, II, IB, IE, BI, BB, BE, EI, EB, EE
- > vector_type;
+ static const std::size_t static_width = Width;
+ static const std::size_t static_height = Height;
+ static const std::size_t static_size = Width * Height;
-public:
- template <field F1, field F2>
- struct get
+ BOOST_STATIC_ASSERT(
+ std::size_t(boost::mpl::size<Seq>::type::value) == static_size);
+
+ template <detail::relate::field F1, detail::relate::field F2>
+ struct static_get
{
- BOOST_STATIC_ASSERT(F1 * 3 + F2 < boost::mpl::size<vector_type>::value);
+ BOOST_STATIC_ASSERT(std::size_t(F1) < static_height);
+ BOOST_STATIC_ASSERT(std::size_t(F2) < static_width);
static const char value
- = boost::mpl::at_c<vector_type, F1 * 3 + F2>::type::value;
+ = boost::mpl::at_c<Seq, F1 * static_width + F2>::type::value;
};
+
+private:
+ // check static_mask characters
+ enum { mask_check = sizeof(static_check_characters<Seq>) };
};
// static_should_handle_element
@@ -624,7 +723,7 @@ public:
template <typename StaticMask, field F1, field F2, bool IsSequence>
struct static_should_handle_element_dispatch
{
- static const char mask_el = StaticMask::template get<F1, F2>::value;
+ static const char mask_el = StaticMask::template static_get<F1, F2>::value;
static const bool value = mask_el == 'F'
|| mask_el == 'T'
|| ( mask_el >= '0' && mask_el <= '9' );
@@ -691,7 +790,7 @@ struct static_interrupt_dispatch
template <typename StaticMask, char V, field F1, field F2, bool IsSequence>
struct static_interrupt_dispatch<StaticMask, V, F1, F2, true, IsSequence>
{
- static const char mask_el = StaticMask::template get<F1, F2>::value;
+ static const char mask_el = StaticMask::template static_get<F1, F2>::value;
static const bool value
= ( V >= '0' && V <= '9' ) ?
@@ -756,7 +855,7 @@ struct static_interrupt
template <typename StaticMask, char D, field F1, field F2, bool IsSequence>
struct static_may_update_dispatch
{
- static const char mask_el = StaticMask::template get<F1, F2>::value;
+ static const char mask_el = StaticMask::template static_get<F1, F2>::value;
static const int version
= mask_el == 'F' ? 0
: mask_el == 'T' ? 1
@@ -860,7 +959,7 @@ struct static_may_update
}
};
-// static_check
+// static_check_matrix
template <typename StaticMask, bool IsSequence>
struct static_check_dispatch
@@ -882,7 +981,7 @@ struct static_check_dispatch
template <field F1, field F2>
struct per_one
{
- static const char mask_el = StaticMask::template get<F1, F2>::value;
+ static const char mask_el = StaticMask::template static_get<F1, F2>::value;
static const int version
= mask_el == 'F' ? 0
: mask_el == 'T' ? 1
@@ -982,31 +1081,34 @@ struct static_check_matrix
template <typename StaticMask, bool Interrupt>
class static_mask_handler
- : private matrix<3>
+ : private matrix_handler< matrix<3> >
{
- typedef matrix<3> base_t;
+ typedef matrix_handler< relate::matrix<3> > base_type;
public:
typedef bool result_type;
bool interrupt;
- inline static_mask_handler(StaticMask const& /*dummy*/)
+ inline static_mask_handler()
+ : interrupt(false)
+ {}
+
+ inline explicit static_mask_handler(StaticMask const& /*dummy*/)
: interrupt(false)
{}
result_type result() const
{
return (!Interrupt || !interrupt)
- && static_check_matrix<StaticMask>::
- apply(static_cast<base_t const&>(*this));
+ && static_check_matrix<StaticMask>::apply(base_type::matrix());
}
template <field F1, field F2, char D>
inline bool may_update() const
{
return static_may_update<StaticMask, D, F1, F2>::
- apply(static_cast<base_t const&>(*this));
+ apply(base_type::matrix());
}
template <field F1, field F2>
@@ -1015,12 +1117,6 @@ public:
return static_should_handle_element<StaticMask, F1, F2>::value;
}
- //template <field F1, field F2>
- //inline char get() const
- //{
- // return base_t::template get<F1, F2>();
- //}
-
template <field F1, field F2, char V>
inline void set()
{
@@ -1056,7 +1152,7 @@ private:
template <field F1, field F2, char V>
inline void set_dispatch(integral_constant<int, 1>)
{
- base_t::template set<F1, F2, V>();
+ base_type::template set<F1, F2, V>();
}
// else
template <field F1, field F2, char V>
@@ -1073,7 +1169,7 @@ private:
template <field F1, field F2, char V>
inline void update_dispatch(integral_constant<int, 1>)
{
- base_t::template update<F1, F2, V>();
+ base_type::template update<F1, F2, V>();
}
// else
template <field F1, field F2, char V>
@@ -1081,165 +1177,9 @@ private:
{}
};
-// OPERATORS
-
-template <typename Mask1, typename Mask2> inline
-boost::tuples::cons<
- Mask1,
- boost::tuples::cons<Mask2, boost::tuples::null_type>
->
-operator||(Mask1 const& m1, Mask2 const& m2)
-{
- namespace bt = boost::tuples;
-
- return
- bt::cons< Mask1, bt::cons<Mask2, bt::null_type> >
- ( m1, bt::cons<Mask2, bt::null_type>(m2, bt::null_type()) );
-}
-
-template <typename Head, typename Tail, typename Mask> inline
-typename index::detail::tuples::push_back<
- boost::tuples::cons<Head, Tail>, Mask
->::type
-operator||(boost::tuples::cons<Head, Tail> const& t, Mask const& m)
-{
- namespace bt = boost::tuples;
-
- return
- index::detail::tuples::push_back<
- bt::cons<Head, Tail>, Mask
- >::apply(t, m);
-}
-
-// PREDEFINED MASKS
-
-// TODO:
-// 1. specialize for simplified masks if available
-// e.g. for TOUCHES use 1 mask for A/A
-// 2. Think about dimensions > 2 e.g. should TOUCHES be true
-// if the interior of the Areal overlaps the boundary of the Volumetric
-// like it's true for Linear/Areal
-
-// EQUALS
-template <typename Geometry1, typename Geometry2>
-struct static_mask_equals_type
-{
- typedef static_mask<'T', '*', 'F', '*', '*', 'F', 'F', 'F', '*'> type; // wikipedia
- //typedef static_mask<'T', 'F', 'F', 'F', 'T', 'F', 'F', 'F', 'T'> type; // OGC
-};
-
-// DISJOINT
-typedef static_mask<'F', 'F', '*', 'F', 'F', '*', '*', '*', '*'> static_mask_disjoint;
+// --------------- UTIL FUNCTIONS ----------------
-// TOUCHES - NOT P/P
-template <typename Geometry1,
- typename Geometry2,
- std::size_t Dim1 = topological_dimension<Geometry1>::value,
- std::size_t Dim2 = topological_dimension<Geometry2>::value>
-struct static_mask_touches_impl
-{
- typedef boost::mpl::vector<
- static_mask<'F', 'T', '*', '*', '*', '*', '*', '*', '*'>,
- static_mask<'F', '*', '*', 'T', '*', '*', '*', '*', '*'>,
- static_mask<'F', '*', '*', '*', 'T', '*', '*', '*', '*'>
- > type;
-};
-// According to OGC, doesn't apply to P/P
-// Using the above mask the result would be always false
-template <typename Geometry1, typename Geometry2>
-struct static_mask_touches_impl<Geometry1, Geometry2, 0, 0>
- : not_implemented<typename geometry::tag<Geometry1>::type,
- typename geometry::tag<Geometry2>::type>
-{};
-
-template <typename Geometry1, typename Geometry2>
-struct static_mask_touches_type
- : static_mask_touches_impl<Geometry1, Geometry2>
-{};
-
-// WITHIN
-typedef static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'> static_mask_within;
-
-// COVERED_BY (non OGC)
-typedef boost::mpl::vector<
- static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'>,
- static_mask<'*', 'T', 'F', '*', '*', 'F', '*', '*', '*'>,
- static_mask<'*', '*', 'F', 'T', '*', 'F', '*', '*', '*'>,
- static_mask<'*', '*', 'F', '*', 'T', 'F', '*', '*', '*'>
- > static_mask_covered_by;
-
-// CROSSES
-// dim(G1) < dim(G2) - P/L P/A L/A
-template <typename Geometry1,
- typename Geometry2,
- std::size_t Dim1 = topological_dimension<Geometry1>::value,
- std::size_t Dim2 = topological_dimension<Geometry2>::value,
- bool D1LessD2 = (Dim1 < Dim2)
->
-struct static_mask_crosses_impl
-{
- typedef static_mask<'T', '*', 'T', '*', '*', '*', '*', '*', '*'> type;
-};
-// TODO: I'm not sure if this one below should be available!
-// dim(G1) > dim(G2) - L/P A/P A/L
-template <typename Geometry1, typename Geometry2,
- std::size_t Dim1, std::size_t Dim2
->
-struct static_mask_crosses_impl<Geometry1, Geometry2, Dim1, Dim2, false>
-{
- typedef static_mask<'T', '*', '*', '*', '*', '*', 'T', '*', '*'> type;
-};
-// dim(G1) == dim(G2) - P/P A/A
-template <typename Geometry1, typename Geometry2,
- std::size_t Dim
->
-struct static_mask_crosses_impl<Geometry1, Geometry2, Dim, Dim, false>
- : not_implemented<typename geometry::tag<Geometry1>::type,
- typename geometry::tag<Geometry2>::type>
-{};
-// dim(G1) == 1 && dim(G2) == 1 - L/L
-template <typename Geometry1, typename Geometry2>
-struct static_mask_crosses_impl<Geometry1, Geometry2, 1, 1, false>
-{
- typedef static_mask<'0', '*', '*', '*', '*', '*', '*', '*', '*'> type;
-};
-
-template <typename Geometry1, typename Geometry2>
-struct static_mask_crosses_type
- : static_mask_crosses_impl<Geometry1, Geometry2>
-{};
-
-// OVERLAPS
-
-// dim(G1) != dim(G2) - NOT P/P, L/L, A/A
-template <typename Geometry1,
- typename Geometry2,
- std::size_t Dim1 = topological_dimension<Geometry1>::value,
- std::size_t Dim2 = topological_dimension<Geometry2>::value
->
-struct static_mask_overlaps_impl
- : not_implemented<typename geometry::tag<Geometry1>::type,
- typename geometry::tag<Geometry2>::type>
-{};
-// dim(G1) == D && dim(G2) == D - P/P A/A
-template <typename Geometry1, typename Geometry2, std::size_t Dim>
-struct static_mask_overlaps_impl<Geometry1, Geometry2, Dim, Dim>
-{
- typedef static_mask<'T', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
-};
-// dim(G1) == 1 && dim(G2) == 1 - L/L
-template <typename Geometry1, typename Geometry2>
-struct static_mask_overlaps_impl<Geometry1, Geometry2, 1, 1>
-{
- typedef static_mask<'1', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
-};
-
-template <typename Geometry1, typename Geometry2>
-struct static_mask_overlaps_type
- : static_mask_overlaps_impl<Geometry1, Geometry2>
-{};
-
-// RESULTS/HANDLERS UTILS
+// set
template <field F1, field F2, char V, typename Result>
inline void set(Result & res)
@@ -1273,33 +1213,7 @@ inline void set(Result & res)
set_dispatch<F1, F2, V, Transpose>::apply(res);
}
-template <char V, typename Result>
-inline void set(Result & res)
-{
- res.template set<interior, interior, V>();
- res.template set<interior, boundary, V>();
- res.template set<interior, exterior, V>();
- res.template set<boundary, interior, V>();
- res.template set<boundary, boundary, V>();
- res.template set<boundary, exterior, V>();
- res.template set<exterior, interior, V>();
- res.template set<exterior, boundary, V>();
- res.template set<exterior, exterior, V>();
-}
-
-template <char II, char IB, char IE, char BI, char BB, char BE, char EI, char EB, char EE, typename Result>
-inline void set(Result & res)
-{
- res.template set<interior, interior, II>();
- res.template set<interior, boundary, IB>();
- res.template set<interior, exterior, IE>();
- res.template set<boundary, interior, BI>();
- res.template set<boundary, boundary, BB>();
- res.template set<boundary, exterior, BE>();
- res.template set<exterior, interior, EI>();
- res.template set<exterior, boundary, EB>();
- res.template set<exterior, exterior, EE>();
-}
+// update
template <field F1, field F2, char D, typename Result>
inline void update(Result & res)
@@ -1333,6 +1247,8 @@ inline void update(Result & res)
update_result_dispatch<F1, F2, D, Transpose>::apply(res);
}
+// may_update
+
template <field F1, field F2, char D, typename Result>
inline bool may_update(Result const& res)
{
@@ -1365,13 +1281,7 @@ inline bool may_update(Result const& res)
return may_update_result_dispatch<F1, F2, D, Transpose>::apply(res);
}
-template <typename Result, char II, char IB, char IE, char BI, char BB, char BE, char EI, char EB, char EE>
-inline Result return_result()
-{
- Result res;
- set<II, IB, IE, BI, BB, BE, EI, EB, EE>(res);
- return res;
-}
+// result_dimension
template <typename Geometry>
struct result_dimension
diff --git a/boost/geometry/algorithms/detail/relate/turns.hpp b/boost/geometry/algorithms/detail/relate/turns.hpp
index 636c9756d8..d54948e1f5 100644
--- a/boost/geometry/algorithms/detail/relate/turns.hpp
+++ b/boost/geometry/algorithms/detail/relate/turns.hpp
@@ -84,14 +84,30 @@ struct get_turns
Geometry2 const& geometry2,
InterruptPolicy & interrupt_policy)
{
- static const bool reverse1 = detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value;
- static const bool reverse2 = detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value;
-
RobustPolicy robust_policy = geometry::get_rescale_policy
<
RobustPolicy
>(geometry1, geometry2);
+ apply(turns, geometry1, geometry2, interrupt_policy, robust_policy);
+ }
+
+ template <typename Turns, typename InterruptPolicy>
+ static inline void apply(Turns & turns,
+ Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ InterruptPolicy & interrupt_policy,
+ RobustPolicy const& robust_policy)
+ {
+ static const bool reverse1 = detail::overlay::do_reverse
+ <
+ geometry::point_order<Geometry1>::value
+ >::value;
+
+ static const bool reverse2 = detail::overlay::do_reverse
+ <
+ geometry::point_order<Geometry2>::value
+ >::value;
dispatch::get_turns
<
@@ -255,9 +271,14 @@ struct less
{
static LessOp less_op;
- return left.operations[OpId].fraction < right.operations[OpId].fraction
- || ( left.operations[OpId].fraction == right.operations[OpId].fraction
- && less_op(left, right) );
+ return
+ geometry::math::equals(left.operations[OpId].fraction,
+ right.operations[OpId].fraction)
+ ?
+ less_op(left, right)
+ :
+ (left.operations[OpId].fraction < right.operations[OpId].fraction)
+ ;
}
template <typename Turn>
diff --git a/boost/geometry/algorithms/detail/relation/implementation.hpp b/boost/geometry/algorithms/detail/relation/implementation.hpp
new file mode 100644
index 0000000000..b9a238d6c8
--- /dev/null
+++ b/boost/geometry/algorithms/detail/relation/implementation.hpp
@@ -0,0 +1,18 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015 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_RELATION_IMPLEMENTATION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATION_IMPLEMENTATION_HPP
+
+
+#include <boost/geometry/algorithms/detail/relate/implementation.hpp>
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATION_IMPLEMENTATION_HPP
diff --git a/boost/geometry/algorithms/detail/relation/interface.hpp b/boost/geometry/algorithms/detail/relation/interface.hpp
new file mode 100644
index 0000000000..73737cf2c2
--- /dev/null
+++ b/boost/geometry/algorithms/detail/relation/interface.hpp
@@ -0,0 +1,186 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// 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.
+
+// 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_RELATION_INTERFACE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATION_INTERFACE_HPP
+
+
+#include <boost/geometry/algorithms/detail/relate/interface.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace relate
+{
+
+template <typename Geometry1, typename Geometry2>
+struct result_handler_type<Geometry1, Geometry2, geometry::de9im::matrix, false>
+{
+ typedef matrix_handler<geometry::de9im::matrix> type;
+};
+
+
+}} // namespace detail::relate
+#endif // DOXYGEN_NO_DETAIL
+
+
+namespace resolve_variant
+{
+
+template <typename Geometry1, typename Geometry2>
+struct relation
+{
+ template <typename Matrix>
+ static inline Matrix apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2)
+ {
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+ assert_dimension_equal<Geometry1, Geometry2>();
+
+ typename detail::relate::result_handler_type
+ <
+ Geometry1,
+ Geometry2,
+ Matrix
+ >::type handler;
+
+ dispatch::relate
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, handler);
+
+ return handler.result();
+ }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
+struct relation<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
+{
+ template <typename Matrix>
+ struct visitor : boost::static_visitor<Matrix>
+ {
+ Geometry2 const& m_geometry2;
+
+ visitor(Geometry2 const& geometry2)
+ : m_geometry2(geometry2) {}
+
+ template <typename Geometry1>
+ Matrix operator()(Geometry1 const& geometry1) const
+ {
+ return relation<Geometry1, Geometry2>
+ ::template apply<Matrix>(geometry1, m_geometry2);
+ }
+ };
+
+ template <typename Matrix>
+ static inline Matrix
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
+ Geometry2 const& geometry2)
+ {
+ return boost::apply_visitor(visitor<Matrix>(geometry2), geometry1);
+ }
+};
+
+template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct relation<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ template <typename Matrix>
+ struct visitor : boost::static_visitor<Matrix>
+ {
+ Geometry1 const& m_geometry1;
+
+ visitor(Geometry1 const& geometry1)
+ : m_geometry1(geometry1) {}
+
+ template <typename Geometry2>
+ Matrix operator()(Geometry2 const& geometry2) const
+ {
+ return relation<Geometry1, Geometry2>
+ ::template apply<Matrix>(m_geometry1, geometry2);
+ }
+ };
+
+ template <typename Matrix>
+ static inline Matrix
+ apply(Geometry1 const& geometry1,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2)
+ {
+ return boost::apply_visitor(visitor<Matrix>(geometry1), geometry2);
+ }
+};
+
+template
+<
+ BOOST_VARIANT_ENUM_PARAMS(typename T1),
+ BOOST_VARIANT_ENUM_PARAMS(typename T2)
+>
+struct relation
+ <
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
+ >
+{
+ template <typename Matrix>
+ struct visitor : boost::static_visitor<Matrix>
+ {
+ template <typename Geometry1, typename Geometry2>
+ Matrix operator()(Geometry1 const& geometry1,
+ Geometry2 const& geometry2) const
+ {
+ return relation<Geometry1, Geometry2>
+ ::template apply<Matrix>(geometry1, geometry2);
+ }
+ };
+
+ template <typename Matrix>
+ static inline Matrix
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2)
+ {
+ return boost::apply_visitor(visitor<Matrix>(), geometry1, geometry2);
+ }
+};
+
+} // namespace resolve_variant
+
+
+/*!
+\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.
+
+\qbk{[include reference/algorithms/relation.qbk]}
+ */
+template <typename Geometry1, typename Geometry2>
+inline de9im::matrix relation(Geometry1 const& geometry1,
+ Geometry2 const& geometry2)
+{
+ return resolve_variant::relation
+ <
+ Geometry1,
+ Geometry2
+ >::template apply<de9im::matrix>(geometry1, geometry2);
+}
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_INTERFACE_HPP
diff --git a/boost/geometry/algorithms/detail/result_inverse.hpp b/boost/geometry/algorithms/detail/result_inverse.hpp
new file mode 100644
index 0000000000..01a1997e49
--- /dev/null
+++ b/boost/geometry/algorithms/detail/result_inverse.hpp
@@ -0,0 +1,44 @@
+// Boost.Geometry
+
+// Copyright (c) 2015 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_RESULT_INVERSE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RESULT_INVERSE_HPP
+
+
+#include <boost/math/constants/constants.hpp>
+
+#include <boost/geometry/core/radius.hpp>
+#include <boost/geometry/core/srs.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/detail/flattening.hpp>
+
+
+namespace boost { namespace geometry { namespace detail
+{
+
+template <typename T>
+struct result_inverse
+{
+ void set(T const& d, T const& a)
+ {
+ distance = d;
+ azimuth = a;
+ }
+
+ T distance;
+ T azimuth;
+};
+
+}}} // namespace boost::geometry::detail
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RESULT_INVERSE_HPP
diff --git a/boost/geometry/algorithms/detail/ring_identifier.hpp b/boost/geometry/algorithms/detail/ring_identifier.hpp
index bc3fe1fef3..9ba39e4a8b 100644
--- a/boost/geometry/algorithms/detail/ring_identifier.hpp
+++ b/boost/geometry/algorithms/detail/ring_identifier.hpp
@@ -15,7 +15,7 @@
#endif
-#include <boost/geometry/algorithms/detail/signed_index_type.hpp>
+#include <boost/geometry/algorithms/detail/signed_size_type.hpp>
namespace boost { namespace geometry
@@ -32,9 +32,9 @@ struct ring_identifier
, ring_index(-1)
{}
- inline ring_identifier(signed_index_type src,
- signed_index_type mul,
- signed_index_type rin)
+ inline ring_identifier(signed_size_type src,
+ signed_size_type mul,
+ signed_size_type rin)
: source_index(src)
, multi_index(mul)
, ring_index(rin)
@@ -68,9 +68,9 @@ struct ring_identifier
#endif
- signed_index_type source_index;
- signed_index_type multi_index;
- signed_index_type ring_index;
+ signed_size_type source_index;
+ signed_size_type multi_index;
+ signed_size_type ring_index;
};
diff --git a/boost/geometry/algorithms/detail/sections/range_by_section.hpp b/boost/geometry/algorithms/detail/sections/range_by_section.hpp
index d139a3fdd2..02cec6cb48 100644
--- a/boost/geometry/algorithms/detail/sections/range_by_section.hpp
+++ b/boost/geometry/algorithms/detail/sections/range_by_section.hpp
@@ -19,11 +19,11 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP
-#include <boost/assert.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
@@ -77,7 +77,7 @@ struct full_section_multi
{
typedef typename boost::range_size<MultiGeometry>::type size_type;
- BOOST_ASSERT
+ BOOST_GEOMETRY_ASSERT
(
section.ring_id.multi_index >= 0
&& size_type(section.ring_id.multi_index) < boost::size(multi)
diff --git a/boost/geometry/algorithms/detail/sections/sectionalize.hpp b/boost/geometry/algorithms/detail/sections/sectionalize.hpp
index a744ea0a34..1ced394353 100644
--- a/boost/geometry/algorithms/detail/sections/sectionalize.hpp
+++ b/boost/geometry/algorithms/detail/sections/sectionalize.hpp
@@ -1,12 +1,12 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+// 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.
-// 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, 2015.
+// Modifications copyright (c) 2013-2015 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
@@ -36,6 +36,7 @@
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
#include <boost/geometry/algorithms/detail/recalculate.hpp>
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
+#include <boost/geometry/algorithms/detail/signed_size_type.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/closure.hpp>
@@ -80,12 +81,14 @@ struct section
ring_identifier ring_id;
Box bounding_box;
- int begin_index;
- int end_index;
+ // NOTE: size_type could be passed as template parameter
+ // NOTE: these probably also could be of type std::size_t
+ signed_size_type begin_index;
+ signed_size_type end_index;
std::size_t count;
std::size_t range_count;
bool duplicate;
- int non_duplicate_index;
+ signed_size_type non_duplicate_index;
bool is_non_duplicate_first;
bool is_non_duplicate_last;
@@ -248,7 +251,7 @@ struct check_duplicate_loop<DimensionCount, DimensionCount>
template <typename T, std::size_t Index, std::size_t Count>
struct assign_loop
{
- static inline void apply(T dims[Count], int const value)
+ static inline void apply(T dims[Count], T const value)
{
dims[Index] = value;
assign_loop<T, Index + 1, Count>::apply(dims, value);
@@ -258,7 +261,7 @@ struct assign_loop
template <typename T, std::size_t Count>
struct assign_loop<T, Count, Count>
{
- static inline void apply(T [Count], int const)
+ static inline void apply(T [Count], T const)
{
}
};
@@ -291,8 +294,8 @@ struct sectionalize_part
typedef typename boost::range_value<Sections>::type section_type;
BOOST_STATIC_ASSERT
(
- (static_cast<int>(section_type::dimension_count)
- == static_cast<int>(boost::mpl::size<DimensionVector>::value))
+ (static_cast<std::size_t>(section_type::dimension_count)
+ == static_cast<std::size_t>(boost::mpl::size<DimensionVector>::value))
);
typedef typename geometry::robust_point_type
@@ -307,8 +310,8 @@ struct sectionalize_part
return;
}
- int index = 0;
- int ndi = 0; // non duplicate index
+ signed_size_type index = 0;
+ signed_size_type ndi = 0; // non duplicate index
section_type section;
bool mark_first_non_duplicated = true;
diff --git a/boost/geometry/algorithms/detail/signed_index_type.hpp b/boost/geometry/algorithms/detail/signed_size_type.hpp
index 36dcf4de4c..db7344ec80 100644
--- a/boost/geometry/algorithms/detail/signed_index_type.hpp
+++ b/boost/geometry/algorithms/detail/signed_size_type.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -8,8 +8,8 @@
// 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_SIGNED_INDEX_TYPE_HPP
-#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SIGNED_INDEX_TYPE_HPP
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SIGNED_SIZE_TYPE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SIGNED_SIZE_TYPE_HPP
#include <cstddef>
@@ -20,10 +20,9 @@ namespace boost { namespace geometry
{
-typedef boost::make_signed<std::size_t>::type signed_index_type;
-//typedef std::ptrdiff_t signed_index_type;
+typedef boost::make_signed<std::size_t>::type signed_size_type;
}} // namespace boost::geometry
-#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SIGNED_INDEX_TYPE_HPP
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SIGNED_SIZE_TYPE_HPP
diff --git a/boost/geometry/algorithms/detail/single_geometry.hpp b/boost/geometry/algorithms/detail/single_geometry.hpp
index f38295ada6..31e4401099 100644
--- a/boost/geometry/algorithms/detail/single_geometry.hpp
+++ b/boost/geometry/algorithms/detail/single_geometry.hpp
@@ -14,7 +14,10 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SINGLE_GEOMETRY_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SINGLE_GEOMETRY_HPP
+#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_base_of.hpp>
+
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/util/range.hpp>
@@ -44,17 +47,12 @@ struct single_geometry
template <typename Geometry>
struct single_geometry<Geometry, true>
{
- typedef typename boost::mpl::if_c
- <
- boost::is_const<Geometry>::value,
- typename boost::range_value<Geometry>::type const&,
- typename boost::range_value<Geometry>::type
- >::type return_type;
+ typedef typename boost::range_reference<Geometry>::type return_type;
template <typename Id>
static inline return_type apply(Geometry & g, Id const& id)
{
- BOOST_ASSERT(id.multi_index >= 0);
+ BOOST_GEOMETRY_ASSERT(id.multi_index >= 0);
typedef typename boost::range_size<Geometry>::type size_type;
return range::at(g, static_cast<size_type>(id.multi_index));
}
diff --git a/boost/geometry/algorithms/detail/sub_range.hpp b/boost/geometry/algorithms/detail/sub_range.hpp
index eda3ce58ba..29edc94e6c 100644
--- a/boost/geometry/algorithms/detail/sub_range.hpp
+++ b/boost/geometry/algorithms/detail/sub_range.hpp
@@ -14,6 +14,9 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP
+#include <boost/mpl/if.hpp>
+
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry {
@@ -84,7 +87,7 @@ struct sub_range<Geometry, Tag, true>
template <typename Id> static inline
return_type apply(Geometry & geometry, Id const& id)
{
- BOOST_ASSERT(0 <= id.multi_index);
+ BOOST_GEOMETRY_ASSERT(0 <= id.multi_index);
typedef typename boost::range_size<Geometry>::type size_type;
size_type const mi = static_cast<size_type>(id.multi_index);
return sub_sub_range::apply(range::at(geometry, mi), id);
@@ -111,6 +114,13 @@ sub_range(Geometry & geometry, Id const& id)
return detail_dispatch::sub_range<Geometry>::apply(geometry, id);
}
+template <typename Geometry, typename Id> inline
+typename sub_range_return_type<Geometry const>::type
+sub_range(Geometry const& geometry, Id const& id)
+{
+ return detail_dispatch::sub_range<Geometry const>::apply(geometry, id);
+}
+
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
diff --git a/boost/geometry/algorithms/detail/sweep.hpp b/boost/geometry/algorithms/detail/sweep.hpp
new file mode 100644
index 0000000000..3dc78261f2
--- /dev/null
+++ b/boost/geometry/algorithms/detail/sweep.hpp
@@ -0,0 +1,87 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SWEEP_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SWEEP_HPP
+
+#include <boost/core/ignore_unused.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace sweep
+{
+
+struct no_interrupt_policy
+{
+ static bool const enabled = false;
+
+ template <typename Event>
+ static inline bool apply(Event const&)
+ {
+ return false;
+ }
+};
+
+}} // namespace detail::sweep
+#endif // DOXYGEN_NO_DETAIL
+
+
+template
+<
+ typename Range,
+ typename PriorityQueue,
+ typename InitializationVisitor,
+ typename EventVisitor,
+ typename InterruptPolicy
+>
+inline void sweep(Range const& range, PriorityQueue& queue,
+ InitializationVisitor& initialization_visitor,
+ EventVisitor& event_visitor,
+ InterruptPolicy const& interrupt_policy)
+{
+ typedef typename PriorityQueue::value_type event_type;
+
+ initialization_visitor.apply(range, queue, event_visitor);
+ while (! queue.empty())
+ {
+ event_type event = queue.top();
+ queue.pop();
+ event_visitor.apply(event, queue);
+ if (interrupt_policy.enabled && interrupt_policy.apply(event))
+ {
+ break;
+ }
+ }
+
+ boost::ignore_unused(interrupt_policy);
+}
+
+
+template
+<
+ typename Range,
+ typename PriorityQueue,
+ typename InitializationVisitor,
+ typename EventVisitor
+>
+inline void sweep(Range const& range, PriorityQueue& queue,
+ InitializationVisitor& initialization_visitor,
+ EventVisitor& event_visitor)
+{
+ sweep(range, queue, initialization_visitor, event_visitor,
+ detail::sweep::no_interrupt_policy());
+}
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SWEEP_HPP
diff --git a/boost/geometry/algorithms/detail/thomas_inverse.hpp b/boost/geometry/algorithms/detail/thomas_inverse.hpp
new file mode 100644
index 0000000000..96b237e054
--- /dev/null
+++ b/boost/geometry/algorithms/detail/thomas_inverse.hpp
@@ -0,0 +1,191 @@
+// Boost.Geometry
+
+// Copyright (c) 2015 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_THOMAS_INVERSE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_THOMAS_INVERSE_HPP
+
+
+#include <boost/math/constants/constants.hpp>
+
+#include <boost/geometry/core/radius.hpp>
+#include <boost/geometry/core/srs.hpp>
+
+#include <boost/geometry/util/condition.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/detail/flattening.hpp>
+#include <boost/geometry/algorithms/detail/result_inverse.hpp>
+
+namespace boost { namespace geometry { namespace detail
+{
+
+/*!
+\brief The solution of the inverse problem of geodesics on latlong coordinates,
+ Forsyth-Andoyer-Lambert type approximation with second order terms.
+\author See
+ - Technical Report: PAUL D. THOMAS, MATHEMATICAL MODELS FOR NAVIGATION SYSTEMS, 1965
+ http://www.dtic.mil/docs/citations/AD0627893
+ - Technical Report: PAUL D. THOMAS, SPHEROIDAL GEODESICS, REFERENCE SYSTEMS, AND LOCAL GEOMETRY, 1970
+ http://www.dtic.mil/docs/citations/AD703541
+*/
+template <typename CT, bool EnableDistance, bool EnableAzimuth>
+struct thomas_inverse
+{
+ typedef result_inverse<CT> result_type;
+
+ template <typename T1, typename T2, typename Spheroid>
+ static inline result_type apply(T1 const& lon1,
+ T1 const& lat1,
+ T2 const& lon2,
+ T2 const& lat2,
+ Spheroid const& spheroid)
+ {
+ result_type result;
+
+ // coordinates in radians
+
+ if ( math::equals(lon1, lon2)
+ && math::equals(lat1, lat2) )
+ {
+ result.set(CT(0), CT(0));
+ return result;
+ }
+
+ CT const f = detail::flattening<CT>(spheroid);
+ CT const one_minus_f = CT(1) - f;
+
+// CT const tan_theta1 = one_minus_f * tan(lat1);
+// CT const tan_theta2 = one_minus_f * tan(lat2);
+// CT const theta1 = atan(tan_theta1);
+// CT const theta2 = atan(tan_theta2);
+
+ CT const pi_half = math::pi<CT>() / CT(2);
+ CT const theta1 = math::equals(lat1, pi_half) ? lat1 :
+ math::equals(lat1, -pi_half) ? lat1 :
+ atan(one_minus_f * tan(lat1));
+ CT const theta2 = math::equals(lat2, pi_half) ? lat2 :
+ math::equals(lat2, -pi_half) ? lat2 :
+ atan(one_minus_f * tan(lat2));
+
+ CT const theta_m = (theta1 + theta2) / CT(2);
+ CT const d_theta_m = (theta2 - theta1) / CT(2);
+ CT const d_lambda = lon2 - lon1;
+ CT const d_lambda_m = d_lambda / CT(2);
+
+ CT const sin_theta_m = sin(theta_m);
+ CT const cos_theta_m = cos(theta_m);
+ CT const sin_d_theta_m = sin(d_theta_m);
+ CT const cos_d_theta_m = cos(d_theta_m);
+ CT const sin2_theta_m = math::sqr(sin_theta_m);
+ CT const cos2_theta_m = math::sqr(cos_theta_m);
+ CT const sin2_d_theta_m = math::sqr(sin_d_theta_m);
+ CT const cos2_d_theta_m = math::sqr(cos_d_theta_m);
+ CT const sin_d_lambda_m = sin(d_lambda_m);
+ CT const sin2_d_lambda_m = math::sqr(sin_d_lambda_m);
+
+ CT const H = cos2_theta_m - sin2_d_theta_m;
+ CT const L = sin2_d_theta_m + H * sin2_d_lambda_m;
+ CT const cos_d = CT(1) - CT(2) * L;
+ CT const d = acos(cos_d);
+ CT const sin_d = sin(d);
+
+ CT const one_minus_L = CT(1) - L;
+
+ if ( math::equals(sin_d, CT(0))
+ || math::equals(L, CT(0))
+ || math::equals(one_minus_L, CT(0)) )
+ {
+ result.set(CT(0), CT(0));
+ return result;
+ }
+
+ CT const U = CT(2) * sin2_theta_m * cos2_d_theta_m / one_minus_L;
+ CT const V = CT(2) * sin2_d_theta_m * cos2_theta_m / L;
+ CT const X = U + V;
+ CT const Y = U - V;
+ CT const T = d / sin_d;
+ //CT const D = CT(4) * math::sqr(T);
+ //CT const E = CT(2) * cos_d;
+ //CT const A = D * E;
+ //CT const B = CT(2) * D;
+ //CT const C = T - (A - E) / CT(2);
+
+ if ( BOOST_GEOMETRY_CONDITION(EnableDistance) )
+ {
+ //CT const n1 = X * (A + C*X);
+ //CT const n2 = Y * (B + E*Y);
+ //CT const n3 = D*X*Y;
+
+ //CT const f_sqr = math::sqr(f);
+ //CT const f_sqr_per_64 = f_sqr / CT(64);
+
+ CT const delta1d = f * (T*X-Y) / CT(4);
+ //CT const delta2d = f_sqr_per_64 * (n1 - n2 + n3);
+
+ CT const a = get_radius<0>(spheroid);
+
+ result.distance = a * sin_d * (T - delta1d);
+ //double S2 = a * sin_d * (T - delta1d + delta2d);
+ }
+ else
+ {
+ result.distance = CT(0);
+ }
+
+ if ( BOOST_GEOMETRY_CONDITION(EnableAzimuth) )
+ {
+ // NOTE: if both cos_latX == 0 then below we'd have 0 * INF
+ // it's a situation when the endpoints are on the poles +-90 deg
+ // in this case the azimuth could either be 0 or +-pi
+ // but above always 0 is returned
+
+ // may also be used to calculate distance21
+ //CT const D = CT(4) * math::sqr(T);
+ CT const E = CT(2) * cos_d;
+ //CT const A = D * E;
+ //CT const B = CT(2) * D;
+ // may also be used to calculate distance21
+ CT const f_sqr = math::sqr(f);
+ CT const f_sqr_per_64 = f_sqr / CT(64);
+
+ CT const F = CT(2)*Y-E*(CT(4)-X);
+ //CT const M = CT(32)*T-(CT(20)*T-A)*X-(B+CT(4))*Y;
+ CT const G = f*T/CT(2) + f_sqr_per_64;
+ CT const tan_d_lambda = tan(d_lambda);
+ CT const Q = -(F*G*tan_d_lambda) / CT(4);
+
+ CT const d_lambda_p = (d_lambda + Q) / CT(2);
+ CT const tan_d_lambda_p = tan(d_lambda_p);
+
+ CT const v = atan2(cos_d_theta_m, sin_theta_m * tan_d_lambda_p);
+ CT const u = atan2(-sin_d_theta_m, cos_theta_m * tan_d_lambda_p);
+
+ CT const pi = math::pi<CT>();
+ CT alpha1 = v + u;
+ if ( alpha1 > pi )
+ {
+ alpha1 -= CT(2) * pi;
+ }
+
+ result.azimuth = alpha1;
+ }
+ else
+ {
+ result.azimuth = CT(0);
+ }
+
+ return result;
+ }
+};
+
+}}} // namespace boost::geometry::detail
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_THOMAS_INVERSE_HPP
diff --git a/boost/geometry/algorithms/detail/throw_on_empty_input.hpp b/boost/geometry/algorithms/detail/throw_on_empty_input.hpp
index 21f5fe40b7..2f82e1a8bd 100644
--- a/boost/geometry/algorithms/detail/throw_on_empty_input.hpp
+++ b/boost/geometry/algorithms/detail/throw_on_empty_input.hpp
@@ -1,8 +1,13 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// 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.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, 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,7 +17,7 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_THROW_ON_EMPTY_INPUT_HPP
#include <boost/geometry/core/exception.hpp>
-#include <boost/geometry/algorithms/num_points.hpp>
+#include <boost/geometry/algorithms/is_empty.hpp>
// BSG 2012-02-06: we use this currently only for distance.
// For other scalar results area,length,perimeter it is commented on purpose.
@@ -39,7 +44,7 @@ template <typename Geometry>
inline void throw_on_empty_input(Geometry const& geometry)
{
#if ! defined(BOOST_GEOMETRY_EMPTY_INPUT_NO_THROW)
- if (geometry::num_points(geometry) == 0)
+ if (geometry::is_empty(geometry))
{
throw empty_input_exception();
}
diff --git a/boost/geometry/algorithms/detail/turns/compare_turns.hpp b/boost/geometry/algorithms/detail/turns/compare_turns.hpp
index c29d5863b7..ec383bf103 100644
--- a/boost/geometry/algorithms/detail/turns/compare_turns.hpp
+++ b/boost/geometry/algorithms/detail/turns/compare_turns.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -30,7 +30,7 @@ namespace detail { namespace turns
// seg_id -> fraction -> other_id -> operation
template
<
- typename IdLess = std::less<signed_index_type>,
+ typename IdLess = std::less<signed_size_type>,
int N = 0, int U = 1, int I = 2, int B = 3, int C = 4, int O = 0,
std::size_t OpId = 0
>
@@ -85,10 +85,14 @@ struct less_seg_fraction_other_op
template <typename Turn>
static inline bool use_fraction(Turn const& left, Turn const& right)
{
- return left.operations[OpId].fraction < right.operations[OpId].fraction
- || ( geometry::math::equals(left.operations[OpId].fraction, right.operations[OpId].fraction)
- && use_other_id(left, right)
- );
+ return
+ geometry::math::equals(left.operations[OpId].fraction,
+ right.operations[OpId].fraction)
+ ?
+ use_other_id(left, right)
+ :
+ (left.operations[OpId].fraction < right.operations[OpId].fraction)
+ ;
}
template <typename Turn>
diff --git a/boost/geometry/algorithms/detail/turns/print_turns.hpp b/boost/geometry/algorithms/detail/turns/print_turns.hpp
index 9d4e45c41f..1e9b9df409 100644
--- a/boost/geometry/algorithms/detail/turns/print_turns.hpp
+++ b/boost/geometry/algorithms/detail/turns/print_turns.hpp
@@ -56,7 +56,7 @@ struct turn_printer
<<": seg: " << turn.operations[0].seg_id.source_index
<< ", m: " << turn.operations[0].seg_id.multi_index
<< ", r: " << turn.operations[0].seg_id.ring_index
- << ", s: " << turn.operations[0].seg_id.segment_index << ", ";
+ << ", s: " << turn.operations[0].seg_id.segment_index;
out << ", fr: " << fraction[0];
out << ", col?: " << turn.operations[0].is_collinear;
out << ' ' << geometry::dsv(turn.point) << ' ';
@@ -70,7 +70,7 @@ struct turn_printer
<< ": seg: " << turn.operations[1].seg_id.source_index
<< ", m: " << turn.operations[1].seg_id.multi_index
<< ", r: " << turn.operations[1].seg_id.ring_index
- << ", s: " << turn.operations[1].seg_id.segment_index << ", ";
+ << ", s: " << turn.operations[1].seg_id.segment_index;
out << ", fr: " << fraction[1];
out << ", col?: " << turn.operations[1].is_collinear;
out << ' ' << geometry::dsv(turn.point) << ' ';
diff --git a/boost/geometry/algorithms/detail/vincenty_direct.hpp b/boost/geometry/algorithms/detail/vincenty_direct.hpp
index 775687cfdb..1c47a0f68d 100644
--- a/boost/geometry/algorithms/detail/vincenty_direct.hpp
+++ b/boost/geometry/algorithms/detail/vincenty_direct.hpp
@@ -33,6 +33,18 @@
namespace boost { namespace geometry { namespace detail
{
+template <typename T>
+struct result_direct
+{
+ void set(T const& lo2, T const& la2)
+ {
+ lon2 = lo2;
+ lat2 = la2;
+ }
+ T lon2;
+ T lat2;
+};
+
/*!
\brief The solution of the direct problem of geodesics on latlong coordinates, after Vincenty, 1975
\author See
@@ -45,45 +57,49 @@ namespace boost { namespace geometry { namespace detail
*/
template <typename CT>
-class vincenty_direct
+struct vincenty_direct
{
+ typedef result_direct<CT> result_type;
+
public:
template <typename T, typename Dist, typename Azi, typename Spheroid>
- vincenty_direct(T const& lo1,
- T const& la1,
- Dist const& distance,
- Azi const& azimuth12,
- Spheroid const& spheroid)
- : lon1(lo1)
- , lat1(la1)
- , is_distance_zero(false)
+ static inline result_type apply(T const& lo1,
+ T const& la1,
+ Dist const& distance,
+ Azi const& azimuth12,
+ Spheroid const& spheroid)
{
+ result_type result;
+
+ CT const lon1 = lo1;
+ CT const lat1 = la1;
+
if ( math::equals(distance, Dist(0)) || distance < Dist(0) )
{
- is_distance_zero = true;
- return;
+ result.set(lon1, lat1);
+ return result;
}
CT const radius_a = CT(get_radius<0>(spheroid));
CT const radius_b = CT(get_radius<2>(spheroid));
- flattening = geometry::detail::flattening<CT>(spheroid);
+ CT const flattening = geometry::detail::flattening<CT>(spheroid);
- sin_azimuth12 = sin(azimuth12);
- cos_azimuth12 = cos(azimuth12);
+ CT const sin_azimuth12 = sin(azimuth12);
+ CT const cos_azimuth12 = cos(azimuth12);
// U: reduced latitude, defined by tan U = (1-f) tan phi
- one_min_f = CT(1) - flattening;
+ CT const one_min_f = CT(1) - flattening;
CT const tan_U1 = one_min_f * tan(lat1);
CT const sigma1 = atan2(tan_U1, cos_azimuth12); // (1)
// may be calculated from tan using 1 sqrt()
CT const U1 = atan(tan_U1);
- sin_U1 = sin(U1);
- cos_U1 = cos(U1);
+ CT const sin_U1 = sin(U1);
+ CT const cos_U1 = cos(U1);
- sin_alpha = cos_U1 * sin_azimuth12; // (2)
- sin_alpha_sqr = math::sqr(sin_alpha);
- cos_alpha_sqr = CT(1) - sin_alpha_sqr;
+ CT const sin_alpha = cos_U1 * sin_azimuth12; // (2)
+ CT const sin_alpha_sqr = math::sqr(sin_alpha);
+ CT const cos_alpha_sqr = CT(1) - sin_alpha_sqr;
CT const b_sqr = radius_b * radius_b;
CT const u_sqr = cos_alpha_sqr * (radius_a * radius_a - b_sqr) / b_sqr;
@@ -91,9 +107,13 @@ public:
CT const B = (u_sqr/CT(1024))*(CT(256) + u_sqr*(CT(-128) + u_sqr*(CT(74) - u_sqr*CT(47)))); // (4)
CT s_div_bA = distance / (radius_b * A);
- sigma = s_div_bA; // (7)
+ CT sigma = s_div_bA; // (7)
CT previous_sigma;
+ CT sin_sigma;
+ CT cos_sigma;
+ CT cos_2sigma_m;
+ CT cos_2sigma_m_sqr;
int counter = 0; // robustness
@@ -120,35 +140,27 @@ public:
} while ( geometry::math::abs(previous_sigma - sigma) > CT(1e-12)
//&& geometry::math::abs(sigma) < pi
&& counter < BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS ); // robustness
- }
- inline CT lat2() const
- {
- if ( is_distance_zero )
{
- return lat1;
+ result.lat2
+ = atan2( sin_U1 * cos_sigma + cos_U1 * sin_sigma * cos_azimuth12,
+ one_min_f * math::sqrt(sin_alpha_sqr + math::sqr(sin_U1 * sin_sigma - cos_U1 * cos_sigma * cos_azimuth12))); // (8)
}
- return atan2( sin_U1 * cos_sigma + cos_U1 * sin_sigma * cos_azimuth12,
- one_min_f * math::sqrt(sin_alpha_sqr + math::sqr(sin_U1 * sin_sigma - cos_U1 * cos_sigma * cos_azimuth12))); // (8)
- }
-
- inline CT lon2() const
- {
- if ( is_distance_zero )
{
- return lon1;
- }
+ CT const lambda = atan2( sin_sigma * sin_azimuth12,
+ cos_U1 * cos_sigma - sin_U1 * sin_sigma * cos_azimuth12); // (9)
+ CT const C = (flattening/CT(16)) * cos_alpha_sqr * ( CT(4) + flattening * ( CT(4) - CT(3) * cos_alpha_sqr ) ); // (10)
+ CT const L = lambda - (CT(1) - C) * flattening * sin_alpha
+ * ( sigma + C * sin_sigma * ( cos_2sigma_m + C * cos_sigma * ( CT(-1) + CT(2) * cos_2sigma_m_sqr ) ) ); // (11)
- CT const lambda = atan2( sin_sigma * sin_azimuth12,
- cos_U1 * cos_sigma - sin_U1 * sin_sigma * cos_azimuth12); // (9)
- CT const C = (flattening/CT(16)) * cos_alpha_sqr * ( CT(4) + flattening * ( CT(4) - CT(3) * cos_alpha_sqr ) ); // (10)
- CT const L = lambda - (CT(1) - C) * flattening * sin_alpha
- * ( sigma + C * sin_sigma * ( cos_2sigma_m + C * cos_sigma * ( CT(-1) + CT(2) * cos_2sigma_m_sqr ) ) ); // (11)
+ result.lon2 = lon1 + L;
+ }
- return lon1 + L;
+ return result;
}
+ /*
inline CT azimuth21() const
{
// NOTE: signs of X and Y are different than in the original paper
@@ -156,32 +168,7 @@ public:
CT(0) :
atan2(-sin_alpha, sin_U1 * sin_sigma - cos_U1 * cos_sigma * cos_azimuth12); // (12)
}
-
-private:
- CT sigma;
- CT sin_sigma;
- CT cos_sigma;
-
- CT cos_2sigma_m;
- CT cos_2sigma_m_sqr;
-
- CT sin_alpha;
- CT sin_alpha_sqr;
- CT cos_alpha_sqr;
-
- CT sin_azimuth12;
- CT cos_azimuth12;
-
- CT sin_U1;
- CT cos_U1;
-
- CT flattening;
- CT one_min_f;
-
- CT const lon1;
- CT const lat1;
-
- bool is_distance_zero;
+ */
};
}}} // namespace boost::geometry::detail
diff --git a/boost/geometry/algorithms/detail/vincenty_inverse.hpp b/boost/geometry/algorithms/detail/vincenty_inverse.hpp
index 861452af00..fe05e95932 100644
--- a/boost/geometry/algorithms/detail/vincenty_inverse.hpp
+++ b/boost/geometry/algorithms/detail/vincenty_inverse.hpp
@@ -20,9 +20,11 @@
#include <boost/geometry/core/radius.hpp>
#include <boost/geometry/core/srs.hpp>
+#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/algorithms/detail/flattening.hpp>
+#include <boost/geometry/algorithms/detail/result_inverse.hpp>
#ifndef BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS
@@ -44,22 +46,25 @@ namespace boost { namespace geometry { namespace detail
- http://futureboy.homeip.net/fsp/colorize.fsp?fileName=navigation.frink
*/
-template <typename CT>
-class vincenty_inverse
+template <typename CT, bool EnableDistance, bool EnableAzimuth>
+struct vincenty_inverse
{
+ typedef result_inverse<CT> result_type;
+
public:
template <typename T1, typename T2, typename Spheroid>
- vincenty_inverse(T1 const& lon1,
- T1 const& lat1,
- T2 const& lon2,
- T2 const& lat2,
- Spheroid const& spheroid)
- : is_result_zero(false)
+ static inline result_type apply(T1 const& lon1,
+ T1 const& lat1,
+ T2 const& lon2,
+ T2 const& lat2,
+ Spheroid const& spheroid)
{
+ result_type result;
+
if (math::equals(lat1, lat2) && math::equals(lon1, lon2))
{
- is_result_zero = true;
- return;
+ result.set(CT(0), CT(0));
+ return result;
}
CT const c1 = 1;
@@ -79,8 +84,8 @@ public:
if (L < -pi) L += two_pi;
if (L > pi) L -= two_pi;
- radius_a = CT(get_radius<0>(spheroid));
- radius_b = CT(get_radius<2>(spheroid));
+ CT const radius_a = CT(get_radius<0>(spheroid));
+ CT const radius_b = CT(get_radius<2>(spheroid));
CT const flattening = geometry::detail::flattening<CT>(spheroid);
// U: reduced latitude, defined by tan U = (1-f) tan phi
@@ -92,11 +97,11 @@ public:
CT const temp_den_U1 = math::sqrt(c1 + math::sqr(tan_U1));
CT const temp_den_U2 = math::sqrt(c1 + math::sqr(tan_U2));
// cos = 1 / sqrt(1 + tan^2)
- cos_U1 = c1 / temp_den_U1;
- cos_U2 = c1 / temp_den_U2;
+ CT const cos_U1 = c1 / temp_den_U1;
+ CT const cos_U2 = c1 / temp_den_U2;
// sin = tan / sqrt(1 + tan^2)
- sin_U1 = tan_U1 / temp_den_U1;
- sin_U2 = tan_U2 / temp_den_U2;
+ CT const sin_U1 = tan_U1 / temp_den_U1;
+ CT const sin_U2 = tan_U2 / temp_den_U2;
// calculate sin U and cos U directly
//CT const U1 = atan(tan_U1);
@@ -107,6 +112,13 @@ public:
//sin_U2 = tan_U2 * cos_U2; // sin(U2);
CT previous_lambda;
+ CT sin_lambda;
+ CT cos_lambda;
+ CT sin_sigma;
+ CT sin_alpha;
+ CT cos2_alpha;
+ CT cos2_sigma_m;
+ CT sigma;
int counter = 0; // robustness
@@ -131,85 +143,59 @@ public:
} while ( geometry::math::abs(previous_lambda - lambda) > c_e_12
&& geometry::math::abs(lambda) < pi
&& counter < BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS ); // robustness
- }
-
- inline CT distance() const
- {
- if ( is_result_zero )
+
+ if ( BOOST_GEOMETRY_CONDITION(EnableDistance) )
{
- return CT(0);
+ // Oops getting hard here
+ // (again, problem is that ttmath cannot divide by doubles, which is OK)
+ CT const c1 = 1;
+ CT const c2 = 2;
+ CT const c3 = 3;
+ CT const c4 = 4;
+ CT const c6 = 6;
+ CT const c47 = 47;
+ CT const c74 = 74;
+ CT const c128 = 128;
+ CT const c256 = 256;
+ CT const c175 = 175;
+ CT const c320 = 320;
+ CT const c768 = 768;
+ CT const c1024 = 1024;
+ CT const c4096 = 4096;
+ CT const c16384 = 16384;
+
+ //CT sqr_u = cos2_alpha * (math::sqr(radius_a) - math::sqr(radius_b)) / math::sqr(radius_b); // above (1)
+ CT sqr_u = cos2_alpha * ( math::sqr(radius_a / radius_b) - c1 ); // above (1)
+
+ CT A = c1 + sqr_u/c16384 * (c4096 + sqr_u * (-c768 + sqr_u * (c320 - c175 * sqr_u))); // (3)
+ CT B = sqr_u/c1024 * (c256 + sqr_u * ( -c128 + sqr_u * (c74 - c47 * sqr_u))); // (4)
+ CT delta_sigma = B * sin_sigma * ( cos2_sigma_m + (B/c4) * (cos(sigma)* (-c1 + c2 * cos2_sigma_m)
+ - (B/c6) * cos2_sigma_m * (-c3 + c4 * math::sqr(sin_sigma)) * (-c3 + c4 * cos2_sigma_m))); // (6)
+
+ result.distance = radius_b * A * (sigma - delta_sigma); // (19)
+ }
+ else
+ {
+ result.distance = CT(0);
+ }
+
+ if ( BOOST_GEOMETRY_CONDITION(EnableAzimuth) )
+ {
+ result.azimuth = atan2(cos_U2 * sin_lambda, cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda); // (20)
+ }
+ else
+ {
+ result.azimuth = CT(0);
}
- // Oops getting hard here
- // (again, problem is that ttmath cannot divide by doubles, which is OK)
- CT const c1 = 1;
- CT const c2 = 2;
- CT const c3 = 3;
- CT const c4 = 4;
- CT const c6 = 6;
- CT const c47 = 47;
- CT const c74 = 74;
- CT const c128 = 128;
- CT const c256 = 256;
- CT const c175 = 175;
- CT const c320 = 320;
- CT const c768 = 768;
- CT const c1024 = 1024;
- CT const c4096 = 4096;
- CT const c16384 = 16384;
-
- //CT sqr_u = cos2_alpha * (math::sqr(radius_a) - math::sqr(radius_b)) / math::sqr(radius_b); // above (1)
- CT sqr_u = cos2_alpha * ( math::sqr(radius_a / radius_b) - c1 ); // above (1)
-
- CT A = c1 + sqr_u/c16384 * (c4096 + sqr_u * (-c768 + sqr_u * (c320 - c175 * sqr_u))); // (3)
- CT B = sqr_u/c1024 * (c256 + sqr_u * ( -c128 + sqr_u * (c74 - c47 * sqr_u))); // (4)
- CT delta_sigma = B * sin_sigma * ( cos2_sigma_m + (B/c4) * (cos(sigma)* (-c1 + c2 * cos2_sigma_m)
- - (B/c6) * cos2_sigma_m * (-c3 + c4 * math::sqr(sin_sigma)) * (-c3 + c4 * cos2_sigma_m))); // (6)
-
- return radius_b * A * (sigma - delta_sigma); // (19)
- }
-
- inline CT azimuth12() const
- {
- return is_result_zero ?
- CT(0) :
- atan2(cos_U2 * sin_lambda, cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda); // (20)
- }
-
- inline CT azimuth21() const
- {
- // NOTE: signs of X and Y are different than in the original paper
- return is_result_zero ?
- CT(0) :
- atan2(-cos_U1 * sin_lambda, sin_U1 * cos_U2 - cos_U1 * sin_U2 * cos_lambda); // (21)
+ return result;
}
-private:
- // alpha: azimuth of the geodesic at the equator
- CT cos2_alpha;
- CT sin_alpha;
-
- // sigma: angular distance p1,p2 on the sphere
- // sigma1: angular distance on the sphere from the equator to p1
- // sigma_m: angular distance on the sphere from the equator to the midpoint of the line
- CT sigma;
- CT sin_sigma;
- CT cos2_sigma_m;
-
- CT sin_lambda;
- CT cos_lambda;
-
- // set only once
- CT cos_U1;
- CT cos_U2;
- CT sin_U1;
- CT sin_U2;
-
- // set only once
- CT radius_a;
- CT radius_b;
-
- bool is_result_zero;
+// inline CT azimuth21() const
+// {
+// // NOTE: signs of X and Y are different than in the original paper
+// atan2(-cos_U1 * sin_lambda, sin_U1 * cos_U2 - cos_U1 * sin_U2 * cos_lambda); // (21)
+// }
};
}}} // namespace boost::geometry::detail
diff --git a/boost/geometry/algorithms/detail/within/point_in_geometry.hpp b/boost/geometry/algorithms/detail/within/point_in_geometry.hpp
index e7486f0e45..68e74a8c5c 100644
--- a/boost/geometry/algorithms/detail/within/point_in_geometry.hpp
+++ b/boost/geometry/algorithms/detail/within/point_in_geometry.hpp
@@ -20,13 +20,15 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_POINT_IN_GEOMETRY_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_POINT_IN_GEOMETRY_HPP
-#include <boost/assert.hpp>
+
#include <boost/core/ignore_unused.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/range.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_reference.hpp>
+#include <boost/geometry/core/assert.hpp>
+
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
@@ -53,7 +55,7 @@ inline int check_result_type(int result)
template <typename T>
inline T check_result_type(T result)
{
- BOOST_ASSERT(false);
+ BOOST_GEOMETRY_ASSERT(false);
return result;
}
@@ -291,7 +293,7 @@ struct point_in_geometry<Geometry, multi_point_tag>
{
int pip = point_in_geometry<point_type>::apply(point, *it, strategy);
- //BOOST_ASSERT(pip != 0);
+ //BOOST_GEOMETRY_ASSERT(pip != 0);
if ( pip > 0 ) // inside
return 1;
}
diff --git a/boost/geometry/algorithms/dispatch/envelope.hpp b/boost/geometry/algorithms/dispatch/envelope.hpp
new file mode 100644
index 0000000000..bb8a99f5a8
--- /dev/null
+++ b/boost/geometry/algorithms/dispatch/envelope.hpp
@@ -0,0 +1,49 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// 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.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Distributed under 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_DISPATCH_ENVELOPE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DISPATCH_ENVELOPE_HPP
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/tag.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Geometry,
+ typename Tag = typename tag<Geometry>::type,
+ typename CS_Tag = typename cs_tag<Geometry>::type
+>
+struct envelope : not_implemented<Tag>
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DISPATCH_ENVELOPE_HPP
diff --git a/boost/geometry/algorithms/dispatch/expand.hpp b/boost/geometry/algorithms/dispatch/expand.hpp
new file mode 100644
index 0000000000..2c23d6a1ce
--- /dev/null
+++ b/boost/geometry/algorithms/dispatch/expand.hpp
@@ -0,0 +1,58 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// 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 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Distributed under 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_DISPATCH_EXPAND_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DISPATCH_EXPAND_HPP
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/tag.hpp>
+
+#include <boost/geometry/strategies/compare.hpp>
+#include <boost/geometry/policies/compare.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename GeometryOut, typename Geometry,
+ typename StrategyLess = strategy::compare::default_strategy,
+ typename StrategyGreater = strategy::compare::default_strategy,
+ typename TagOut = typename tag<GeometryOut>::type,
+ typename Tag = typename tag<Geometry>::type,
+ typename CSTagOut = typename cs_tag<GeometryOut>::type,
+ typename CSTag = typename cs_tag<Geometry>::type
+>
+struct expand : not_implemented<TagOut, Tag>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DISPATCH_EXPAND_HPP
diff --git a/boost/geometry/algorithms/envelope.hpp b/boost/geometry/algorithms/envelope.hpp
index bd1ea9cb7a..00981224b2 100644
--- a/boost/geometry/algorithms/envelope.hpp
+++ b/boost/geometry/algorithms/envelope.hpp
@@ -1,295 +1,25 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// 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.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
-// Use, modification and distribution is subject to the Boost Software License,
-// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// Distributed under 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_ENVELOPE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_ENVELOPE_HPP
-#include <vector>
-
-#include <boost/numeric/conversion/cast.hpp>
-#include <boost/range.hpp>
-
-#include <boost/variant/apply_visitor.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/variant/variant_fwd.hpp>
-
-#include <boost/geometry/algorithms/assign.hpp>
-#include <boost/geometry/algorithms/expand.hpp>
-#include <boost/geometry/algorithms/not_implemented.hpp>
-#include <boost/geometry/core/cs.hpp>
-#include <boost/geometry/core/exterior_ring.hpp>
-#include <boost/geometry/core/point_type.hpp>
-#include <boost/geometry/core/tags.hpp>
-
-#include <boost/geometry/geometries/concepts/check.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace envelope
-{
-
-
-/// Calculate envelope of an 2D or 3D segment
-struct envelope_expand_one
-{
- template<typename Geometry, typename Box>
- static inline void apply(Geometry const& geometry, Box& mbr)
- {
- assign_inverse(mbr);
- geometry::expand(mbr, geometry);
- }
-};
-
-
-/// Iterate through range (also used in multi*)
-template<typename Range, typename Box>
-inline void envelope_range_additional(Range const& range, Box& mbr)
-{
- typedef typename boost::range_iterator<Range const>::type iterator_type;
-
- for (iterator_type it = boost::begin(range);
- it != boost::end(range);
- ++it)
- {
- geometry::expand(mbr, *it);
- }
-}
-
-
-
-/// Generic range dispatching struct
-struct envelope_range
-{
- /// Calculate envelope of range using a strategy
- template <typename Range, typename Box>
- static inline void apply(Range const& range, Box& mbr)
- {
- assign_inverse(mbr);
- envelope_range_additional(range, mbr);
- }
-};
-
-
-struct envelope_multi_linestring
-{
- template<typename MultiLinestring, typename Box>
- static inline void apply(MultiLinestring const& mp, Box& mbr)
- {
- assign_inverse(mbr);
- for (typename boost::range_iterator<MultiLinestring const>::type
- it = mp.begin();
- it != mp.end();
- ++it)
- {
- envelope_range_additional(*it, mbr);
- }
- }
-};
-
-
-// version for multi_polygon: outer ring's of all polygons
-struct envelope_multi_polygon
-{
- template<typename MultiPolygon, typename Box>
- static inline void apply(MultiPolygon const& mp, Box& mbr)
- {
- assign_inverse(mbr);
- for (typename boost::range_const_iterator<MultiPolygon>::type
- it = mp.begin();
- it != mp.end();
- ++it)
- {
- envelope_range_additional(exterior_ring(*it), mbr);
- }
- }
-};
-
-
-}} // namespace detail::envelope
-#endif // DOXYGEN_NO_DETAIL
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
-{
-
-
-template
-<
- typename Geometry,
- typename Tag = typename tag<Geometry>::type
->
-struct envelope: not_implemented<Tag>
-{};
-
-
-template <typename Point>
-struct envelope<Point, point_tag>
- : detail::envelope::envelope_expand_one
-{};
-
-
-template <typename Box>
-struct envelope<Box, box_tag>
- : detail::envelope::envelope_expand_one
-{};
-
-
-template <typename Segment>
-struct envelope<Segment, segment_tag>
- : detail::envelope::envelope_expand_one
-{};
-
-
-template <typename Linestring>
-struct envelope<Linestring, linestring_tag>
- : detail::envelope::envelope_range
-{};
-
-
-template <typename Ring>
-struct envelope<Ring, ring_tag>
- : detail::envelope::envelope_range
-{};
-
-
-template <typename Polygon>
-struct envelope<Polygon, polygon_tag>
- : detail::envelope::envelope_range
-{
- template <typename Box>
- static inline void apply(Polygon const& poly, Box& mbr)
- {
- // For polygon, inspecting outer ring is sufficient
- detail::envelope::envelope_range::apply(exterior_ring(poly), mbr);
- }
-
-};
-
-
-template <typename Multi>
-struct envelope<Multi, multi_point_tag>
- : detail::envelope::envelope_range
-{};
-
-
-template <typename Multi>
-struct envelope<Multi, multi_linestring_tag>
- : detail::envelope::envelope_multi_linestring
-{};
-
-
-template <typename Multi>
-struct envelope<Multi, multi_polygon_tag>
- : detail::envelope::envelope_multi_polygon
-{};
-
-
-} // namespace dispatch
-#endif
-
-
-namespace resolve_variant {
-
-template <typename Geometry>
-struct envelope
-{
- template <typename Box>
- static inline void apply(Geometry const& geometry, Box& box)
- {
- concept::check<Geometry const>();
- concept::check<Box>();
-
- dispatch::envelope<Geometry>::apply(geometry, box);
- }
-};
-
-template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
-struct envelope<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
-{
- template <typename Box>
- struct visitor: boost::static_visitor<void>
- {
- Box& m_box;
-
- visitor(Box& box): m_box(box) {}
-
- template <typename Geometry>
- void operator()(Geometry const& geometry) const
- {
- envelope<Geometry>::apply(geometry, m_box);
- }
- };
-
- template <typename Box>
- static inline void
- apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
- Box& box)
- {
- boost::apply_visitor(visitor<Box>(box), geometry);
- }
-};
-
-} // namespace resolve_variant
-
-
-/*!
-\brief \brief_calc{envelope}
-\ingroup envelope
-\details \details_calc{envelope,\det_envelope}.
-\tparam Geometry \tparam_geometry
-\tparam Box \tparam_box
-\param geometry \param_geometry
-\param mbr \param_box \param_set{envelope}
-
-\qbk{[include reference/algorithms/envelope.qbk]}
-\qbk{
-[heading Example]
-[envelope] [envelope_output]
-}
-*/
-template<typename Geometry, typename Box>
-inline void envelope(Geometry const& geometry, Box& mbr)
-{
- resolve_variant::envelope<Geometry>::apply(geometry, 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}
-
-\qbk{[include reference/algorithms/envelope.qbk]}
-\qbk{
-[heading Example]
-[return_envelope] [return_envelope_output]
-}
-*/
-template<typename Box, typename Geometry>
-inline Box return_envelope(Geometry const& geometry)
-{
- Box mbr;
- resolve_variant::envelope<Geometry>::apply(geometry, mbr);
- return mbr;
-}
-
-}} // namespace boost::geometry
+#include <boost/geometry/algorithms/detail/envelope/interface.hpp>
+#include <boost/geometry/algorithms/detail/envelope/implementation.hpp>
#endif // BOOST_GEOMETRY_ALGORITHMS_ENVELOPE_HPP
diff --git a/boost/geometry/algorithms/equals.hpp b/boost/geometry/algorithms/equals.hpp
index 7c709c808d..0f0bdde584 100644
--- a/boost/geometry/algorithms/equals.hpp
+++ b/boost/geometry/algorithms/equals.hpp
@@ -51,7 +51,8 @@
#include <boost/geometry/util/select_most_precise.hpp>
#include <boost/geometry/algorithms/detail/equals/collect_vectors.hpp>
-#include <boost/geometry/algorithms/detail/relate/relate.hpp>
+#include <boost/geometry/algorithms/relate.hpp>
+#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
#include <boost/geometry/views/detail/indexed_point_view.hpp>
@@ -181,9 +182,9 @@ struct equals_by_collection
template<typename Geometry1, typename Geometry2>
struct equals_by_relate
- : detail::relate::relate_base
+ : detail::relate::relate_impl
<
- detail::relate::static_mask_equals_type,
+ detail::de9im::static_mask_equals_type,
Geometry1,
Geometry2
>
@@ -371,7 +372,7 @@ struct equals<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
Geometry2 const& geometry2
)
{
- return apply_visitor(visitor(geometry2), geometry1);
+ return boost::apply_visitor(visitor(geometry2), geometry1);
}
};
@@ -400,7 +401,7 @@ struct equals<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2
)
{
- return apply_visitor(visitor(geometry1), geometry2);
+ return boost::apply_visitor(visitor(geometry1), geometry2);
}
};
@@ -430,7 +431,7 @@ struct equals<
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2
)
{
- return apply_visitor(visitor(), geometry1, geometry2);
+ return boost::apply_visitor(visitor(), geometry1, geometry2);
}
};
diff --git a/boost/geometry/algorithms/expand.hpp b/boost/geometry/algorithms/expand.hpp
index 9dc0a48e06..f41df53801 100644
--- a/boost/geometry/algorithms/expand.hpp
+++ b/boost/geometry/algorithms/expand.hpp
@@ -1,348 +1,26 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// Copyright (c) 2014 Samuel Debionne, Grenoble, France.
+// 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 Samuel Debionne, Grenoble, France.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
-// Use, modification and distribution is subject to the Boost Software License,
-// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// Distributed under 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_EXPAND_HPP
#define BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP
-
-#include <cstddef>
-
-#include <boost/numeric/conversion/cast.hpp>
-
-#include <boost/variant/apply_visitor.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/variant/variant_fwd.hpp>
-
-#include <boost/geometry/algorithms/not_implemented.hpp>
-#include <boost/geometry/core/coordinate_dimension.hpp>
-#include <boost/geometry/geometries/concepts/check.hpp>
-
-#include <boost/geometry/util/select_coordinate_type.hpp>
-
-#include <boost/geometry/strategies/compare.hpp>
-#include <boost/geometry/policies/compare.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace expand
-{
-
-
-template
-<
- typename StrategyLess, typename StrategyGreater,
- std::size_t Dimension, std::size_t DimensionCount
->
-struct point_loop
-{
- template <typename Box, typename Point>
- static inline void apply(Box& box, Point const& source)
- {
- typedef typename strategy::compare::detail::select_strategy
- <
- StrategyLess, 1, Point, Dimension
- >::type less_type;
-
- typedef typename strategy::compare::detail::select_strategy
- <
- StrategyGreater, -1, Point, Dimension
- >::type greater_type;
-
- typedef typename select_coordinate_type<Point, Box>::type coordinate_type;
-
- less_type less;
- greater_type greater;
-
- coordinate_type const coord = get<Dimension>(source);
-
- if (less(coord, get<min_corner, Dimension>(box)))
- {
- set<min_corner, Dimension>(box, coord);
- }
-
- if (greater(coord, get<max_corner, Dimension>(box)))
- {
- set<max_corner, Dimension>(box, coord);
- }
-
- point_loop
- <
- StrategyLess, StrategyGreater,
- Dimension + 1, DimensionCount
- >::apply(box, source);
- }
-};
-
-
-template
-<
- 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 StrategyLess, typename StrategyGreater,
- std::size_t Index,
- std::size_t Dimension, std::size_t DimensionCount
->
-struct indexed_loop
-{
- template <typename Box, typename Geometry>
- static inline void apply(Box& box, Geometry const& source)
- {
- typedef typename strategy::compare::detail::select_strategy
- <
- StrategyLess, 1, Box, Dimension
- >::type less_type;
-
- typedef typename strategy::compare::detail::select_strategy
- <
- StrategyGreater, -1, Box, Dimension
- >::type greater_type;
-
- typedef typename select_coordinate_type
- <
- Box,
- Geometry
- >::type coordinate_type;
-
- less_type less;
- greater_type greater;
-
- coordinate_type const coord = get<Index, Dimension>(source);
-
- if (less(coord, get<min_corner, Dimension>(box)))
- {
- set<min_corner, Dimension>(box, coord);
- }
-
- if (greater(coord, get<max_corner, Dimension>(box)))
- {
- set<max_corner, Dimension>(box, coord);
- }
-
- indexed_loop
- <
- StrategyLess, StrategyGreater,
- Index, Dimension + 1, DimensionCount
- >::apply(box, source);
- }
-};
-
-
-template
-<
- typename StrategyLess, typename StrategyGreater,
- std::size_t Index, std::size_t DimensionCount
->
-struct indexed_loop
- <
- StrategyLess, StrategyGreater,
- Index, DimensionCount, DimensionCount
- >
-{
- template <typename Box, typename Geometry>
- static inline void apply(Box&, Geometry const&) {}
-};
-
-
-
-// Changes a box such that the other box is also contained by the box
-template
-<
- typename StrategyLess, typename StrategyGreater
->
-struct expand_indexed
-{
- template <typename Box, typename Geometry>
- static inline void apply(Box& box, Geometry const& geometry)
- {
- indexed_loop
- <
- StrategyLess, StrategyGreater,
- 0, 0, dimension<Geometry>::type::value
- >::apply(box, geometry);
-
- indexed_loop
- <
- StrategyLess, StrategyGreater,
- 1, 0, dimension<Geometry>::type::value
- >::apply(box, geometry);
- }
-};
-
-}} // namespace detail::expand
-#endif // DOXYGEN_NO_DETAIL
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
-{
-
-template
-<
- typename GeometryOut, typename Geometry,
- typename StrategyLess = strategy::compare::default_strategy,
- typename StrategyGreater = strategy::compare::default_strategy,
- typename TagOut = typename tag<GeometryOut>::type,
- typename Tag = typename tag<Geometry>::type
->
-struct expand: not_implemented<TagOut, Tag>
-{};
-
-
-// Box + point -> new box containing also point
-template
-<
- typename BoxOut, typename Point,
- typename StrategyLess, typename StrategyGreater
->
-struct expand<BoxOut, Point, StrategyLess, StrategyGreater, box_tag, point_tag>
- : detail::expand::point_loop
- <
- StrategyLess, StrategyGreater,
- 0, dimension<Point>::type::value
- >
-{};
-
-
-// Box + box -> new box containing two input boxes
-template
-<
- typename BoxOut, typename BoxIn,
- typename StrategyLess, typename StrategyGreater
->
-struct expand<BoxOut, BoxIn, StrategyLess, StrategyGreater, box_tag, box_tag>
- : detail::expand::expand_indexed<StrategyLess, StrategyGreater>
-{};
-
-template
-<
- typename Box, typename Segment,
- typename StrategyLess, typename StrategyGreater
->
-struct expand<Box, Segment, StrategyLess, StrategyGreater, box_tag, segment_tag>
- : detail::expand::expand_indexed<StrategyLess, StrategyGreater>
-{};
-
-
-} // namespace dispatch
-#endif // DOXYGEN_NO_DISPATCH
-
-
-namespace resolve_variant {
-
-template <typename Geometry>
-struct expand
-{
- template <typename Box>
- static inline void apply(Box& box, Geometry const& geometry)
- {
- concept::check<Box>();
- concept::check<Geometry const>();
- concept::check_concepts_and_equal_dimensions<Box, Geometry const>();
-
- dispatch::expand<Box, Geometry>::apply(box, geometry);
- }
-};
-
-template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
-struct expand<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
-{
- template <typename Box>
- struct visitor: boost::static_visitor<void>
- {
- Box& m_box;
-
- visitor(Box& box) : m_box(box) {}
-
- template <typename Geometry>
- void operator()(Geometry const& geometry) const
- {
- return expand<Geometry>::apply(m_box, geometry);
- }
- };
-
- template <class Box>
- static inline void
- apply(Box& box,
- boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
- {
- return boost::apply_visitor(visitor<Box>(box), geometry);
- }
-};
-
-} // namespace resolve_variant
-
-
-/***
-*!
-\brief Expands a box using the extend (envelope) of another geometry (box, point)
-\ingroup expand
-\tparam Box type of the box
-\tparam Geometry of second geometry, to be expanded with the box
-\param box box to expand another geometry with, might be changed
-\param geometry other geometry
-\param strategy_less
-\param strategy_greater
-\note Strategy is currently ignored
- *
-template
-<
- typename Box, typename Geometry,
- typename StrategyLess, typename StrategyGreater
->
-inline void expand(Box& box, Geometry const& geometry,
- StrategyLess const& strategy_less,
- StrategyGreater const& strategy_greater)
-{
- concept::check_concepts_and_equal_dimensions<Box, Geometry const>();
-
- dispatch::expand<Box, Geometry>::apply(box, geometry);
-}
-***/
-
-
-/*!
-\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
-
-\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);
-}
-
-}} // namespace boost::geometry
+#include <boost/geometry/algorithms/detail/expand/interface.hpp>
+#include <boost/geometry/algorithms/detail/expand/implementation.hpp>
#endif // BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP
diff --git a/boost/geometry/algorithms/is_convex.hpp b/boost/geometry/algorithms/is_convex.hpp
new file mode 100644
index 0000000000..8feb48db6a
--- /dev/null
+++ b/boost/geometry/algorithms/is_convex.hpp
@@ -0,0 +1,160 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_IS_CONVEX_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_IS_CONVEX_HPP
+
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
+#include <boost/geometry/iterators/ever_circling_iterator.hpp>
+#include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
+#include <boost/geometry/views/detail/normalized_view.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace is_convex
+{
+
+struct ring_is_convex
+{
+ template <typename Ring>
+ static inline bool apply(Ring const& ring)
+ {
+ typedef typename geometry::point_type<Ring>::type point_type;
+ typedef typename strategy::side::services::default_strategy
+ <
+ typename cs_tag<point_type>::type
+ >::type side_strategy_type;
+
+ std::size_t n = boost::size(ring);
+ if (boost::size(ring) < core_detail::closure::minimum_ring_size
+ <
+ geometry::closure<Ring>::value
+ >::value)
+ {
+ // (Too) small rings are considered as non-concave, is convex
+ return true;
+ }
+
+ // Walk in clockwise direction, consider ring as closed
+ // (though closure is not important in this algorithm - any dupped
+ // point is skipped)
+ typedef detail::normalized_view<Ring const> view_type;
+ view_type view(ring);
+
+ typedef geometry::ever_circling_range_iterator<view_type const> it_type;
+ it_type previous(view);
+ it_type current(view);
+ current++;
+
+ std::size_t index = 1;
+ while (equals::equals_point_point(*current, *previous) && index < n)
+ {
+ current++;
+ index++;
+ }
+
+ if (index == n)
+ {
+ // All points are apparently equal
+ return true;
+ }
+
+ it_type next = current;
+ next++;
+ while (equals::equals_point_point(*current, *next))
+ {
+ next++;
+ }
+
+ // We have now three different points on the ring
+ // Walk through all points, use a counter because of the ever-circling
+ // iterator
+ for (std::size_t i = 0; i < n; i++)
+ {
+ int const side = side_strategy_type::apply(*previous, *current, *next);
+ if (side == 1)
+ {
+ // Next is on the left side of clockwise ring:
+ // the piece is not convex
+ return false;
+ }
+
+ previous = current;
+ current = next;
+
+ // Advance next to next different point
+ // (because there are non-equal points, this loop is not infinite)
+ next++;
+ while (equals::equals_point_point(*current, *next))
+ {
+ next++;
+ }
+ }
+ return true;
+ }
+};
+
+
+}} // namespace detail::is_convex
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Geometry,
+ typename Tag = typename tag<Geometry>::type
+>
+struct is_convex : not_implemented<Tag>
+{};
+
+template <typename Box>
+struct is_convex<Box, box_tag>
+{
+ static inline bool apply(Box const& )
+ {
+ // Any box is convex (TODO: consider spherical boxes)
+ return true;
+ }
+};
+
+template <typename Box>
+struct is_convex<Box, ring_tag> : detail::is_convex::ring_is_convex
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+// TODO: variants
+
+// TODO: documentation / qbk
+template<typename Geometry>
+inline bool is_convex(Geometry const& geometry)
+{
+ return dispatch::is_convex<Geometry>::apply(geometry);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_IS_CONVEX_HPP
diff --git a/boost/geometry/algorithms/is_empty.hpp b/boost/geometry/algorithms/is_empty.hpp
new file mode 100644
index 0000000000..02c295eaba
--- /dev/null
+++ b/boost/geometry/algorithms/is_empty.hpp
@@ -0,0 +1,207 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_IS_EMPTY_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_IS_EMPTY_HPP
+
+#include <boost/range.hpp>
+
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
+
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace is_empty
+{
+
+struct always_not_empty
+{
+ template <typename Geometry>
+ static inline bool apply(Geometry const&)
+ {
+ return false;
+ }
+};
+
+struct range_is_empty
+{
+ template <typename Range>
+ static inline bool apply(Range const& range)
+ {
+ return boost::empty(range);
+ }
+};
+
+class polygon_is_empty
+{
+ template <typename InteriorRings>
+ static inline bool check_interior_rings(InteriorRings const& interior_rings)
+ {
+ return check_iterator_range
+ <
+ range_is_empty, true // allow empty range
+ >::apply(boost::begin(interior_rings), boost::end(interior_rings));
+ }
+
+public:
+ template <typename Polygon>
+ static inline bool apply(Polygon const& polygon)
+ {
+ return boost::empty(exterior_ring(polygon))
+ && check_interior_rings(interior_rings(polygon));
+ }
+};
+
+template <typename Policy = range_is_empty>
+struct multi_is_empty
+{
+ template <typename MultiGeometry>
+ static inline bool apply(MultiGeometry const& multigeometry)
+ {
+ return check_iterator_range
+ <
+ Policy, true // allow empty range
+ >::apply(boost::begin(multigeometry), boost::end(multigeometry));
+ }
+
+};
+
+}} // namespace detail::is_empty
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Geometry, typename Tag = typename tag<Geometry>::type>
+struct is_empty : not_implemented<Tag>
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, point_tag>
+ : detail::is_empty::always_not_empty
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, box_tag>
+ : detail::is_empty::always_not_empty
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, segment_tag>
+ : detail::is_empty::always_not_empty
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, linestring_tag>
+ : detail::is_empty::range_is_empty
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, ring_tag>
+ : detail::is_empty::range_is_empty
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, polygon_tag>
+ : detail::is_empty::polygon_is_empty
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, multi_point_tag>
+ : detail::is_empty::range_is_empty
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, multi_linestring_tag>
+ : detail::is_empty::multi_is_empty<>
+{};
+
+template <typename Geometry>
+struct is_empty<Geometry, multi_polygon_tag>
+ : detail::is_empty::multi_is_empty<detail::is_empty::polygon_is_empty>
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+namespace resolve_variant
+{
+
+template <typename Geometry>
+struct is_empty
+{
+ static inline bool apply(Geometry const& geometry)
+ {
+ concept::check<Geometry const>();
+
+ return dispatch::is_empty<Geometry>::apply(geometry);
+ }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct is_empty<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ struct visitor : boost::static_visitor<bool>
+ {
+ template <typename Geometry>
+ inline bool operator()(Geometry const& geometry) const
+ {
+ return is_empty<Geometry>::apply(geometry);
+ }
+ };
+
+ static bool
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
+ {
+ return boost::apply_visitor(visitor(), geometry);
+ }
+};
+
+} // namespace resolve_variant
+
+
+/*!
+\brief \brief_check{is the empty set}
+\ingroup is_empty
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry
+\return \return_check{is the empty set}
+
+\qbk{[include reference/algorithms/is_empty.qbk]}
+*/
+template <typename Geometry>
+inline bool is_empty(Geometry const& geometry)
+{
+ return resolve_variant::is_empty<Geometry>::apply(geometry);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_IS_EMPTY_HPP
diff --git a/boost/geometry/algorithms/length.hpp b/boost/geometry/algorithms/length.hpp
index fad17ade46..58324bcc80 100644
--- a/boost/geometry/algorithms/length.hpp
+++ b/boost/geometry/algorithms/length.hpp
@@ -229,7 +229,7 @@ struct length<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
Strategy const& strategy
)
{
- return apply_visitor(visitor<Strategy>(strategy), geometry);
+ return boost::apply_visitor(visitor<Strategy>(strategy), geometry);
}
};
diff --git a/boost/geometry/algorithms/overlaps.hpp b/boost/geometry/algorithms/overlaps.hpp
index f724a544fd..96310d6cb5 100644
--- a/boost/geometry/algorithms/overlaps.hpp
+++ b/boost/geometry/algorithms/overlaps.hpp
@@ -28,7 +28,8 @@
#include <boost/geometry/geometries/concepts/check.hpp>
-#include <boost/geometry/algorithms/detail/relate/relate.hpp>
+#include <boost/geometry/algorithms/relate.hpp>
+#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
namespace boost { namespace geometry
{
@@ -149,9 +150,9 @@ template
typename Tag2 = typename tag<Geometry2>::type
>
struct overlaps
- : detail::relate::relate_base
+ : detail::relate::relate_impl
<
- detail::relate::static_mask_overlaps_type,
+ detail::de9im::static_mask_overlaps_type,
Geometry1,
Geometry2
>
diff --git a/boost/geometry/algorithms/relate.hpp b/boost/geometry/algorithms/relate.hpp
new file mode 100644
index 0000000000..34733ec596
--- /dev/null
+++ b/boost/geometry/algorithms/relate.hpp
@@ -0,0 +1,17 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015 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_RELATE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_RELATE_HPP
+
+#include <boost/geometry/algorithms/detail/relate/interface.hpp>
+#include <boost/geometry/algorithms/detail/relate/implementation.hpp>
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_RELATE_HPP
diff --git a/boost/geometry/algorithms/relation.hpp b/boost/geometry/algorithms/relation.hpp
new file mode 100644
index 0000000000..c3cf2f99f8
--- /dev/null
+++ b/boost/geometry/algorithms/relation.hpp
@@ -0,0 +1,17 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015 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_RELATION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_RELATION_HPP
+
+#include <boost/geometry/algorithms/detail/relation/interface.hpp>
+#include <boost/geometry/algorithms/detail/relation/implementation.hpp>
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_RELATION_HPP
diff --git a/boost/geometry/algorithms/simplify.hpp b/boost/geometry/algorithms/simplify.hpp
index 0047546718..9dd87f61a9 100644
--- a/boost/geometry/algorithms/simplify.hpp
+++ b/boost/geometry/algorithms/simplify.hpp
@@ -491,7 +491,7 @@ inline void simplify(Geometry const& geometry, Geometry& out,
{
concept::check<Geometry>();
- simplify(geometry, out, max_distance, default_strategy());
+ geometry::simplify(geometry, out, max_distance, default_strategy());
}
diff --git a/boost/geometry/algorithms/sym_difference.hpp b/boost/geometry/algorithms/sym_difference.hpp
index de34c9c7b0..6c49ca634c 100644
--- a/boost/geometry/algorithms/sym_difference.hpp
+++ b/boost/geometry/algorithms/sym_difference.hpp
@@ -1,6 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// 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.
+
+// Contributed and/or modified by Menelaos Karavelas, 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
@@ -10,9 +15,12 @@
#define BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP
#include <algorithm>
-
+#include <iterator>
+#include <vector>
#include <boost/geometry/algorithms/intersection.hpp>
+#include <boost/geometry/algorithms/union.hpp>
+#include <boost/geometry/geometries/multi_polygon.hpp>
namespace boost { namespace geometry
@@ -23,6 +31,177 @@ namespace detail { namespace sym_difference
{
+template <typename GeometryOut>
+struct compute_difference
+{
+ template
+ <
+ typename Geometry1,
+ typename Geometry2,
+ typename RobustPolicy,
+ typename OutputIterator,
+ typename Strategy
+ >
+ static inline OutputIterator apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
+ OutputIterator out,
+ Strategy const& strategy)
+ {
+ return geometry::dispatch::intersection_insert
+ <
+ Geometry1,
+ Geometry2,
+ GeometryOut,
+ overlay_difference,
+ geometry::detail::overlay::do_reverse
+ <
+ geometry::point_order<Geometry1>::value
+ >::value,
+ geometry::detail::overlay::do_reverse
+ <
+ geometry::point_order<Geometry2>::value, true
+ >::value
+ >::apply(geometry1, geometry2, robust_policy, out, strategy);
+ }
+};
+
+
+
+template <typename GeometryOut, typename Geometry1, typename Geometry2>
+struct sym_difference_generic
+{
+ template
+ <
+ typename RobustPolicy,
+ typename OutputIterator,
+ typename Strategy
+ >
+ static inline OutputIterator apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
+ OutputIterator out,
+ Strategy const& strategy)
+ {
+ out = compute_difference
+ <
+ GeometryOut
+ >::apply(geometry1, geometry2, robust_policy, out, strategy);
+
+ return compute_difference
+ <
+ GeometryOut
+ >::apply(geometry2, geometry1, robust_policy, out, strategy);
+ }
+};
+
+
+template <typename GeometryOut, typename Areal1, typename Areal2>
+struct sym_difference_areal_areal
+{
+ template
+ <
+ typename RobustPolicy,
+ typename OutputIterator,
+ typename Strategy
+ >
+ static inline OutputIterator apply(Areal1 const& areal1,
+ Areal2 const& areal2,
+ RobustPolicy const& robust_policy,
+ OutputIterator out,
+ Strategy const& strategy)
+ {
+ typedef geometry::model::multi_polygon
+ <
+ GeometryOut
+ > helper_geometry_type;
+
+ helper_geometry_type diff12, diff21;
+
+ std::back_insert_iterator<helper_geometry_type> oit12(diff12);
+ std::back_insert_iterator<helper_geometry_type> oit21(diff21);
+
+ compute_difference
+ <
+ GeometryOut
+ >::apply(areal1, areal2, robust_policy, oit12, strategy);
+
+ compute_difference
+ <
+ GeometryOut
+ >::apply(areal2, areal1, robust_policy, oit21, strategy);
+
+ return geometry::dispatch::union_insert
+ <
+ helper_geometry_type,
+ helper_geometry_type,
+ GeometryOut
+ >::apply(diff12, diff21, robust_policy, out, strategy);
+ }
+};
+
+
+}} // namespace detail::sym_difference
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename GeometryOut,
+ typename TagIn1 = typename geometry::tag_cast
+ <
+ typename tag<Geometry1>::type, areal_tag
+ >::type,
+ typename TagIn2 = typename geometry::tag_cast
+ <
+ typename tag<Geometry2>::type, areal_tag
+ >::type,
+ typename TagOut = typename geometry::tag<GeometryOut>::type
+>
+struct sym_difference_insert
+ : detail::sym_difference::sym_difference_generic
+ <
+ GeometryOut, Geometry1, Geometry2
+ >
+{};
+
+
+template
+<
+ typename Areal1,
+ typename Areal2,
+ typename GeometryOut,
+ typename TagOut
+>
+struct sym_difference_insert
+ <
+ Areal1, Areal2, GeometryOut,
+ areal_tag, areal_tag, TagOut
+ > : detail::sym_difference::sym_difference_areal_areal
+ <
+ GeometryOut, Areal1, Areal2
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace sym_difference
+{
+
+
/*!
\brief \brief_calc2{symmetric difference} \brief_strategy
@@ -60,24 +239,10 @@ inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
concept::check<Geometry2 const>();
concept::check<GeometryOut>();
- out = geometry::dispatch::intersection_insert
+ return dispatch::sym_difference_insert
<
- Geometry1, Geometry2,
- GeometryOut,
- overlay_difference,
- geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
- geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, true>::value
+ Geometry1, Geometry2, GeometryOut
>::apply(geometry1, geometry2, robust_policy, out, strategy);
- out = geometry::dispatch::intersection_insert
- <
- Geometry2, Geometry1,
- GeometryOut,
- overlay_difference,
- geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
- geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value, true>::value,
- geometry::detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value
- >::apply(geometry2, geometry1, robust_policy, out, strategy);
- return out;
}
diff --git a/boost/geometry/algorithms/touches.hpp b/boost/geometry/algorithms/touches.hpp
index 48334d7255..d6f0df3c74 100644
--- a/boost/geometry/algorithms/touches.hpp
+++ b/boost/geometry/algorithms/touches.hpp
@@ -37,7 +37,8 @@
#include <boost/geometry/algorithms/detail/sub_range.hpp>
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
-#include <boost/geometry/algorithms/detail/relate/relate.hpp>
+#include <boost/geometry/algorithms/relate.hpp>
+#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
namespace boost { namespace geometry
{
@@ -67,7 +68,7 @@ struct box_box_loop
coordinate_type2 const& max2 = get<max_corner, Dimension>(b2);
// TODO assert or exception?
- //BOOST_ASSERT(min1 <= max1 && min2 <= max2);
+ //BOOST_GEOMETRY_ASSERT(min1 <= max1 && min2 <= max2);
if ( max1 < min2 || max2 < min1 )
{
@@ -349,9 +350,9 @@ struct touches<Box1, Box2, box_tag, box_tag, areal_tag, areal_tag, false>
template <typename Linear1, typename Linear2, typename Tag1, typename Tag2>
struct touches<Linear1, Linear2, Tag1, Tag2, linear_tag, linear_tag, false>
- : detail::relate::relate_base
+ : detail::relate::relate_impl
<
- detail::relate::static_mask_touches_type,
+ detail::de9im::static_mask_touches_type,
Linear1,
Linear2
>
@@ -361,9 +362,9 @@ struct touches<Linear1, Linear2, Tag1, Tag2, linear_tag, linear_tag, false>
template <typename Linear, typename Areal, typename Tag1, typename Tag2>
struct touches<Linear, Areal, Tag1, Tag2, linear_tag, areal_tag, false>
- : detail::relate::relate_base
+ : detail::relate::relate_impl
<
- detail::relate::static_mask_touches_type,
+ detail::de9im::static_mask_touches_type,
Linear,
Areal
>
@@ -372,9 +373,9 @@ struct touches<Linear, Areal, Tag1, Tag2, linear_tag, areal_tag, false>
// A/L
template <typename Linear, typename Areal, typename Tag1, typename Tag2>
struct touches<Linear, Areal, Tag1, Tag2, linear_tag, areal_tag, true>
- : detail::relate::relate_base
+ : detail::relate::relate_impl
<
- detail::relate::static_mask_touches_type,
+ detail::de9im::static_mask_touches_type,
Areal,
Linear
>
diff --git a/boost/geometry/algorithms/transform.hpp b/boost/geometry/algorithms/transform.hpp
index 357263a4ea..c7f3bd6cbb 100644
--- a/boost/geometry/algorithms/transform.hpp
+++ b/boost/geometry/algorithms/transform.hpp
@@ -70,9 +70,9 @@ struct transform_box
typedef typename point_type<Box2>::type point_type2;
point_type1 lower_left, upper_right;
- detail::assign::assign_box_2d_corner<min_corner, min_corner>(
+ geometry::detail::assign::assign_box_2d_corner<min_corner, min_corner>(
b1, lower_left);
- detail::assign::assign_box_2d_corner<max_corner, max_corner>(
+ geometry::detail::assign::assign_box_2d_corner<max_corner, max_corner>(
b1, upper_right);
point_type2 p1, p2;
@@ -88,10 +88,10 @@ struct transform_box
if (x1 > x2) { std::swap(x1, x2); }
if (y1 > y2) { std::swap(y1, y2); }
- set<min_corner, 0>(b2, x1);
- set<min_corner, 1>(b2, y1);
- set<max_corner, 0>(b2, x2);
- set<max_corner, 1>(b2, y2);
+ geometry::set<min_corner, 0>(b2, x1);
+ geometry::set<min_corner, 1>(b2, y1);
+ geometry::set<max_corner, 0>(b2, x2);
+ geometry::set<max_corner, 1>(b2, y2);
return true;
}
@@ -161,8 +161,8 @@ struct transform_polygon
geometry::clear(poly2);
- if (!transform_range_out<point2_type>(exterior_ring(poly1),
- std::back_inserter(exterior_ring(poly2)), strategy))
+ if (!transform_range_out<point2_type>(geometry::exterior_ring(poly1),
+ std::back_inserter(geometry::exterior_ring(poly2)), strategy))
{
return false;
}
@@ -174,12 +174,13 @@ struct transform_polygon
<
typename traits::interior_mutable_type<Polygon2>::type
>::type
- >::apply(interior_rings(poly2), num_interior_rings(poly1));
+ >::apply(geometry::interior_rings(poly2),
+ geometry::num_interior_rings(poly1));
- typename interior_return_type<Polygon1 const>::type
- rings1 = interior_rings(poly1);
- typename interior_return_type<Polygon2>::type
- rings2 = interior_rings(poly2);
+ typename geometry::interior_return_type<Polygon1 const>::type
+ rings1 = geometry::interior_rings(poly1);
+ typename geometry::interior_return_type<Polygon2>::type
+ rings2 = geometry::interior_rings(poly2);
typename detail::interior_iterator<Polygon1 const>::type
it1 = boost::begin(rings1);
@@ -424,7 +425,7 @@ struct transform<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
Strategy const& strategy
)
{
- return apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
+ return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
}
};
@@ -469,7 +470,7 @@ inline bool transform(Geometry1 const& geometry1, Geometry2& geometry2,
template <typename Geometry1, typename Geometry2>
inline bool transform(Geometry1 const& geometry1, Geometry2& geometry2)
{
- return transform(geometry1, geometry2, default_strategy());
+ return geometry::transform(geometry1, geometry2, default_strategy());
}
diff --git a/boost/geometry/algorithms/within.hpp b/boost/geometry/algorithms/within.hpp
index 9f2b6fedf7..35f9396ba6 100644
--- a/boost/geometry/algorithms/within.hpp
+++ b/boost/geometry/algorithms/within.hpp
@@ -358,9 +358,9 @@ struct within<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
Geometry2 const& m_geometry2;
Strategy const& m_strategy;
- visitor(Geometry2 const& geometry2, Strategy const& strategy):
- m_geometry2(geometry2),
- m_strategy(strategy)
+ visitor(Geometry2 const& geometry2, Strategy const& strategy)
+ : m_geometry2(geometry2)
+ , m_strategy(strategy)
{}
template <typename Geometry1>
@@ -378,10 +378,8 @@ struct within<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
Geometry2 const& geometry2,
Strategy const& strategy)
{
- return boost::apply_visitor(
- visitor<Strategy>(geometry2, strategy),
- geometry1
- );
+ return boost::apply_visitor(visitor<Strategy>(geometry2, strategy),
+ geometry1);
}
};
@@ -394,9 +392,9 @@ struct within<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
Geometry1 const& m_geometry1;
Strategy const& m_strategy;
- visitor(Geometry1 const& geometry1, Strategy const& strategy):
- m_geometry1(geometry1),
- m_strategy(strategy)
+ visitor(Geometry1 const& geometry1, Strategy const& strategy)
+ : m_geometry1(geometry1)
+ , m_strategy(strategy)
{}
template <typename Geometry2>
@@ -414,9 +412,8 @@ struct within<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
Strategy const& strategy)
{
- return boost::apply_visitor(
- visitor<Strategy>(geometry1, strategy),
- geometry2
+ return boost::apply_visitor(visitor<Strategy>(geometry1, strategy),
+ geometry2
);
}
};
@@ -453,10 +450,9 @@ struct within<
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
Strategy const& strategy)
{
- return boost::apply_visitor(
- visitor<Strategy>(strategy),
- geometry1, geometry2
- );
+ return boost::apply_visitor(visitor<Strategy>(strategy),
+ geometry1,
+ geometry2);
}
};