summaryrefslogtreecommitdiff
path: root/boost/geometry
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry')
-rw-r--r--boost/geometry/algorithms/area.hpp9
-rw-r--r--boost/geometry/algorithms/buffer.hpp42
-rw-r--r--boost/geometry/algorithms/densify.hpp7
-rwxr-xr-xboost/geometry/algorithms/detail/buffer/buffer_box.hpp62
-rw-r--r--boost/geometry/algorithms/detail/buffer/buffer_policies.hpp15
-rw-r--r--boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp152
-rw-r--r--boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp148
-rw-r--r--boost/geometry/algorithms/detail/buffer/turn_in_original_visitor.hpp12
-rw-r--r--boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp426
-rw-r--r--boost/geometry/algorithms/detail/covered_by/implementation.hpp6
-rw-r--r--boost/geometry/algorithms/detail/covered_by/interface.hpp12
-rw-r--r--boost/geometry/algorithms/detail/disjoint/areal_areal.hpp101
-rw-r--r--boost/geometry/algorithms/detail/disjoint/box_box.hpp136
-rw-r--r--boost/geometry/algorithms/detail/disjoint/linear_areal.hpp7
-rw-r--r--boost/geometry/algorithms/detail/disjoint/linear_linear.hpp12
-rw-r--r--boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp42
-rw-r--r--boost/geometry/algorithms/detail/disjoint/point_box.hpp15
-rw-r--r--boost/geometry/algorithms/detail/disjoint/point_point.hpp202
-rw-r--r--boost/geometry/algorithms/detail/disjoint/segment_box.hpp98
-rw-r--r--boost/geometry/algorithms/detail/distance/interface.hpp13
-rw-r--r--boost/geometry/algorithms/detail/distance/point_to_geometry.hpp20
-rw-r--r--boost/geometry/algorithms/detail/distance/segment_to_box.hpp52
-rw-r--r--boost/geometry/algorithms/detail/envelope/areal.hpp70
-rw-r--r--boost/geometry/algorithms/detail/envelope/box.hpp148
-rw-r--r--boost/geometry/algorithms/detail/envelope/interface.hpp31
-rw-r--r--boost/geometry/algorithms/detail/envelope/linear.hpp77
-rw-r--r--boost/geometry/algorithms/detail/envelope/multipoint.hpp353
-rw-r--r--boost/geometry/algorithms/detail/envelope/point.hpp90
-rw-r--r--boost/geometry/algorithms/detail/envelope/range.hpp112
-rw-r--r--boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp29
-rw-r--r--boost/geometry/algorithms/detail/envelope/segment.hpp410
-rw-r--r--boost/geometry/algorithms/detail/equals/implementation.hpp30
-rw-r--r--boost/geometry/algorithms/detail/equals/point_point.hpp16
-rw-r--r--boost/geometry/algorithms/detail/expand/box.hpp99
-rw-r--r--boost/geometry/algorithms/detail/expand/indexed.hpp24
-rw-r--r--boost/geometry/algorithms/detail/expand/interface.hpp27
-rw-r--r--boost/geometry/algorithms/detail/expand/point.hpp259
-rw-r--r--boost/geometry/algorithms/detail/expand/segment.hpp112
-rw-r--r--boost/geometry/algorithms/detail/extreme_points.hpp5
-rw-r--r--boost/geometry/algorithms/detail/get_left_turns.hpp9
-rw-r--r--boost/geometry/algorithms/detail/get_max_size.hpp7
-rw-r--r--boost/geometry/algorithms/detail/is_valid/complement_graph.hpp6
-rw-r--r--boost/geometry/algorithms/detail/is_valid/debug_complement_graph.hpp5
-rw-r--r--boost/geometry/algorithms/detail/is_valid/debug_validity_phase.hpp6
-rw-r--r--boost/geometry/algorithms/detail/is_valid/has_invalid_coordinate.hpp10
-rw-r--r--boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp14
-rw-r--r--boost/geometry/algorithms/detail/is_valid/multipolygon.hpp9
-rw-r--r--boost/geometry/algorithms/detail/is_valid/polygon.hpp35
-rw-r--r--boost/geometry/algorithms/detail/is_valid/ring.hpp4
-rw-r--r--boost/geometry/algorithms/detail/normalize.hpp285
-rw-r--r--boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp29
-rw-r--r--boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp33
-rw-r--r--boost/geometry/algorithms/detail/overlay/assign_parents.hpp16
-rw-r--r--boost/geometry/algorithms/detail/overlay/check_enrich.hpp16
-rw-r--r--boost/geometry/algorithms/detail/overlay/clip_linestring.hpp21
-rw-r--r--boost/geometry/algorithms/detail/overlay/convert_ring.hpp15
-rw-r--r--boost/geometry/algorithms/detail/overlay/copy_segments.hpp26
-rw-r--r--boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp9
-rw-r--r--boost/geometry/algorithms/detail/overlay/follow.hpp24
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp20
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turn_info.hpp337
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp199
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp427
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp306
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp152
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turns.hpp344
-rw-r--r--boost/geometry/algorithms/detail/overlay/linear_linear.hpp12
-rw-r--r--boost/geometry/algorithms/detail/overlay/overlay.hpp6
-rw-r--r--boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp14
-rw-r--r--boost/geometry/algorithms/detail/overlay/select_rings.hpp1
-rw-r--r--boost/geometry/algorithms/detail/overlay/self_turn_points.hpp26
-rw-r--r--boost/geometry/algorithms/detail/overlay/stream_info.hpp19
-rw-r--r--boost/geometry/algorithms/detail/overlay/traversal.hpp278
-rw-r--r--boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp49
-rw-r--r--boost/geometry/algorithms/detail/overlay/traversal_switch_detector.hpp6
-rw-r--r--boost/geometry/algorithms/detail/point_on_border.hpp160
-rw-r--r--boost/geometry/algorithms/detail/relate/areal_areal.hpp34
-rw-r--r--boost/geometry/algorithms/detail/relate/boundary_checker.hpp41
-rw-r--r--boost/geometry/algorithms/detail/relate/follow_helpers.hpp23
-rw-r--r--boost/geometry/algorithms/detail/relate/linear_areal.hpp89
-rw-r--r--boost/geometry/algorithms/detail/relate/linear_linear.hpp50
-rw-r--r--boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp97
-rw-r--r--boost/geometry/algorithms/detail/relate/point_geometry.hpp10
-rw-r--r--boost/geometry/algorithms/detail/relate/point_point.hpp20
-rw-r--r--boost/geometry/algorithms/detail/relate/result.hpp5
-rw-r--r--boost/geometry/algorithms/detail/relate/topology_check.hpp62
-rw-r--r--boost/geometry/algorithms/detail/relate/turns.hpp6
-rw-r--r--boost/geometry/algorithms/detail/sections/section_box_policies.hpp12
-rw-r--r--boost/geometry/algorithms/detail/sections/section_functions.hpp10
-rw-r--r--boost/geometry/algorithms/detail/sections/sectionalize.hpp98
-rw-r--r--boost/geometry/algorithms/detail/sub_range.hpp16
-rw-r--r--boost/geometry/algorithms/detail/within/implementation.hpp6
-rw-r--r--boost/geometry/algorithms/detail/within/interface.hpp12
-rw-r--r--boost/geometry/algorithms/detail/within/point_in_geometry.hpp57
-rw-r--r--boost/geometry/algorithms/discrete_frechet_distance.hpp69
-rw-r--r--boost/geometry/algorithms/discrete_hausdorff_distance.hpp35
-rw-r--r--boost/geometry/algorithms/dispatch/disjoint.hpp5
-rw-r--r--boost/geometry/algorithms/dispatch/distance.hpp8
-rw-r--r--boost/geometry/algorithms/dispatch/envelope.hpp8
-rw-r--r--boost/geometry/algorithms/dispatch/expand.hpp8
-rw-r--r--boost/geometry/algorithms/is_convex.hpp14
-rw-r--r--boost/geometry/algorithms/line_interpolate.hpp411
-rw-r--r--boost/geometry/algorithms/simplify.hpp23
-rw-r--r--boost/geometry/algorithms/union.hpp9
-rw-r--r--boost/geometry/core/config.hpp26
-rw-r--r--boost/geometry/core/cs.hpp155
-rw-r--r--boost/geometry/core/tags.hpp7
-rw-r--r--boost/geometry/formulas/area_formulas.hpp1
-rw-r--r--boost/geometry/formulas/differential_quantities.hpp7
-rw-r--r--boost/geometry/formulas/eccentricity_sqr.hpp6
-rw-r--r--boost/geometry/formulas/interpolate_point_spherical.hpp107
-rw-r--r--boost/geometry/formulas/karney_direct.hpp25
-rw-r--r--boost/geometry/formulas/meridian_direct.hpp10
-rw-r--r--boost/geometry/formulas/meridian_segment.hpp4
-rw-r--r--boost/geometry/formulas/quarter_meridian.hpp7
-rw-r--r--boost/geometry/formulas/spherical.hpp6
-rw-r--r--boost/geometry/formulas/thomas_direct.hpp7
-rw-r--r--boost/geometry/formulas/vincenty_direct.hpp7
-rw-r--r--boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp11
-rw-r--r--boost/geometry/geometries/adapted/boost_tuple.hpp6
-rw-r--r--boost/geometry/geometries/adapted/std_array.hpp15
-rw-r--r--boost/geometry/geometries/concepts/multi_point_concept.hpp1
-rw-r--r--boost/geometry/geometries/helper_geometry.hpp59
-rw-r--r--boost/geometry/geometries/variant.hpp9
-rw-r--r--boost/geometry/geometry.hpp1
-rw-r--r--boost/geometry/index/detail/algorithms/intersection_content.hpp9
-rw-r--r--boost/geometry/index/detail/meta.hpp67
-rw-r--r--boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp39
-rw-r--r--boost/geometry/index/indexable.hpp207
-rw-r--r--boost/geometry/index/rtree.hpp30
-rw-r--r--boost/geometry/io/wkt/read.hpp19
-rw-r--r--boost/geometry/io/wkt/write.hpp17
-rw-r--r--boost/geometry/iterators/detail/point_iterator/iterator_type.hpp4
-rw-r--r--boost/geometry/policies/robustness/get_rescale_policy.hpp7
-rw-r--r--boost/geometry/policies/robustness/rescale_policy.hpp5
-rw-r--r--boost/geometry/srs/projections/dpar.hpp7
-rw-r--r--boost/geometry/srs/projections/impl/aasincos.hpp2
-rw-r--r--boost/geometry/srs/projections/impl/dms_parser.hpp4
-rw-r--r--boost/geometry/srs/projections/impl/pj_apply_gridshift.hpp10
-rw-r--r--boost/geometry/srs/projections/impl/pj_apply_gridshift_shared.hpp6
-rw-r--r--boost/geometry/srs/projections/impl/pj_datum_set.hpp10
-rw-r--r--boost/geometry/srs/projections/impl/pj_ellps.hpp2
-rw-r--r--boost/geometry/srs/projections/impl/pj_gauss.hpp3
-rw-r--r--boost/geometry/srs/projections/impl/pj_gridinfo.hpp15
-rw-r--r--boost/geometry/srs/projections/impl/pj_gridlist.hpp3
-rw-r--r--boost/geometry/srs/projections/impl/pj_gridlist_shared.hpp7
-rw-r--r--boost/geometry/srs/projections/impl/pj_mlfn.hpp2
-rw-r--r--boost/geometry/srs/projections/impl/pj_phi2.hpp2
-rw-r--r--boost/geometry/srs/projections/impl/pj_transform.hpp1
-rw-r--r--boost/geometry/srs/projections/impl/proj_mdist.hpp2
-rw-r--r--boost/geometry/srs/projections/par_data.hpp12
-rw-r--r--boost/geometry/srs/projections/proj/aeqd.hpp12
-rw-r--r--boost/geometry/srs/projections/proj/airy.hpp7
-rw-r--r--boost/geometry/srs/projections/proj/aitoff.hpp7
-rw-r--r--boost/geometry/srs/projections/proj/bipc.hpp10
-rw-r--r--boost/geometry/srs/projections/proj/bonne.hpp10
-rw-r--r--boost/geometry/srs/projections/proj/cea.hpp7
-rw-r--r--boost/geometry/srs/projections/proj/chamb.hpp8
-rw-r--r--boost/geometry/srs/projections/proj/eqc.hpp3
-rw-r--r--boost/geometry/srs/projections/proj/eqdc.hpp10
-rw-r--r--boost/geometry/srs/projections/proj/etmerc.hpp7
-rw-r--r--boost/geometry/srs/projections/proj/fouc_s.hpp9
-rw-r--r--boost/geometry/srs/projections/proj/gn_sinu.hpp9
-rw-r--r--boost/geometry/srs/projections/proj/hammer.hpp3
-rw-r--r--boost/geometry/srs/projections/proj/healpix.hpp7
-rw-r--r--boost/geometry/srs/projections/proj/imw_p.hpp7
-rw-r--r--boost/geometry/srs/projections/proj/isea.hpp6
-rw-r--r--boost/geometry/srs/projections/proj/krovak.hpp3
-rw-r--r--boost/geometry/srs/projections/proj/labrd.hpp3
-rw-r--r--boost/geometry/srs/projections/proj/lagrng.hpp7
-rw-r--r--boost/geometry/srs/projections/proj/lcc.hpp9
-rw-r--r--boost/geometry/srs/projections/proj/loxim.hpp7
-rw-r--r--boost/geometry/srs/projections/proj/lsat.hpp9
-rw-r--r--boost/geometry/srs/projections/proj/merc.hpp7
-rw-r--r--boost/geometry/srs/projections/proj/nsper.hpp9
-rw-r--r--boost/geometry/srs/projections/proj/ob_tran.hpp8
-rw-r--r--boost/geometry/srs/projections/proj/ocea.hpp3
-rw-r--r--boost/geometry/srs/projections/proj/oea.hpp5
-rw-r--r--boost/geometry/srs/projections/proj/omerc.hpp3
-rw-r--r--boost/geometry/srs/projections/proj/rpoly.hpp3
-rw-r--r--boost/geometry/srs/projections/proj/sconics.hpp3
-rw-r--r--boost/geometry/srs/projections/proj/stere.hpp3
-rw-r--r--boost/geometry/srs/projections/proj/tpeqd.hpp5
-rw-r--r--boost/geometry/srs/projections/proj/urm5.hpp5
-rw-r--r--boost/geometry/srs/projections/proj/urmfps.hpp5
-rw-r--r--boost/geometry/srs/projections/proj/wag3.hpp3
-rw-r--r--boost/geometry/srs/projections/proj/wink1.hpp3
-rw-r--r--boost/geometry/srs/projections/proj/wink2.hpp3
-rw-r--r--boost/geometry/srs/projections/shared_grids.hpp23
-rw-r--r--boost/geometry/srs/shared_grids.hpp6
-rw-r--r--boost/geometry/srs/transformation.hpp12
-rw-r--r--boost/geometry/strategies/agnostic/hull_graham_andrew.hpp18
-rw-r--r--boost/geometry/strategies/agnostic/point_in_box_by_side.hpp18
-rw-r--r--boost/geometry/strategies/agnostic/point_in_point.hpp69
-rw-r--r--boost/geometry/strategies/agnostic/point_in_poly_oriented_winding.hpp2
-rw-r--r--boost/geometry/strategies/cartesian/area.hpp5
-rw-r--r--boost/geometry/strategies/cartesian/azimuth.hpp4
-rw-r--r--boost/geometry/strategies/cartesian/buffer_end_flat.hpp12
-rw-r--r--boost/geometry/strategies/cartesian/buffer_point_circle.hpp13
-rw-r--r--boost/geometry/strategies/cartesian/buffer_point_square.hpp15
-rw-r--r--boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp5
-rw-r--r--boost/geometry/strategies/cartesian/densify.hpp1
-rw-r--r--boost/geometry/strategies/cartesian/disjoint_box_box.hpp112
-rw-r--r--boost/geometry/strategies/cartesian/distance_projected_point.hpp8
-rw-r--r--boost/geometry/strategies/cartesian/distance_pythagoras.hpp7
-rw-r--r--boost/geometry/strategies/cartesian/distance_pythagoras_box_box.hpp9
-rw-r--r--boost/geometry/strategies/cartesian/distance_pythagoras_point_box.hpp8
-rw-r--r--boost/geometry/strategies/cartesian/distance_segment_box.hpp13
-rw-r--r--boost/geometry/strategies/cartesian/envelope.hpp153
-rw-r--r--boost/geometry/strategies/cartesian/envelope_box.hpp119
-rw-r--r--boost/geometry/strategies/cartesian/envelope_multipoint.hpp59
-rw-r--r--boost/geometry/strategies/cartesian/envelope_point.hpp111
-rw-r--r--boost/geometry/strategies/cartesian/envelope_segment.hpp61
-rw-r--r--boost/geometry/strategies/cartesian/expand_box.hpp69
-rw-r--r--boost/geometry/strategies/cartesian/expand_point.hpp125
-rw-r--r--boost/geometry/strategies/cartesian/expand_segment.hpp71
-rw-r--r--boost/geometry/strategies/cartesian/intersection.hpp58
-rw-r--r--boost/geometry/strategies/cartesian/line_interpolate.hpp129
-rw-r--r--boost/geometry/strategies/cartesian/point_in_box.hpp125
-rw-r--r--boost/geometry/strategies/cartesian/point_in_point.hpp124
-rw-r--r--boost/geometry/strategies/cartesian/point_in_poly_crossings_multiply.hpp6
-rw-r--r--boost/geometry/strategies/cartesian/point_in_poly_franklin.hpp6
-rw-r--r--boost/geometry/strategies/cartesian/point_in_poly_winding.hpp22
-rw-r--r--boost/geometry/strategies/cartesian/side_by_triangle.hpp28
-rw-r--r--boost/geometry/strategies/cartesian/side_of_intersection.hpp6
-rw-r--r--boost/geometry/strategies/concepts/area_concept.hpp7
-rw-r--r--boost/geometry/strategies/concepts/distance_concept.hpp6
-rw-r--r--boost/geometry/strategies/concepts/within_concept.hpp53
-rw-r--r--boost/geometry/strategies/convex_hull.hpp6
-rw-r--r--boost/geometry/strategies/disjoint.hpp9
-rw-r--r--boost/geometry/strategies/envelope.hpp7
-rw-r--r--boost/geometry/strategies/expand.hpp45
-rw-r--r--boost/geometry/strategies/geographic/area.hpp1
-rw-r--r--boost/geometry/strategies/geographic/buffer_point_circle.hpp127
-rw-r--r--boost/geometry/strategies/geographic/disjoint_segment_box.hpp15
-rw-r--r--boost/geometry/strategies/geographic/distance_cross_track.hpp28
-rw-r--r--boost/geometry/strategies/geographic/distance_cross_track_box_box.hpp10
-rw-r--r--boost/geometry/strategies/geographic/distance_cross_track_point_box.hpp8
-rw-r--r--boost/geometry/strategies/geographic/distance_segment_box.hpp29
-rw-r--r--boost/geometry/strategies/geographic/envelope.hpp116
-rw-r--r--boost/geometry/strategies/geographic/envelope_segment.hpp41
-rw-r--r--boost/geometry/strategies/geographic/expand_segment.hpp102
-rw-r--r--boost/geometry/strategies/geographic/intersection.hpp64
-rw-r--r--boost/geometry/strategies/geographic/line_interpolate.hpp129
-rw-r--r--boost/geometry/strategies/geographic/side.hpp11
-rw-r--r--boost/geometry/strategies/line_interpolate.hpp42
-rw-r--r--boost/geometry/strategies/normalize.hpp268
-rw-r--r--boost/geometry/strategies/side.hpp7
-rw-r--r--boost/geometry/strategies/spherical/compare.hpp5
-rw-r--r--boost/geometry/strategies/spherical/densify.hpp67
-rw-r--r--boost/geometry/strategies/spherical/disjoint_box_box.hpp134
-rw-r--r--boost/geometry/strategies/spherical/disjoint_segment_box.hpp17
-rw-r--r--boost/geometry/strategies/spherical/distance_cross_track.hpp12
-rw-r--r--boost/geometry/strategies/spherical/distance_segment_box.hpp43
-rw-r--r--boost/geometry/strategies/spherical/envelope.hpp146
-rw-r--r--boost/geometry/strategies/spherical/envelope_box.hpp145
-rw-r--r--boost/geometry/strategies/spherical/envelope_multipoint.hpp379
-rw-r--r--boost/geometry/strategies/spherical/envelope_point.hpp111
-rw-r--r--boost/geometry/strategies/spherical/envelope_segment.hpp407
-rw-r--r--boost/geometry/strategies/spherical/expand_box.hpp98
-rw-r--r--boost/geometry/strategies/spherical/expand_point.hpp233
-rw-r--r--boost/geometry/strategies/spherical/expand_segment.hpp118
-rw-r--r--boost/geometry/strategies/spherical/intersection.hpp61
-rw-r--r--boost/geometry/strategies/spherical/line_interpolate.hpp123
-rw-r--r--boost/geometry/strategies/spherical/point_in_point.hpp172
-rw-r--r--boost/geometry/strategies/spherical/point_in_poly_winding.hpp24
-rw-r--r--boost/geometry/strategies/spherical/ssf.hpp15
-rw-r--r--boost/geometry/strategies/strategies.hpp4
-rw-r--r--boost/geometry/util/calculation_type.hpp6
-rw-r--r--boost/geometry/util/combine_if.hpp11
-rw-r--r--boost/geometry/util/is_inverse_spheroidal_coordinates.hpp5
-rw-r--r--boost/geometry/util/series_expansion.hpp9
-rw-r--r--boost/geometry/views/detail/boundary_view/implementation.hpp5
273 files changed, 9129 insertions, 4835 deletions
diff --git a/boost/geometry/algorithms/area.hpp b/boost/geometry/algorithms/area.hpp
index 26ff5c5058..b5ec53392f 100644
--- a/boost/geometry/algorithms/area.hpp
+++ b/boost/geometry/algorithms/area.hpp
@@ -216,15 +216,20 @@ struct area<MultiGeometry, multi_polygon_tag> : detail::multi_sum
namespace resolve_strategy
{
+template <typename Strategy>
struct area
{
- template <typename Geometry, typename Strategy>
+ template <typename Geometry>
static inline typename area_result<Geometry, Strategy>::type
apply(Geometry const& geometry, Strategy const& strategy)
{
return dispatch::area<Geometry>::apply(geometry, strategy);
}
+};
+template <>
+struct area<default_strategy>
+{
template <typename Geometry>
static inline typename area_result<Geometry>::type
apply(Geometry const& geometry, default_strategy)
@@ -252,7 +257,7 @@ struct area
static inline typename area_result<Geometry, Strategy>::type
apply(Geometry const& geometry, Strategy const& strategy)
{
- return resolve_strategy::area::apply(geometry, strategy);
+ return resolve_strategy::area<Strategy>::apply(geometry, strategy);
}
};
diff --git a/boost/geometry/algorithms/buffer.hpp b/boost/geometry/algorithms/buffer.hpp
index fd6f0fbe6a..ec2f9c5aca 100644
--- a/boost/geometry/algorithms/buffer.hpp
+++ b/boost/geometry/algorithms/buffer.hpp
@@ -37,52 +37,12 @@
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/algorithms/detail/buffer/buffer_box.hpp>
#include <boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp>
namespace boost { namespace geometry
{
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace buffer
-{
-
-template <typename BoxIn, typename BoxOut, typename T, std::size_t C, std::size_t D, std::size_t N>
-struct box_loop
-{
- typedef typename coordinate_type<BoxOut>::type coordinate_type;
-
- static inline void apply(BoxIn const& box_in, T const& distance, BoxOut& box_out)
- {
- coordinate_type d = distance;
- set<C, D>(box_out, get<C, D>(box_in) + d);
- box_loop<BoxIn, BoxOut, T, C, D + 1, N>::apply(box_in, distance, box_out);
- }
-};
-
-template <typename BoxIn, typename BoxOut, typename T, std::size_t C, std::size_t N>
-struct box_loop<BoxIn, BoxOut, T, C, N, N>
-{
- static inline void apply(BoxIn const&, T const&, BoxOut&) {}
-};
-
-// Extends a box with the same amount in all directions
-template<typename BoxIn, typename BoxOut, typename T>
-inline void buffer_box(BoxIn const& box_in, T const& distance, BoxOut& box_out)
-{
- assert_dimension_equal<BoxIn, BoxOut>();
-
- static const std::size_t N = dimension<BoxIn>::value;
-
- box_loop<BoxIn, BoxOut, T, min_corner, 0, N>::apply(box_in, -distance, box_out);
- box_loop<BoxIn, BoxOut, T, max_corner, 0, N>::apply(box_in, distance, box_out);
-}
-
-
-
-}} // namespace detail::buffer
-#endif // DOXYGEN_NO_DETAIL
-
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
diff --git a/boost/geometry/algorithms/densify.hpp b/boost/geometry/algorithms/densify.hpp
index ed948b3464..3a6e27d6ae 100644
--- a/boost/geometry/algorithms/densify.hpp
+++ b/boost/geometry/algorithms/densify.hpp
@@ -15,6 +15,7 @@
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/exception.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tag.hpp>
@@ -370,6 +371,9 @@ struct densify<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
[heading Example]
[densify_strategy]
[densify_strategy_output]
+
+[heading See also]
+\* [link geometry.reference.algorithms.line_interpolate line_interpolate]
}
*/
template <typename Geometry, typename Distance, typename Strategy>
@@ -409,6 +413,9 @@ inline void densify(Geometry const& geometry,
[heading Example]
[densify]
[densify_output]
+
+[heading See also]
+\* [link geometry.reference.algorithms.line_interpolate line_interpolate]
}
*/
template <typename Geometry, typename Distance>
diff --git a/boost/geometry/algorithms/detail/buffer/buffer_box.hpp b/boost/geometry/algorithms/detail/buffer/buffer_box.hpp
new file mode 100755
index 0000000000..f19a91d6ba
--- /dev/null
+++ b/boost/geometry/algorithms/detail/buffer/buffer_box.hpp
@@ -0,0 +1,62 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2018-2019 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_DETAIL_BUFFER_BUFFER_BOX_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFER_BOX_HPP
+
+#include <cstddef>
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/access.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace buffer
+{
+
+template <typename BoxIn, typename BoxOut, typename T, std::size_t C, std::size_t D, std::size_t N>
+struct box_loop
+{
+ typedef typename coordinate_type<BoxOut>::type coordinate_type;
+
+ static inline void apply(BoxIn const& box_in, T const& distance, BoxOut& box_out)
+ {
+ coordinate_type d = distance;
+ set<C, D>(box_out, get<C, D>(box_in) + d);
+ box_loop<BoxIn, BoxOut, T, C, D + 1, N>::apply(box_in, distance, box_out);
+ }
+};
+
+template <typename BoxIn, typename BoxOut, typename T, std::size_t C, std::size_t N>
+struct box_loop<BoxIn, BoxOut, T, C, N, N>
+{
+ static inline void apply(BoxIn const&, T const&, BoxOut&) {}
+};
+
+// Extends a box with the same amount in all directions
+template<typename BoxIn, typename BoxOut, typename T>
+inline void buffer_box(BoxIn const& box_in, T const& distance, BoxOut& box_out)
+{
+ assert_dimension_equal<BoxIn, BoxOut>();
+
+ static const std::size_t N = dimension<BoxIn>::value;
+
+ box_loop<BoxIn, BoxOut, T, min_corner, 0, N>::apply(box_in, -distance, box_out);
+ box_loop<BoxIn, BoxOut, T, max_corner, 0, N>::apply(box_in, distance, box_out);
+}
+
+}} // namespace detail::buffer
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFER_BOX_HPP
diff --git a/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp b/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp
index 0374b53a99..a37eabbe25 100644
--- a/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp
+++ b/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2017.
-// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2017, 2018.
+// Modifications copyright (c) 2017-2018, 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,
@@ -13,10 +13,6 @@
#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>
#include <boost/range.hpp>
@@ -26,6 +22,7 @@
#include <boost/geometry/algorithms/covered_by.hpp>
#include <boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp>
+#include <boost/geometry/algorithms/detail/overlay/traversal_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/strategies/buffer.hpp>
@@ -181,9 +178,7 @@ struct buffer_turn_info
intersection_location_type location;
-#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;
@@ -193,9 +188,7 @@ struct buffer_turn_info
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;
@@ -212,9 +205,7 @@ 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 ba824243cc..128f2beef3 100644
--- a/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp
+++ b/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp
@@ -3,8 +3,8 @@
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2016-2017.
-// Modifications copyright (c) 2016-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2016-2018.
+// Modifications copyright (c) 2016-2018 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,
@@ -145,6 +145,8 @@ struct buffered_piece_collection
>::type robust_comparable_radius_type;
typedef typename IntersectionStrategy::side_strategy_type side_strategy_type;
+ typedef typename IntersectionStrategy::envelope_strategy_type envelope_strategy_type;
+ typedef typename IntersectionStrategy::expand_strategy_type expand_strategy_type;
typedef typename IntersectionStrategy::template area_strategy
<
@@ -165,6 +167,12 @@ struct buffered_piece_collection
robust_point_type
>::type robust_area_result_type;
+ typedef typename strategy::point_in_geometry::services::default_strategy
+ <
+ robust_point_type,
+ robust_ring_type
+ >::type point_in_geometry_strategy_type;
+
typedef typename geometry::rescale_policy_type
<
typename geometry::point_type<Ring>::type
@@ -280,12 +288,14 @@ struct buffered_piece_collection
{}
inline robust_original(robust_ring_type const& ring,
- bool is_interior, bool has_interiors)
+ bool is_interior, bool has_interiors,
+ envelope_strategy_type const& envelope_strategy,
+ expand_strategy_type const& expand_strategy)
: m_ring(ring)
, m_is_interior(is_interior)
, m_has_interiors(has_interiors)
{
- geometry::envelope(m_ring, m_box);
+ geometry::envelope(m_ring, m_box, envelope_strategy);
// create monotonic sections in x-dimension
// The dimension is critical because the direction is later used
@@ -293,7 +303,8 @@ struct buffered_piece_collection
// and this strategy is scanning in x direction.
typedef boost::mpl::vector_c<std::size_t, 0> dimensions;
geometry::sectionalize<false, dimensions>(m_ring,
- detail::no_rescale_policy(), m_sections);
+ detail::no_rescale_policy(), m_sections,
+ envelope_strategy, expand_strategy);
}
robust_ring_type m_ring;
@@ -335,6 +346,9 @@ struct buffered_piece_collection
IntersectionStrategy m_intersection_strategy;
side_strategy_type m_side_strategy;
area_strategy_type m_area_strategy;
+ envelope_strategy_type m_envelope_strategy;
+ expand_strategy_type m_expand_strategy;
+
robust_area_strategy_type m_robust_area_strategy;
RobustPolicy const& m_robust_policy;
@@ -354,6 +368,8 @@ struct buffered_piece_collection
, m_intersection_strategy(intersection_strategy)
, m_side_strategy(intersection_strategy.get_side_strategy())
, m_area_strategy(intersection_strategy.template get_area_strategy<point_type>())
+ , m_envelope_strategy(intersection_strategy.get_envelope_strategy())
+ , m_expand_strategy(intersection_strategy.get_expand_strategy())
, m_robust_area_strategy(intersection_strategy.template get_area_strategy<robust_point_type>())
, m_robust_policy(robust_policy)
{}
@@ -529,7 +545,6 @@ 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
@@ -538,7 +553,6 @@ struct buffered_piece_collection
it->operations[0].enriched.startable = false;
it->operations[1].enriched.startable = false;
}
-#endif
}
}
@@ -635,6 +649,15 @@ struct buffered_piece_collection
{
// Check if a turn is inside any of the originals
+ typedef turn_in_original_ovelaps_box
+ <
+ typename IntersectionStrategy::disjoint_point_box_strategy_type
+ > turn_in_original_ovelaps_box_type;
+ typedef original_ovelaps_box
+ <
+ typename IntersectionStrategy::disjoint_box_box_strategy_type
+ > original_ovelaps_box_type;
+
turn_in_original_visitor<turn_vector_type> visitor(m_turns);
geometry::partition
<
@@ -642,8 +665,8 @@ struct buffered_piece_collection
include_turn_policy,
detail::partition::include_all_policy
>::apply(m_turns, robust_originals, visitor,
- turn_get_box(), turn_in_original_ovelaps_box(),
- original_get_box(), original_ovelaps_box());
+ turn_get_box(), turn_in_original_ovelaps_box_type(),
+ original_get_box(), original_ovelaps_box_type());
bool const deflate = distance_strategy.negative();
@@ -727,46 +750,47 @@ 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 boost::range_iterator<piece_vector_type>::type
- it = boost::begin(m_pieces); it != boost::end(m_pieces); ++it)
+ if (! use_side_of_intersection<typename geometry::cs_tag<point_type>::type>::value)
{
- piece& pc = *it;
- signed_size_type piece_segment_index = pc.first_seg_id.segment_index;
- if (! pc.robust_turns.empty())
+ // 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 boost::range_iterator<piece_vector_type>::type
+ it = boost::begin(m_pieces); it != boost::end(m_pieces); ++it)
{
- if (pc.robust_turns.size() > 1u)
+ piece& pc = *it;
+ signed_size_type piece_segment_index = pc.first_seg_id.segment_index;
+ if (! pc.robust_turns.empty())
{
- std::sort(pc.robust_turns.begin(), pc.robust_turns.end(), buffer_operation_less());
- }
- // Walk through them, in reverse to insert at right index
- 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)
- {
- 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
- );
+ if (pc.robust_turns.size() > 1u)
+ {
+ std::sort(pc.robust_turns.begin(), pc.robust_turns.end(), buffer_operation_less());
+ }
+ // Walk through them, in reverse to insert at right index
+ 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)
+ {
+ 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
+ );
- pc.robust_ring.insert(boost::begin(pc.robust_ring) + index_in_vector, rit->point);
- pc.offsetted_count++;
+ pc.robust_ring.insert(boost::begin(pc.robust_ring) + index_in_vector, rit->point);
+ pc.offsetted_count++;
- m_turns[rit->turn_index].operations[rit->operation_index].index_in_robust_ring = index_in_vector + index_offset;
+ m_turns[rit->turn_index].operations[rit->operation_index].index_in_robust_ring = index_in_vector + index_offset;
+ }
}
}
- }
- BOOST_GEOMETRY_ASSERT(assert_indices_in_robust_rings());
-#endif
+ BOOST_GEOMETRY_ASSERT(assert_indices_in_robust_rings());
+ }
}
template <std::size_t Dimension>
@@ -842,7 +866,8 @@ struct buffered_piece_collection
// create monotonic sections in y-dimension
typedef boost::mpl::vector_c<std::size_t, 1> dimensions;
geometry::sectionalize<false, dimensions>(pc.robust_ring,
- detail::no_rescale_policy(), pc.sections);
+ detail::no_rescale_policy(), pc.sections,
+ m_envelope_strategy, m_expand_strategy);
// Determine min/max radius
typedef geometry::model::referring_segment<robust_point_type const>
@@ -906,12 +931,21 @@ struct buffered_piece_collection
> visitor(m_pieces, offsetted_rings, m_turns,
m_intersection_strategy, m_robust_policy);
+ typedef detail::section::get_section_box
+ <
+ typename IntersectionStrategy::expand_box_strategy_type
+ > get_section_box_type;
+ typedef detail::section::overlaps_section_box
+ <
+ typename IntersectionStrategy::disjoint_box_box_strategy_type
+ > overlaps_section_box_type;
+
geometry::partition
<
robust_box_type
>::apply(monotonic_sections, visitor,
- detail::section::get_section_box(),
- detail::section::overlaps_section_box());
+ get_section_box_type(),
+ overlaps_section_box_type());
}
insert_rescaled_piece_turns();
@@ -926,15 +960,26 @@ struct buffered_piece_collection
// Check if it is inside any of the pieces
turn_in_piece_visitor
<
- turn_vector_type, piece_vector_type
- > visitor(m_turns, m_pieces);
+ typename geometry::cs_tag<point_type>::type,
+ turn_vector_type, piece_vector_type,
+ point_in_geometry_strategy_type
+ > visitor(m_turns, m_pieces, point_in_geometry_strategy_type());
+
+ typedef turn_ovelaps_box
+ <
+ typename IntersectionStrategy::disjoint_point_box_strategy_type
+ > turn_ovelaps_box_type;
+ typedef piece_ovelaps_box
+ <
+ typename IntersectionStrategy::disjoint_box_box_strategy_type
+ > piece_ovelaps_box_type;
geometry::partition
<
robust_box_type
>::apply(m_turns, m_pieces, visitor,
- turn_get_box(), turn_ovelaps_box(),
- piece_get_box(), piece_ovelaps_box());
+ turn_get_box(), turn_ovelaps_box_type(),
+ piece_get_box(), piece_ovelaps_box_type());
}
}
@@ -1057,7 +1102,7 @@ struct buffered_piece_collection
robust_originals.push_back(
robust_original(current_robust_ring,
- is_interior, has_interiors));
+ is_interior, has_interiors, m_envelope_strategy, m_expand_strategy));
}
}
@@ -1174,7 +1219,7 @@ struct buffered_piece_collection
return;
}
- geometry::envelope(pc.robust_ring, pc.robust_envelope);
+ geometry::envelope(pc.robust_ring, pc.robust_envelope, m_envelope_strategy);
geometry::assign_inverse(pc.robust_offsetted_envelope);
for (signed_size_type i = 0; i < pc.offsetted_count; i++)
@@ -1400,6 +1445,8 @@ struct buffered_piece_collection
inline bool point_coveredby_original(point_type const& point)
{
+ typedef typename IntersectionStrategy::disjoint_point_box_strategy_type d_pb_strategy_type;
+
robust_point_type any_point;
geometry::recalculate(any_point, point, m_robust_policy);
@@ -1416,14 +1463,15 @@ struct buffered_piece_collection
{
robust_original const& original = *it;
if (detail::disjoint::disjoint_point_box(any_point,
- original.m_box))
+ original.m_box,
+ d_pb_strategy_type()))
{
continue;
}
int const geometry_code
= detail::within::point_in_geometry(any_point,
- original.m_ring);
+ original.m_ring, point_in_geometry_strategy_type());
if (geometry_code == -1)
{
diff --git a/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp b/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp
index 506ff58474..b2af001be2 100644
--- a/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp
+++ b/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp
@@ -3,8 +3,8 @@
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2017.
-// Modifications copyright (c) 2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2017, 2018.
+// Modifications copyright (c) 2017-2018 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,
@@ -17,6 +17,7 @@
#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/algorithms/equals.hpp>
#include <boost/geometry/algorithms/expand.hpp>
#include <boost/geometry/algorithms/detail/disjoint/box_box.hpp>
@@ -34,34 +35,81 @@ namespace boost { namespace geometry
namespace detail { namespace buffer
{
-
-#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
-struct buffer_assign_turn
+// Implements a unique_sub_range for a buffered piece,
+// the range can return subsequent points
+// known as "i", "j" and "k" (and further), indexed as 0,1,2,3
+template <typename Ring>
+struct unique_sub_range_from_piece
{
- 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)
+ typedef typename boost::range_iterator<Ring const>::type iterator_type;
+ typedef typename geometry::point_type<Ring const>::type point_type;
+
+ unique_sub_range_from_piece(Ring const& ring,
+ iterator_type iterator_at_i, iterator_type iterator_at_j)
+ : m_ring(ring)
+ , m_iterator_at_i(iterator_at_i)
+ , m_iterator_at_j(iterator_at_j)
+ , m_point_retrieved(false)
+ {}
+
+ static inline bool is_first_segment() { return false; }
+ static inline bool is_last_segment() { return false; }
+
+ static inline std::size_t size() { return 3u; }
+
+ inline point_type const& at(std::size_t index) const
{
- info.rob_pi = iinfo.rpi();
- info.rob_pj = iinfo.rpj();
- info.rob_qi = iinfo.rqi();
- info.rob_qj = iinfo.rqj();
+ BOOST_GEOMETRY_ASSERT(index < size());
+ switch (index)
+ {
+ case 0 : return *m_iterator_at_i;
+ case 1 : return *m_iterator_at_j;
+ case 2 : return get_point_k();
+ default : return *m_iterator_at_i;
+ }
+ }
+
+private :
+
+ inline point_type const& get_point_k() const
+ {
+ if (! m_point_retrieved)
+ {
+ m_iterator_at_k = advance_one(m_iterator_at_j);
+ m_point_retrieved = true;
+ }
+ return *m_iterator_at_k;
+ }
+
+ inline void circular_advance_one(iterator_type& next) const
+ {
+ ++next;
+ if (next == boost::end(m_ring))
+ {
+ next = boost::begin(m_ring) + 1;
+ }
}
+ inline iterator_type advance_one(iterator_type it) const
+ {
+ iterator_type result = it;
+ circular_advance_one(result);
+
+ // TODO: we could also use piece-boundaries
+ // to check if the point equals the last one
+ while (geometry::equals(*it, *result))
+ {
+ circular_advance_one(result);
+ }
+ return result;
+ }
+
+ Ring const& m_ring;
+ iterator_type m_iterator_at_i;
+ iterator_type m_iterator_at_j;
+ mutable iterator_type m_iterator_at_k;
+ mutable bool m_point_retrieved;
};
-#endif
template
<
@@ -102,29 +150,6 @@ class piece_turn_visitor
return ! m_rings[piece1.first_seg_id.multi_index].has_concave;
}
- template <typename Range, typename Iterator>
- inline void move_to_next_point(Range const& range, Iterator& next) const
- {
- ++next;
- if (next == boost::end(range))
- {
- next = boost::begin(range) + 1;
- }
- }
-
- template <typename Range, typename Iterator>
- inline Iterator next_point(Range const& range, Iterator it) const
- {
- Iterator result = it;
- move_to_next_point(range, result);
- // TODO: we could use either piece-boundaries, or comparison with
- // robust points, to check if the point equals the last one
- while(geometry::equals(*it, *result))
- {
- move_to_next_point(range, result);
- }
- return result;
- }
template <std::size_t Dimension, typename Iterator, typename Box>
inline void move_begin_iterator(Iterator& it_begin, Iterator it_beyond,
@@ -229,15 +254,19 @@ class piece_turn_visitor
the_model.operations[1].piece_index = piece2.index;
the_model.operations[1].seg_id = piece2.first_seg_id;
the_model.operations[1].seg_id.segment_index = index2; // override
+ geometry::recalculate(the_model.rob_pi, *prev1, m_robust_policy);
+ geometry::recalculate(the_model.rob_pj, *it1, m_robust_policy);
- iterator next1 = next_point(ring1, it1);
+ unique_sub_range_from_piece<ring_type> unique_sub_range1(ring1, prev1, it1);
iterator it2 = it2_first;
for (iterator prev2 = it2++;
it2 != it2_beyond;
prev2 = it2++, the_model.operations[1].seg_id.segment_index++)
{
- iterator next2 = next_point(ring2, it2);
+ unique_sub_range_from_piece<ring_type> unique_sub_range2(ring2, prev2, it2);
+ geometry::recalculate(the_model.rob_qi, *prev2, m_robust_policy);
+ geometry::recalculate(the_model.rob_qj, *it2, m_robust_policy);
// TODO: internally get_turn_info calculates robust points.
// But they are already calculated.
@@ -246,20 +275,14 @@ 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,
- *prev2, *it2, *next2,
- false, false, false, false,
- the_model,
- m_intersection_strategy,
- m_robust_policy,
- std::back_inserter(m_turns));
+ turn_policy::apply(unique_sub_range1, unique_sub_range2,
+ the_model,
+ m_intersection_strategy,
+ m_robust_policy,
+ std::back_inserter(m_turns));
}
}
}
@@ -292,7 +315,8 @@ public:
|| is_adjacent(piece1, piece2)
|| is_on_same_convex_ring(piece1, piece2)
|| detail::disjoint::disjoint_box_box(section1.bounding_box,
- section2.bounding_box) )
+ section2.bounding_box,
+ m_intersection_strategy.get_disjoint_box_box_strategy()) )
{
return true;
}
diff --git a/boost/geometry/algorithms/detail/buffer/turn_in_original_visitor.hpp b/boost/geometry/algorithms/detail/buffer/turn_in_original_visitor.hpp
index 70053536fb..5236da1da8 100644
--- a/boost/geometry/algorithms/detail/buffer/turn_in_original_visitor.hpp
+++ b/boost/geometry/algorithms/detail/buffer/turn_in_original_visitor.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2014 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2016.
-// Modifications copyright (c) 2016 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2016, 2018.
+// Modifications copyright (c) 2016-2018 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,
@@ -16,6 +16,7 @@
#include <boost/core/ignore_unused.hpp>
+#include <boost/geometry/algorithms/detail/buffer/buffer_policies.hpp>
#include <boost/geometry/algorithms/expand.hpp>
#include <boost/geometry/strategies/agnostic/point_in_poly_winding.hpp>
#include <boost/geometry/strategies/buffer.hpp>
@@ -38,12 +39,14 @@ struct original_get_box
}
};
+template <typename DisjointBoxBoxStrategy>
struct original_ovelaps_box
{
template <typename Box, typename Original>
static inline bool apply(Box const& box, Original const& original)
{
- return ! detail::disjoint::disjoint_box_box(box, original.m_box);
+ return ! detail::disjoint::disjoint_box_box(box, original.m_box,
+ DisjointBoxBoxStrategy());
}
};
@@ -56,6 +59,7 @@ struct include_turn_policy
}
};
+template <typename DisjointPointBoxStrategy>
struct turn_in_original_ovelaps_box
{
template <typename Box, typename Turn>
@@ -68,7 +72,7 @@ struct turn_in_original_ovelaps_box
}
return ! geometry::detail::disjoint::disjoint_point_box(
- turn.robust_point, box);
+ turn.robust_point, box, DisjointPointBoxStrategy());
}
};
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 e066c27f36..5e2258dfce 100644
--- a/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp
+++ b/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp
@@ -3,8 +3,8 @@
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2016.
-// Modifications copyright (c) 2016 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2016, 2018.
+// Modifications copyright (c) 2016-2018 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,
@@ -20,6 +20,7 @@
#include <boost/range.hpp>
#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/config.hpp>
#include <boost/geometry/arithmetic/dot_product.hpp>
#include <boost/geometry/algorithms/assign.hpp>
@@ -34,11 +35,8 @@
#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>
-#else
#include <boost/geometry/strategies/agnostic/point_in_poly_winding.hpp>
-#endif
namespace boost { namespace geometry
@@ -58,6 +56,7 @@ struct piece_get_box
}
};
+template <typename DisjointBoxBoxStrategy>
struct piece_ovelaps_box
{
template <typename Box, typename Piece>
@@ -73,7 +72,8 @@ struct piece_ovelaps_box
return false;
}
- return ! geometry::detail::disjoint::disjoint_box_box(box, piece.robust_envelope);
+ return ! geometry::detail::disjoint::disjoint_box_box(box, piece.robust_envelope,
+ DisjointBoxBoxStrategy());
}
};
@@ -86,12 +86,14 @@ struct turn_get_box
}
};
+template <typename DisjointPointBoxStrategy>
struct turn_ovelaps_box
{
template <typename Box, typename Turn>
static inline bool apply(Box const& box, Turn const& turn)
{
- return ! geometry::detail::disjoint::disjoint_point_box(turn.robust_point, box);
+ return ! geometry::detail::disjoint::disjoint_point_box(turn.robust_point, box,
+ DisjointPointBoxStrategy());
}
};
@@ -103,10 +105,8 @@ enum analyse_result
analyse_disjoint,
analyse_within,
analyse_on_original_boundary,
- analyse_on_offsetted
-#if ! defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
- , analyse_near_offsetted
-#endif
+ analyse_on_offsetted,
+ analyse_near_offsetted
};
template <typename Point>
@@ -123,85 +123,115 @@ inline bool in_box(Point const& previous,
return geometry::covered_by(point, box);
}
-template <typename Point, typename Turn>
-inline analyse_result check_segment(Point const& previous,
- Point const& current, Turn const& turn,
- bool from_monotonic)
-{
+// meta-programming-structure defining if to use side-of-intersection
+// (only for cartesian / only necessary with rescaling)
+template <typename Tag>
+struct use_side_of_intersection {};
-#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 defined(BOOST_GEOMETRY_USE_RESCALING)
+// With rescaling, let Cartesian use side-of-intersection
+template <>
+struct use_side_of_intersection<cartesian_tag> { static bool const value = true; };
+#else
+template <>
+struct use_side_of_intersection<cartesian_tag> { static bool const value = false; };
+#endif
- 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;
+template <>
+struct use_side_of_intersection<spherical_tag> { static bool const value = false; };
-#else
+template <>
+struct use_side_of_intersection<geographic_tag> { static bool const value = false; };
- typedef typename strategy::side::services::default_strategy
- <
- typename cs_tag<Point>::type
- >::type side_strategy;
- typedef typename geometry::coordinate_type<Point>::type coordinate_type;
- coordinate_type const twice_area
- = side_strategy::template side_value
- <
- coordinate_type,
- coordinate_type
- >(previous, current, turn.robust_point);
+template <bool UseSideOfIntersection>
+struct check_segment {};
- if (twice_area == 0)
+// Implementation using side-of-intersection
+template <>
+struct check_segment<true>
+{
+ template <typename Point, typename Turn>
+ static inline analyse_result apply(Point const& previous,
+ Point const& current, Turn const& turn,
+ bool from_monotonic)
{
- // Collinear, only on segment if it is covered by its bbox
- if (in_box(previous, current, turn.robust_point))
+ 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 if (twice_area < 0)
+};
+
+template <>
+struct check_segment<false>
+{
+ template <typename Point, typename Turn>
+ static inline analyse_result apply(Point const& previous,
+ Point const& current, Turn const& turn,
+ bool from_monotonic)
{
- // It is in the triangle right-of the segment where the
- // segment is the hypothenusa. Check if it is close
- // (within rounding-area)
- if (twice_area * twice_area < geometry::comparable_distance(previous, current)
- && in_box(previous, current, turn.robust_point))
+ typedef typename strategy::side::services::default_strategy
+ <
+ typename cs_tag<Point>::type
+ >::type side_strategy;
+
+ int const side = side_strategy::apply(previous, current, turn.robust_point);
+
+ if (side == 0)
+ {
+ // Collinear, only on segment if it is covered by its bbox
+ if (in_box(previous, current, turn.robust_point))
+ {
+ return analyse_on_offsetted;
+ }
+ }
+ else if (side == -1)
{
- return analyse_near_offsetted;
+ // It is in the triangle right-of the segment where the
+ // segment is the hypothenusa. Check if it is close
+ // (within rounding-area)
+ if (in_box(previous, current, turn.robust_point))
+ {
+ return analyse_near_offsetted;
+ }
+ else if (from_monotonic)
+ {
+ return analyse_within;
+ }
}
else if (from_monotonic)
{
- return analyse_within;
+ // Left of segment
+ return analyse_disjoint;
}
- }
- else if (twice_area > 0 && from_monotonic)
- {
- // Left of segment
- return analyse_disjoint;
- }
- // Not monotonic, on left or right side: continue analysing
- return analyse_continue;
-#endif
-}
+ // Not monotonic, on left or right side: continue analysing
+ return analyse_continue;
+ }
+};
+template <bool UseSideOfIntersection>
+class analyse_turn_wrt_point_piece {};
-class analyse_turn_wrt_point_piece
+template <>
+class analyse_turn_wrt_point_piece<true>
{
public :
template <typename Turn, typename Piece>
@@ -211,17 +241,9 @@ public :
typedef typename Turn::robust_point_type point_type;
typedef typename geometry::coordinate_type<point_type>::type coordinate_type;
-#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());
@@ -241,7 +263,6 @@ public :
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
@@ -272,8 +293,51 @@ public :
return analyse_on_offsetted;
}
}
-#else
- analyse_result code = check_segment(previous, current, turn, false);
+ }
+ }
+ }
+
+ // It is nowhere outside, and not on segment, so it is within
+ return analyse_within;
+ }
+
+};
+
+template <>
+class analyse_turn_wrt_point_piece<false>
+{
+public :
+ template <typename Turn, typename Piece>
+ static inline analyse_result apply(Turn const& turn, Piece const& piece)
+ {
+ typedef typename Piece::section_type section_type;
+ typedef typename Turn::robust_point_type point_type;
+ typedef typename geometry::coordinate_type<point_type>::type coordinate_type;
+
+ typedef strategy::within::winding<point_type> strategy_type;
+
+ typename strategy_type::state_type state;
+ strategy_type strategy;
+
+ BOOST_GEOMETRY_ASSERT(! piece.sections.empty());
+
+ coordinate_type const point_x = geometry::get<0>(turn.robust_point);
+
+ for (std::size_t s = 0; s < piece.sections.size(); s++)
+ {
+ section_type const& section = piece.sections[s];
+ // If point within horizontal range of monotonic section:
+ if (! section.duplicate
+ && section.begin_index < section.end_index
+ && point_x >= geometry::get<min_corner, 0>(section.bounding_box) - 1
+ && point_x <= geometry::get<max_corner, 0>(section.bounding_box) + 1)
+ {
+ 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];
+
+ analyse_result code = check_segment<false>::apply(previous, current, turn, false);
if (code != analyse_continue)
{
return code;
@@ -282,15 +346,10 @@ 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)
{
@@ -303,25 +362,24 @@ public :
// Should normally not occur - on-segment is covered
return analyse_unknown;
-#endif
}
};
-class analyse_turn_wrt_piece
+template <bool UseSideOfIntersection>
+struct check_helper_segment {};
+
+template <>
+struct check_helper_segment<true>
{
template <typename Point, typename Turn>
- static inline analyse_result check_helper_segment(Point const& s1,
+ static inline analyse_result apply(Point const& s1,
Point const& s2, Turn const& turn,
-#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
- bool , // is on original, to be reused
-#else
bool is_original,
-#endif
Point const& offsetted)
{
boost::ignore_unused(offsetted);
-#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
+ boost::ignore_unused(is_original);
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);
@@ -360,7 +418,20 @@ class analyse_turn_wrt_piece
// right of segment
return analyse_continue;
-#else
+ }
+
+};
+
+template <>
+struct check_helper_segment<false>
+{
+ template <typename Point, typename Turn>
+ static inline analyse_result apply(Point const& s1,
+ Point const& s2, Turn const& turn,
+ bool is_original,
+ Point const& offsetted)
+ {
+ boost::ignore_unused(offsetted);
typedef typename strategy::side::services::default_strategy
<
typename cs_tag<Point>::type
@@ -409,9 +480,12 @@ class analyse_turn_wrt_piece
// right of segment
return analyse_continue;
-#endif
}
+};
+template <bool UseSideOfIntersection>
+class analyse_turn_wrt_piece
+{
template <typename Turn, typename Piece>
static inline analyse_result check_helper_segments(Turn const& turn, Piece const& piece)
{
@@ -471,7 +545,7 @@ class analyse_turn_wrt_piece
// Right side of the piece
analyse_result result
- = check_helper_segment(points[0], points[1], turn,
+ = check_helper_segment<UseSideOfIntersection>::apply(points[0], points[1], turn,
false, points[0]);
if (result != analyse_continue)
{
@@ -479,7 +553,7 @@ class analyse_turn_wrt_piece
}
// Left side of the piece
- result = check_helper_segment(points[2], points[3], turn,
+ result = check_helper_segment<UseSideOfIntersection>::apply(points[2], points[3], turn,
false, points[3]);
if (result != analyse_continue)
{
@@ -489,7 +563,7 @@ class analyse_turn_wrt_piece
if (! comparator(points[1], points[2]))
{
// Side of the piece at side of original geometry
- result = check_helper_segment(points[1], points[2], turn,
+ result = check_helper_segment<UseSideOfIntersection>::apply(points[1], points[2], turn,
true, point);
if (result != analyse_continue)
{
@@ -536,7 +610,7 @@ class analyse_turn_wrt_piece
// w.r.t. specified direction, and prev points to a point smaller
// We now know if it is inside/outside
it_type prev = it - 1;
- return check_segment(*prev, *it, turn, true);
+ return check_segment<UseSideOfIntersection>::apply(*prev, *it, turn, true);
}
return analyse_continue;
}
@@ -593,7 +667,7 @@ public :
// (on which any side or side-value would return 0)
if (! comparator(previous, current))
{
- code = check_segment(previous, current, turn, false);
+ code = check_segment<UseSideOfIntersection>::apply(previous, current, turn, false);
if (code != analyse_continue)
{
return code;
@@ -606,45 +680,17 @@ public :
};
+// Helper Structure, of which the apply method returns a side value in {-1, 0, 1}
+template <bool UseSideOfIntersection>
+struct turn_in_piece {};
-template <typename Turns, typename Pieces>
-class turn_in_piece_visitor
+template <>
+struct turn_in_piece<true>
{
- Turns& m_turns; // because partition is currently operating on const input only
- Pieces const& m_pieces; // to check for piece-type
- template <typename Operation, typename Piece>
- inline bool skip(Operation const& op, Piece const& piece) const
- {
- if (op.piece_index == piece.index)
- {
- return true;
- }
- Piece const& pc = m_pieces[op.piece_index];
- if (pc.left_index == piece.index || pc.right_index == piece.index)
- {
- if (pc.type == strategy::buffer::buffered_flat_end)
- {
- // If it is a flat end, don't compare against its neighbor:
- // it will always be located on one of the helper segments
- return true;
- }
- if (pc.type == strategy::buffer::buffered_concave)
- {
- // If it is concave, the same applies: the IP will be
- // located on one of the helper segments
- return true;
- }
- }
-
- return false;
- }
-
-#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
- // NOTE: this function returns a side value in {-1, 0, 1}
+private :
template <typename Turn, typename Piece>
- static inline int turn_in_convex_piece(Turn const& turn,
- Piece const& piece)
+ static inline int 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;
@@ -693,14 +739,90 @@ class turn_in_piece_visitor
}
return 1; // inside
}
-#endif
+
+public :
+
+ template <typename Turn, typename Piece, typename Strategy>
+ static inline int apply(Turn const& turn, Piece const& piece,
+ Strategy const& strategy)
+ {
+ if (piece.is_convex)
+ {
+ return in_convex_piece(turn, piece);
+ }
+ else
+ {
+ // side-of-intersection only supported for convex pieces
+ // Call point_in_geometry, a performance-bottleneck
+ // TODO: might be replaced by extending analysing piece
+ return detail::within::point_in_geometry(turn.robust_point,
+ piece.robust_ring, strategy);
+ }
+ }
+};
+
+template <>
+struct turn_in_piece<false>
+{
+public :
+
+ template <typename Turn, typename Piece, typename Strategy>
+ static inline int apply(Turn const& turn, Piece const& piece,
+ Strategy const& strategy)
+ {
+ return detail::within::point_in_geometry(turn.robust_point,
+ piece.robust_ring, strategy);
+ }
+};
+
+template
+<
+ typename CsTag,
+ typename Turns,
+ typename Pieces,
+ typename PointInGeometryStrategy
+>
+class turn_in_piece_visitor
+{
+ Turns& m_turns; // because partition is currently operating on const input only
+ Pieces const& m_pieces; // to check for piece-type
+ PointInGeometryStrategy const& m_point_in_geometry_strategy;
+
+ template <typename Operation, typename Piece>
+ inline bool skip(Operation const& op, Piece const& piece) const
+ {
+ if (op.piece_index == piece.index)
+ {
+ return true;
+ }
+ Piece const& pc = m_pieces[op.piece_index];
+ if (pc.left_index == piece.index || pc.right_index == piece.index)
+ {
+ if (pc.type == strategy::buffer::buffered_flat_end)
+ {
+ // If it is a flat end, don't compare against its neighbor:
+ // it will always be located on one of the helper segments
+ return true;
+ }
+ if (pc.type == strategy::buffer::buffered_concave)
+ {
+ // If it is concave, the same applies: the IP will be
+ // located on one of the helper segments
+ return true;
+ }
+ }
+
+ return false;
+ }
public:
- inline turn_in_piece_visitor(Turns& turns, Pieces const& pieces)
+ inline turn_in_piece_visitor(Turns& turns, Pieces const& pieces,
+ PointInGeometryStrategy const& strategy)
: m_turns(turns)
, m_pieces(pieces)
+ , m_point_in_geometry_strategy(strategy)
{}
template <typename Turn, typename Piece>
@@ -759,10 +881,13 @@ public:
}
}
+ static const bool use_soi = use_side_of_intersection<CsTag>::value;
+ boost::ignore_unused(use_soi);
+
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);
+ ? analyse_turn_wrt_point_piece<use_soi>::apply(turn, piece)
+ : analyse_turn_wrt_piece<use_soi>::apply(turn, piece);
switch(analyse_code)
{
@@ -777,32 +902,15 @@ public:
case analyse_within :
mutable_turn.count_within++;
return true;
-#if ! defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
case analyse_near_offsetted :
mutable_turn.count_within_near_offsetted++;
return true;
-#endif
default :
break;
}
-#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
+ int const geometry_code = turn_in_piece<use_soi>::apply(turn, piece,
+ m_point_in_geometry_strategy);
if (geometry_code == 1)
{
diff --git a/boost/geometry/algorithms/detail/covered_by/implementation.hpp b/boost/geometry/algorithms/detail/covered_by/implementation.hpp
index c5a02b9761..b180a3d5a3 100644
--- a/boost/geometry/algorithms/detail/covered_by/implementation.hpp
+++ b/boost/geometry/algorithms/detail/covered_by/implementation.hpp
@@ -4,8 +4,8 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2013, 2014, 2017.
-// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2017, 2019.
+// Modifications copyright (c) 2013-2019 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -36,7 +36,7 @@ struct use_point_in_geometry
template <typename Geometry1, typename Geometry2, typename Strategy>
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
{
- return detail::within::point_in_geometry(geometry1, geometry2, strategy) >= 0;
+ return detail::within::covered_by_point_geometry(geometry1, geometry2, strategy);
}
};
diff --git a/boost/geometry/algorithms/detail/covered_by/interface.hpp b/boost/geometry/algorithms/detail/covered_by/interface.hpp
index 6599078210..bdc92db43b 100644
--- a/boost/geometry/algorithms/detail/covered_by/interface.hpp
+++ b/boost/geometry/algorithms/detail/covered_by/interface.hpp
@@ -4,8 +4,8 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2013, 2014, 2017.
-// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2017, 2018.
+// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -63,13 +63,7 @@ struct covered_by
Geometry2 const& geometry2,
Strategy const& strategy)
{
- concepts::within::check
- <
- typename tag<Geometry1>::type,
- typename tag<Geometry2>::type,
- typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
- Strategy
- >();
+ concepts::within::check<Geometry1, Geometry2, Strategy>();
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
assert_dimension_equal<Geometry1, Geometry2>();
diff --git a/boost/geometry/algorithms/detail/disjoint/areal_areal.hpp b/boost/geometry/algorithms/detail/disjoint/areal_areal.hpp
index 664c995384..3fccc74d22 100644
--- a/boost/geometry/algorithms/detail/disjoint/areal_areal.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/areal_areal.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013-2017.
-// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013-2019.
+// Modifications copyright (c) 2013-2019, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -28,6 +28,9 @@
#include <boost/geometry/algorithms/detail/point_on_border.hpp>
#include <boost/geometry/algorithms/detail/disjoint/linear_linear.hpp>
+#include <boost/geometry/algorithms/detail/disjoint/segment_box.hpp>
+
+#include <boost/geometry/iterators/segment_iterator.hpp>
namespace boost { namespace geometry
@@ -38,30 +41,15 @@ namespace boost { namespace geometry
namespace detail { namespace disjoint
{
-
-template <typename Geometry, typename Tag = typename tag<Geometry>::type>
-struct check_each_ring_for_within_call_covered_by
+template <typename Geometry1, typename Geometry2, typename Strategy>
+inline bool point_on_border_covered_by(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
{
- /*!
- \tparam Strategy point_in_geometry strategy
- */
- template <typename Point, typename Strategy>
- static inline bool apply(Point const& p, Geometry const& g, Strategy const& strategy)
- {
- return geometry::covered_by(p, g, strategy);
- }
-};
-
-template <typename Geometry>
-struct check_each_ring_for_within_call_covered_by<Geometry, box_tag>
-{
- template <typename Point, typename Strategy>
- static inline bool apply(Point const& p, Geometry const& g, Strategy const& )
- {
- return geometry::covered_by(p, g);
- }
-};
-
+ typename geometry::point_type<Geometry1>::type pt;
+ return geometry::point_on_border(pt, geometry1)
+ && geometry::covered_by(pt, geometry2, strategy);
+}
/*!
\tparam Strategy point_in_geometry strategy
@@ -83,13 +71,8 @@ struct check_each_ring_for_within
template <typename Range>
inline void apply(Range const& range)
{
- typename point_type<Range>::type pt;
not_disjoint = not_disjoint
- || ( geometry::point_on_border(pt, range)
- && check_each_ring_for_within_call_covered_by
- <
- Geometry
- >::apply(pt, m_geometry, m_strategy) );
+ || point_on_border_covered_by(range, m_geometry, m_strategy);
}
};
@@ -113,7 +96,7 @@ inline bool rings_containing(FirstGeometry const& geometry1,
template <typename Geometry1, typename Geometry2>
-struct general_areal
+struct areal_areal
{
/*!
\tparam Strategy relate (segments intersection) strategy
@@ -147,6 +130,56 @@ struct general_areal
};
+template <typename Areal, typename Box>
+struct areal_box
+{
+ /*!
+ \tparam Strategy relate (segments intersection) strategy
+ */
+ template <typename Strategy>
+ static inline bool apply(Areal const& areal,
+ Box const& box,
+ Strategy const& strategy)
+ {
+ if ( ! for_each_segment(geometry::segments_begin(areal),
+ geometry::segments_end(areal),
+ box,
+ strategy.get_disjoint_segment_box_strategy()) )
+ {
+ return false;
+ }
+
+ // If there is no intersection of any segment and box,
+ // the box might be located inside areal geometry
+
+ if ( point_on_border_covered_by(box, areal,
+ strategy.template get_point_in_geometry_strategy<Box, Areal>()) )
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+private:
+ template <typename SegIter, typename Strategy>
+ static inline bool for_each_segment(SegIter first,
+ SegIter last,
+ Box const& box,
+ Strategy const& strategy)
+ {
+ for ( ; first != last ; ++first)
+ {
+ if (! disjoint_segment_box::apply(*first, box, strategy))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+};
+
+
}} // namespace detail::disjoint
#endif // DOXYGEN_NO_DETAIL
@@ -160,13 +193,13 @@ namespace dispatch
template <typename Areal1, typename Areal2>
struct disjoint<Areal1, Areal2, 2, areal_tag, areal_tag, false>
- : detail::disjoint::general_areal<Areal1, Areal2>
+ : detail::disjoint::areal_areal<Areal1, Areal2>
{};
template <typename Areal, typename Box>
struct disjoint<Areal, Box, 2, areal_tag, box_tag, false>
- : detail::disjoint::general_areal<Areal, Box>
+ : detail::disjoint::areal_box<Areal, Box>
{};
diff --git a/boost/geometry/algorithms/detail/disjoint/box_box.hpp b/boost/geometry/algorithms/detail/disjoint/box_box.hpp
index 87618939b8..67f0633218 100644
--- a/boost/geometry/algorithms/detail/disjoint/box_box.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/box_box.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013-2017.
-// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013-2018.
+// Modifications copyright (c) 2013-2018, 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,139 +23,30 @@
#include <cstddef>
-#include <boost/geometry/core/access.hpp>
-#include <boost/geometry/core/tags.hpp>
-
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
-#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
-#include <boost/geometry/util/select_most_precise.hpp>
-
+// For backward compatibility
+#include <boost/geometry/strategies/cartesian/disjoint_box_box.hpp>
+#include <boost/geometry/strategies/spherical/disjoint_box_box.hpp>
namespace boost { namespace geometry
{
+
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace disjoint
{
-template
-<
- typename Box1, typename Box2,
- std::size_t Dimension = 0,
- std::size_t DimensionCount = dimension<Box1>::value,
- typename CSTag = typename tag_cast
- <
- typename cs_tag<Box1>::type,
- spherical_tag
- >::type
->
-struct box_box
-{
- template <typename Strategy>
- static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const&)
- {
- return apply(box1, box2);
- }
-
- static inline bool apply(Box1 const& box1, Box2 const& box2)
- {
- if (get<max_corner, Dimension>(box1) < get<min_corner, Dimension>(box2))
- {
- return true;
- }
- if (get<min_corner, Dimension>(box1) > get<max_corner, Dimension>(box2))
- {
- return true;
- }
- return box_box
- <
- Box1, Box2,
- Dimension + 1, DimensionCount
- >::apply(box1, box2);
- }
-};
-
-
-template <typename Box1, typename Box2, std::size_t DimensionCount, typename CSTag>
-struct box_box<Box1, Box2, DimensionCount, DimensionCount, CSTag>
-{
- static inline bool apply(Box1 const& , Box2 const& )
- {
- return false;
- }
-};
-
-
-template <typename Box1, typename Box2, std::size_t DimensionCount>
-struct box_box<Box1, Box2, 0, DimensionCount, spherical_tag>
-{
- template <typename Strategy>
- static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const&)
- {
- return apply(box1, box2);
- }
-
- static inline bool apply(Box1 const& box1, Box2 const& box2)
- {
- typedef typename geometry::select_most_precise
- <
- typename coordinate_type<Box1>::type,
- typename coordinate_type<Box2>::type
- >::type calc_t;
- typedef typename coordinate_system<Box1>::type::units units_t;
- typedef math::detail::constants_on_spheroid<calc_t, units_t> constants;
-
- calc_t const b1_min = get<min_corner, 0>(box1);
- calc_t const b1_max = get<max_corner, 0>(box1);
- calc_t const b2_min = get<min_corner, 0>(box2);
- calc_t const b2_max = get<max_corner, 0>(box2);
-
- // min <= max <=> diff >= 0
- calc_t const diff1 = b1_max - b1_min;
- calc_t const diff2 = b2_max - b2_min;
-
- // check the intersection if neither box cover the whole globe
- if (diff1 < constants::period() && diff2 < constants::period())
- {
- // calculate positive longitude translation with b1_min as origin
- calc_t const diff_min = math::longitude_distance_unsigned<units_t>(b1_min, b2_min);
- calc_t const b2_min_transl = b1_min + diff_min; // always right of b1_min
- calc_t b2_max_transl = b2_min_transl - constants::period() + diff2;
-
- // if the translation is too close then use the original point
- // note that math::abs(b2_max_transl - b2_max) takes values very
- // close to k*2*constants::period() for k=0,1,2,...
- if (math::abs(b2_max_transl - b2_max) < constants::period() / 2)
- {
- b2_max_transl = b2_max;
- }
-
- if (b2_min_transl > b1_max // b2_min right of b1_max
- && b2_max_transl < b1_min) // b2_max left of b1_min
- {
- return true;
- }
- }
-
- return box_box
- <
- Box1, Box2,
- 1, DimensionCount
- >::apply(box1, box2);
- }
-};
-
/*!
\brief Internal utility function to detect if boxes are disjoint
\note Is used from other algorithms, declared separately
to avoid circular references
*/
-template <typename Box1, typename Box2>
-inline bool disjoint_box_box(Box1 const& box1, Box2 const& box2)
+template <typename Box1, typename Box2, typename Strategy>
+inline bool disjoint_box_box(Box1 const& box1, Box2 const& box2, Strategy const&)
{
- return box_box<Box1, Box2>::apply(box1, box2);
+ return Strategy::apply(box1, box2);
}
@@ -170,8 +61,13 @@ namespace dispatch
template <typename Box1, typename Box2, std::size_t DimensionCount>
struct disjoint<Box1, Box2, DimensionCount, box_tag, box_tag, false>
- : detail::disjoint::box_box<Box1, Box2, 0, DimensionCount>
-{};
+{
+ template <typename Strategy>
+ static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const&)
+ {
+ return Strategy::apply(box1, box2);
+ }
+};
} // namespace dispatch
diff --git a/boost/geometry/algorithms/detail/disjoint/linear_areal.hpp b/boost/geometry/algorithms/detail/disjoint/linear_areal.hpp
index e6077d3e7f..55e3fe07fd 100644
--- a/boost/geometry/algorithms/detail/disjoint/linear_areal.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/linear_areal.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013-2017.
-// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013-2018.
+// Modifications copyright (c) 2013-2018, 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
@@ -41,8 +41,9 @@
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
#include <boost/geometry/algorithms/detail/point_on_border.hpp>
-#include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp>
+#include <boost/geometry/algorithms/detail/disjoint/linear_linear.hpp>
#include <boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp>
+#include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp>
#include <boost/geometry/algorithms/detail/disjoint/point_box.hpp>
#include <boost/geometry/algorithms/detail/disjoint/segment_box.hpp>
diff --git a/boost/geometry/algorithms/detail/disjoint/linear_linear.hpp b/boost/geometry/algorithms/detail/disjoint/linear_linear.hpp
index 989b8df247..7b830f7d1f 100644
--- a/boost/geometry/algorithms/detail/disjoint/linear_linear.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/linear_linear.hpp
@@ -93,18 +93,6 @@ struct assign_disjoint_policy
static bool const include_no_turn = true;
static bool const include_degenerate = true;
static bool const include_opposite = true;
-
- // We don't assign extra info:
- template
- <
- typename Info,
- typename Point1,
- typename Point2,
- typename IntersectionInfo
- >
- static inline void apply(Info& , Point1 const& , Point2 const&,
- IntersectionInfo const&)
- {}
};
diff --git a/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp b/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp
index d7aa9089e3..029d68be5b 100644
--- a/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp
@@ -1,8 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014-2017, Oracle and/or its affiliates.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2014-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -138,13 +138,15 @@ private:
EnvelopeStrategy const& m_strategy;
};
+ template <typename DisjointPointBoxStrategy>
struct overlaps_box_point
{
template <typename Box, typename Point>
static inline bool apply(Box const& box, Point const& point)
{
// The default strategy is enough in this case
- return ! detail::disjoint::disjoint_point_box(point, box);
+ return ! detail::disjoint::disjoint_point_box(point, box,
+ DisjointPointBoxStrategy());
}
};
@@ -225,6 +227,7 @@ public:
typedef typename Strategy::envelope_strategy_type envelope_strategy_type;
typedef typename Strategy::disjoint_strategy_type disjoint_strategy_type;
+ typedef typename Strategy::disjoint_point_box_strategy_type disjoint_pb_strategy_type;
// TODO: disjoint Segment/Box may be called in partition multiple times
// possibly for non-cartesian segments which could be slow. We should consider
@@ -236,7 +239,7 @@ public:
geometry::model::box<typename point_type<MultiPoint>::type>
>::apply(multipoint, segment_range(linear), visitor,
expand_box_point(),
- overlaps_box_point(),
+ overlaps_box_point<disjoint_pb_strategy_type>(),
expand_box_segment<envelope_strategy_type>(strategy.get_envelope_strategy()),
overlaps_box_segment<disjoint_strategy_type>(strategy.get_disjoint_strategy()));
@@ -256,8 +259,12 @@ class multi_point_single_geometry
{
public:
template <typename Strategy>
- static inline bool apply(MultiPoint const& multi_point, SingleGeometry const& single_geometry, Strategy const& strategy)
+ static inline bool apply(MultiPoint const& multi_point,
+ SingleGeometry const& single_geometry,
+ Strategy const& strategy)
{
+ typedef typename Strategy::disjoint_point_box_strategy_type d_pb_strategy_type;
+
typedef typename point_type<MultiPoint>::type point1_type;
typedef typename point_type<SingleGeometry>::type point2_type;
typedef model::box<point2_type> box2_type;
@@ -270,7 +277,7 @@ public:
for ( iterator it = boost::begin(multi_point) ; it != boost::end(multi_point) ; ++it )
{
// The default strategy is enough for Point/Box
- if (! detail::disjoint::disjoint_point_box(*it, box2)
+ if (! detail::disjoint::disjoint_point_box(*it, box2, d_pb_strategy_type())
&& ! dispatch::disjoint<point1_type, SingleGeometry>::apply(*it, single_geometry, strategy))
{
return false;
@@ -310,23 +317,27 @@ private:
}
};
+ template <typename DisjointPointBoxStrategy>
struct overlaps_box_point
{
template <typename Box, typename Point>
static inline bool apply(Box const& box, Point const& point)
{
// The default strategy is enough for Point/Box
- return ! detail::disjoint::disjoint_point_box(point, box);
+ return ! detail::disjoint::disjoint_point_box(point, box,
+ DisjointPointBoxStrategy());
}
};
+ template <typename DisjointBoxBoxStrategy>
struct overlaps_box_box_pair
{
template <typename Box, typename BoxPair>
inline bool apply(Box const& box, BoxPair const& box_pair) const
{
// The default strategy is enough for Box/Box
- return ! detail::disjoint::disjoint_box_box(box_pair.first, box);
+ return ! detail::disjoint::disjoint_box_box(box_pair.first, box,
+ DisjointBoxBoxStrategy());
}
};
@@ -344,11 +355,13 @@ private:
template <typename Point, typename BoxPair>
inline bool apply(Point const& point, BoxPair const& box_pair)
{
+ typedef typename PtSegStrategy::disjoint_point_box_strategy_type d_pb_strategy_type;
+
typedef typename boost::range_value<MultiGeometry>::type single_type;
// The default strategy is enough for Point/Box
if (! m_intersection_found
- && ! detail::disjoint::disjoint_point_box(point, box_pair.first)
+ && ! detail::disjoint::disjoint_point_box(point, box_pair.first, d_pb_strategy_type())
&& ! dispatch::disjoint<Point, single_type>::apply(point, range::at(m_multi_geometry, box_pair.second), m_strategy))
{
m_intersection_found = true;
@@ -390,14 +403,23 @@ public:
item_visitor_type<Strategy> visitor(multi_geometry, strategy);
+ typedef overlaps_box_point
+ <
+ typename Strategy::disjoint_point_box_strategy_type
+ > overlaps_box_point_type;
+ typedef overlaps_box_box_pair
+ <
+ typename Strategy::disjoint_box_box_strategy_type
+ > overlaps_box_box_pair_type;
+
geometry::partition
<
box1_type
>::apply(multi_point, boxes, visitor,
expand_box_point(),
- overlaps_box_point(),
+ overlaps_box_point_type(),
expand_box_box_pair(),
- overlaps_box_box_pair());
+ overlaps_box_box_pair_type());
return ! visitor.intersection_found();
}
diff --git a/boost/geometry/algorithms/detail/disjoint/point_box.hpp b/boost/geometry/algorithms/detail/disjoint/point_box.hpp
index 2e6773d221..b4c4026467 100644
--- a/boost/geometry/algorithms/detail/disjoint/point_box.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/point_box.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland
-// This file was modified by Oracle on 2013-2017.
-// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013-2018.
+// Modifications copyright (c) 2013-2018, 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
@@ -41,16 +41,11 @@ namespace detail { namespace disjoint
/*!
\brief Internal utility function to detect if point/box are disjoint
*/
-template <typename Point, typename Box>
-inline bool disjoint_point_box(Point const& point, Box const& box)
+template <typename Point, typename Box, typename Strategy>
+inline bool disjoint_point_box(Point const& point, Box const& box, Strategy const& )
{
- typedef typename strategy::disjoint::services::default_strategy
- <
- Point, Box
- >::type strategy_type;
-
// ! covered_by(point, box)
- return ! strategy_type::apply(point, box);
+ return ! Strategy::apply(point, box);
}
diff --git a/boost/geometry/algorithms/detail/disjoint/point_point.hpp b/boost/geometry/algorithms/detail/disjoint/point_point.hpp
index 13ac34d718..f91712934b 100644
--- a/boost/geometry/algorithms/detail/disjoint/point_point.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/point_point.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland
-// This file was modified by Oracle on 2013, 2014, 2015, 2017.
-// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018.
+// Modifications copyright (c) 2013-2018, 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,29 +23,15 @@
#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>
+// For backward compatibility
+#include <boost/geometry/strategies/disjoint.hpp>
+#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
+#include <boost/geometry/strategies/spherical/point_in_point.hpp>
+
namespace boost { namespace geometry
{
@@ -56,169 +42,15 @@ namespace detail { namespace disjoint
{
-template <std::size_t Dimension, std::size_t DimensionCount>
-struct point_point_generic
-{
- template <typename Point1, typename Point2, typename Strategy>
- static inline bool apply(Point1 const& p1, Point2 const& p2, Strategy const& )
- {
- return apply(p1, p2);
- }
-
- template <typename Point1, typename Point2>
- static inline bool apply(Point1 const& p1, Point2 const& p2)
- {
- if (! geometry::math::equals(get<Dimension>(p1), get<Dimension>(p2)))
- {
- return true;
- }
- return
- point_point_generic<Dimension + 1, DimensionCount>::apply(p1, p2);
- }
-};
-
-template <std::size_t DimensionCount>
-struct point_point_generic<DimensionCount, DimensionCount>
-{
- 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, typename Strategy>
- static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& )
- {
- return apply(point1, point2);
- }
-
- template <typename Point1, typename Point2>
- static inline bool apply(Point1 const& point1, Point2 const& point2)
- {
- 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
*/
-template <typename Point1, typename Point2>
-inline bool disjoint_point_point(Point1 const& point1, Point2 const& point2)
+template <typename Point1, typename Point2, typename Strategy>
+inline bool disjoint_point_point(Point1 const& point1, Point2 const& point2,
+ Strategy const& )
{
- return point_point
- <
- Point1, Point2,
- 0, dimension<Point1>::type::value
- >::apply(point1, point2);
+ return ! Strategy::apply(point1, point2);
}
@@ -226,8 +58,6 @@ inline bool disjoint_point_point(Point1 const& point1, Point2 const& point2)
#endif // DOXYGEN_NO_DETAIL
-
-
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
@@ -235,8 +65,14 @@ namespace dispatch
template <typename Point1, typename Point2, std::size_t DimensionCount>
struct disjoint<Point1, Point2, DimensionCount, point_tag, point_tag, false>
- : detail::disjoint::point_point<Point1, Point2, 0, DimensionCount>
-{};
+{
+ template <typename Strategy>
+ static inline bool apply(Point1 const& point1, Point2 const& point2,
+ Strategy const& )
+ {
+ return ! Strategy::apply(point1, point2);
+ }
+};
} // namespace dispatch
diff --git a/boost/geometry/algorithms/detail/disjoint/segment_box.hpp b/boost/geometry/algorithms/detail/disjoint/segment_box.hpp
index baa4cf83dd..ea51f6be7a 100644
--- a/boost/geometry/algorithms/detail/disjoint/segment_box.hpp
+++ b/boost/geometry/algorithms/detail/disjoint/segment_box.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013-2017.
-// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013-2019.
+// Modifications copyright (c) 2013-2019, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -39,6 +39,9 @@
#include <boost/geometry/geometries/box.hpp>
+// Temporary, for envelope_segment_impl
+#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
+
namespace boost { namespace geometry
{
@@ -50,21 +53,6 @@ namespace detail { namespace disjoint
template <typename CS_Tag>
struct disjoint_segment_box_sphere_or_spheroid
{
-private:
-
- template <typename CT>
- static inline void swap(CT& lon1,
- CT& lat1,
- CT& lon2,
- CT& lat2)
- {
- std::swap(lon1, lon2);
- std::swap(lat1, lat2);
- }
-
-
-public:
-
struct disjoint_info
{
enum type
@@ -82,26 +70,50 @@ public:
operator T () const;
};
- template <typename Segment, typename Box, typename Strategy>
+ template
+ <
+ typename Segment, typename Box,
+ typename AzimuthStrategy,
+ typename NormalizeStrategy,
+ typename DisjointPointBoxStrategy,
+ typename DisjointBoxBoxStrategy
+ >
static inline bool apply(Segment const& segment,
Box const& box,
- Strategy const& azimuth_strategy)
+ AzimuthStrategy const& azimuth_strategy,
+ NormalizeStrategy const& normalize_strategy,
+ DisjointPointBoxStrategy const& disjoint_point_box_strategy,
+ DisjointBoxBoxStrategy const& disjoint_box_box_strategy)
{
typedef typename point_type<Segment>::type segment_point;
segment_point vertex;
- return (apply(segment, box, azimuth_strategy, vertex) != disjoint_info::intersect);
+ return apply(segment, box, vertex,
+ azimuth_strategy,
+ normalize_strategy,
+ disjoint_point_box_strategy,
+ disjoint_box_box_strategy) != disjoint_info::intersect;
}
- template <typename Segment, typename Box, typename Strategy, typename P>
+ template
+ <
+ typename Segment, typename Box,
+ typename P,
+ typename AzimuthStrategy,
+ typename NormalizeStrategy,
+ typename DisjointPointBoxStrategy,
+ typename DisjointBoxBoxStrategy
+ >
static inline disjoint_info apply(Segment const& segment,
Box const& box,
- Strategy const& azimuth_strategy,
- P& vertex)
+ P& vertex,
+ AzimuthStrategy const& azimuth_strategy,
+ NormalizeStrategy const& ,
+ DisjointPointBoxStrategy const& disjoint_point_box_strategy,
+ DisjointBoxBoxStrategy const& disjoint_box_box_strategy)
{
assert_dimension_equal<Segment, Box>();
typedef typename point_type<Segment>::type segment_point_type;
- typedef typename cs_tag<Segment>::type segment_cs_type;
segment_point_type p0, p1;
geometry::detail::assign_point_from_index<0>(segment, p0);
@@ -113,7 +125,8 @@ public:
// Simplest cases first
// Case 1: if box contains one of segment's endpoints then they are not disjoint
- if (! disjoint_point_box(p0, box) || ! disjoint_point_box(p1, box))
+ if ( ! disjoint_point_box(p0, box, disjoint_point_box_strategy)
+ || ! disjoint_point_box(p1, box, disjoint_point_box_strategy) )
{
return disjoint_info::intersect;
}
@@ -122,10 +135,10 @@ public:
typedef typename coordinate_type<segment_point_type>::type CT;
- segment_point_type p0_normalized =
- geometry::detail::return_normalized<segment_point_type>(p0);
- segment_point_type p1_normalized =
- geometry::detail::return_normalized<segment_point_type>(p1);
+ segment_point_type p0_normalized;
+ NormalizeStrategy::apply(p0, p0_normalized);
+ segment_point_type p1_normalized;
+ NormalizeStrategy::apply(p1, p1_normalized);
CT lon1 = geometry::get_as_radian<0>(p0_normalized);
CT lat1 = geometry::get_as_radian<1>(p0_normalized);
@@ -134,38 +147,35 @@ public:
if (lon1 > lon2)
{
- swap(lon1, lat1, lon2, lat2);
+ std::swap(lon1, lon2);
+ std::swap(lat1, lat2);
}
- //Compute alp1 outside envelope and pass it to envelope_segment_impl
- //in order for it to be used later in the algorithm
- CT alp1;
-
- azimuth_strategy.apply(lon1, lat1, lon2, lat2, alp1);
-
geometry::model::box<segment_point_type> box_seg;
- geometry::detail::envelope::envelope_segment_impl<segment_cs_type>
- ::template apply<geometry::radian>(lon1, lat1,
- lon2, lat2,
- box_seg,
- azimuth_strategy,
- alp1);
+ strategy::envelope::detail::envelope_segment_impl
+ <
+ CS_Tag
+ >::template apply<geometry::radian>(lon1, lat1,
+ lon2, lat2,
+ box_seg,
+ azimuth_strategy);
- if (disjoint_box_box(box, box_seg))
+ if (disjoint_box_box(box, box_seg, disjoint_box_box_strategy))
{
return disjoint_return_value;
}
// Case 3: test intersection by comparing angles
- CT a_b0, a_b1, a_b2, a_b3;
+ CT alp1, a_b0, a_b1, a_b2, a_b3;
CT b_lon_min = geometry::get_as_radian<geometry::min_corner, 0>(box);
CT b_lat_min = geometry::get_as_radian<geometry::min_corner, 1>(box);
CT b_lon_max = geometry::get_as_radian<geometry::max_corner, 0>(box);
CT b_lat_max = geometry::get_as_radian<geometry::max_corner, 1>(box);
+ azimuth_strategy.apply(lon1, lat1, lon2, lat2, alp1);
azimuth_strategy.apply(lon1, lat1, b_lon_min, b_lat_min, a_b0);
azimuth_strategy.apply(lon1, lat1, b_lon_max, b_lat_min, a_b1);
azimuth_strategy.apply(lon1, lat1, b_lon_min, b_lat_max, a_b2);
diff --git a/boost/geometry/algorithms/detail/distance/interface.hpp b/boost/geometry/algorithms/detail/distance/interface.hpp
index 4122ecfe17..2338abbeb5 100644
--- a/boost/geometry/algorithms/detail/distance/interface.hpp
+++ b/boost/geometry/algorithms/detail/distance/interface.hpp
@@ -95,9 +95,10 @@ struct distance
namespace resolve_strategy
{
+template <typename Strategy>
struct distance
{
- template <typename Geometry1, typename Geometry2, typename Strategy>
+ template <typename Geometry1, typename Geometry2>
static inline typename distance_result<Geometry1, Geometry2, Strategy>::type
apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
@@ -108,7 +109,11 @@ struct distance
Geometry1, Geometry2, Strategy
>::apply(geometry1, geometry2, strategy);
}
+};
+template <>
+struct distance<default_strategy>
+{
template <typename Geometry1, typename Geometry2>
static inline
typename distance_result<Geometry1, Geometry2, default_strategy>::type
@@ -144,8 +149,10 @@ struct distance
Geometry2 const& geometry2,
Strategy const& strategy)
{
- return
- resolve_strategy::distance::apply(geometry1, geometry2, strategy);
+ return resolve_strategy::distance
+ <
+ Strategy
+ >::apply(geometry1, geometry2, strategy);
}
};
diff --git a/boost/geometry/algorithms/detail/distance/point_to_geometry.hpp b/boost/geometry/algorithms/detail/distance/point_to_geometry.hpp
index 9596799cb2..f41cf5c764 100644
--- a/boost/geometry/algorithms/detail/distance/point_to_geometry.hpp
+++ b/boost/geometry/algorithms/detail/distance/point_to_geometry.hpp
@@ -5,10 +5,11 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2019.
+// Modifications copyright (c) 2014-2019, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -39,13 +40,12 @@
#include <boost/geometry/strategies/tags.hpp>
#include <boost/geometry/algorithms/assign.hpp>
-#include <boost/geometry/algorithms/covered_by.hpp>
-#include <boost/geometry/algorithms/within.hpp>
#include <boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp>
#include <boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp>
#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
#include <boost/geometry/algorithms/detail/distance/iterator_selector.hpp>
+#include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
#include <boost/geometry/algorithms/dispatch/distance.hpp>
@@ -160,7 +160,8 @@ struct point_to_ring
Ring const& ring,
Strategy const& strategy)
{
- if (geometry::within(point, ring))
+ // TODO: pass strategy
+ if (within::within_point_geometry(point, ring))
{
return return_type(0);
}
@@ -204,7 +205,8 @@ private:
{
for (InteriorRingIterator it = first; it != last; ++it)
{
- if (geometry::within(point, *it))
+ // TODO: pass strategy
+ if (within::within_point_geometry(point, *it))
{
// the point is inside a polygon hole, so its distance
// to the polygon its distance to the polygon's
@@ -233,7 +235,8 @@ public:
Polygon const& polygon,
Strategy const& strategy)
{
- if (!geometry::covered_by(point, exterior_ring(polygon)))
+ // TODO: pass strategy
+ if (! within::covered_by_point_geometry(point, exterior_ring(polygon)))
{
// the point is outside the exterior ring, so its distance
// to the polygon is its distance to the polygon's exterior ring
@@ -330,7 +333,8 @@ struct point_to_multigeometry<Point, MultiPolygon, Strategy, true>
MultiPolygon const& multipolygon,
Strategy const& strategy)
{
- if (geometry::covered_by(point, multipolygon))
+ // TODO: pass strategy
+ if (within::covered_by_point_geometry(point, multipolygon))
{
return 0;
}
diff --git a/boost/geometry/algorithms/detail/distance/segment_to_box.hpp b/boost/geometry/algorithms/detail/distance/segment_to_box.hpp
index bfe52c7b1b..d88a6699c8 100644
--- a/boost/geometry/algorithms/detail/distance/segment_to_box.hpp
+++ b/boost/geometry/algorithms/detail/distance/segment_to_box.hpp
@@ -1,15 +1,17 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014-2018 Oracle and/or its affiliates.
+// Copyright (c) 2014-2019 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_BOX_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_BOX_HPP
+
#include <cstddef>
#include <functional>
@@ -27,26 +29,27 @@
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
+#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
+#include <boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp>
+#include <boost/geometry/algorithms/detail/disjoint/segment_box.hpp>
+#include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
+#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
+#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
+#include <boost/geometry/algorithms/dispatch/distance.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+#include <boost/geometry/policies/compare.hpp>
+
#include <boost/geometry/util/calculation_type.hpp>
#include <boost/geometry/util/condition.hpp>
+#include <boost/geometry/util/has_nan_coordinate.hpp>
#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/strategies/disjoint.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/tags.hpp>
-#include <boost/geometry/policies/compare.hpp>
-
-#include <boost/geometry/algorithms/equals.hpp>
-#include <boost/geometry/algorithms/intersects.hpp>
-#include <boost/geometry/algorithms/not_implemented.hpp>
-
-#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
-#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
-#include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
-#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
-
-#include <boost/geometry/algorithms/dispatch/distance.hpp>
-
namespace boost { namespace geometry
{
@@ -57,6 +60,20 @@ namespace detail { namespace distance
{
+// TODO: Take strategy
+template <typename Segment, typename Box>
+inline bool intersects_segment_box(Segment const& segment, Box const& box)
+{
+ typedef typename strategy::disjoint::services::default_strategy
+ <
+ Segment, Box
+ >::type strategy_type;
+
+ return ! detail::disjoint::disjoint_segment_box::apply(segment, box,
+ strategy_type());
+}
+
+
template
<
typename Segment,
@@ -99,7 +116,7 @@ public:
Strategy const& strategy,
bool check_intersection = true)
{
- if (check_intersection && geometry::intersects(segment, box))
+ if (check_intersection && intersects_segment_box(segment, box))
{
return 0;
}
@@ -214,7 +231,7 @@ public:
Strategy const& strategy,
bool check_intersection = true)
{
- if (check_intersection && geometry::intersects(segment, box))
+ if (check_intersection && intersects_segment_box(segment, box))
{
return 0;
}
@@ -753,7 +770,8 @@ public:
detail::assign_point_from_index<0>(segment, p[0]);
detail::assign_point_from_index<1>(segment, p[1]);
- if (geometry::equals(p[0], p[1]))
+ if (detail::equals::equals_point_point(p[0], p[1],
+ sb_strategy.get_equals_point_point_strategy()))
{
typedef typename boost::mpl::if_
<
diff --git a/boost/geometry/algorithms/detail/envelope/areal.hpp b/boost/geometry/algorithms/detail/envelope/areal.hpp
index 034a98c0ae..3c9b5c576c 100644
--- a/boost/geometry/algorithms/detail/envelope/areal.hpp
+++ b/boost/geometry/algorithms/detail/envelope/areal.hpp
@@ -3,6 +3,7 @@
// Copyright (c) 2018 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -28,7 +29,6 @@ namespace boost { namespace geometry
namespace detail { namespace envelope
{
-template <typename EnvelopePolicy>
struct envelope_polygon
{
template <typename Polygon, typename Box, typename Strategy>
@@ -42,13 +42,13 @@ struct envelope_polygon
// if the exterior ring is empty, consider the interior rings
envelope_multi_range
<
- EnvelopePolicy
+ envelope_range
>::apply(interior_rings(polygon), mbr, strategy);
}
else
{
// otherwise, consider only the exterior ring
- EnvelopePolicy::apply(ext_ring, mbr, strategy);
+ envelope_range::apply(ext_ring, mbr, strategy);
}
}
};
@@ -62,77 +62,21 @@ namespace dispatch
{
-template <typename Ring, typename CS_Tag>
-struct envelope<Ring, ring_tag, CS_Tag>
- : detail::envelope::envelope_range
-{};
-
template <typename Ring>
-struct envelope<Ring, ring_tag, spherical_equatorial_tag>
- : detail::envelope::envelope_linestring_or_ring_on_spheroid
-{};
-
-template <typename Ring>
-struct envelope<Ring, ring_tag, geographic_tag>
- : detail::envelope::envelope_linestring_or_ring_on_spheroid
-{};
-
-
-template <typename Polygon, typename CS_Tag>
-struct envelope<Polygon, polygon_tag, CS_Tag>
- : detail::envelope::envelope_polygon
- <
- detail::envelope::envelope_range
- >
-{};
-
-template <typename Polygon>
-struct envelope<Polygon, polygon_tag, spherical_equatorial_tag>
- : detail::envelope::envelope_polygon
- <
- detail::envelope::envelope_linestring_or_ring_on_spheroid
- >
+struct envelope<Ring, ring_tag>
+ : detail::envelope::envelope_range
{};
template <typename Polygon>
-struct envelope<Polygon, polygon_tag, geographic_tag>
+struct envelope<Polygon, polygon_tag>
: detail::envelope::envelope_polygon
- <
- detail::envelope::envelope_linestring_or_ring_on_spheroid
- >
-{};
-
-
-template <typename MultiPolygon, typename CS_Tag>
-struct envelope<MultiPolygon, multi_polygon_tag, CS_Tag>
- : detail::envelope::envelope_multi_range
- <
- detail::envelope::envelope_polygon
- <
- detail::envelope::envelope_range
- >
- >
-{};
-
-template <typename MultiPolygon>
-struct envelope<MultiPolygon, multi_polygon_tag, spherical_equatorial_tag>
- : detail::envelope::envelope_multi_range
- <
- detail::envelope::envelope_polygon
- <
- detail::envelope::envelope_linestring_or_ring_on_spheroid
- >
- >
{};
template <typename MultiPolygon>
-struct envelope<MultiPolygon, multi_polygon_tag, geographic_tag>
+struct envelope<MultiPolygon, multi_polygon_tag>
: detail::envelope::envelope_multi_range
<
detail::envelope::envelope_polygon
- <
- detail::envelope::envelope_linestring_or_ring_on_spheroid
- >
>
{};
diff --git a/boost/geometry/algorithms/detail/envelope/box.hpp b/boost/geometry/algorithms/detail/envelope/box.hpp
index cf039a292a..b085a14b9d 100644
--- a/boost/geometry/algorithms/detail/envelope/box.hpp
+++ b/boost/geometry/algorithms/detail/envelope/box.hpp
@@ -18,164 +18,34 @@
#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>
+// For backward compatibility
+#include <boost/geometry/strategies/cartesian/envelope_box.hpp>
+#include <boost/geometry/strategies/spherical/envelope_box.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
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
{
- 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 Box>
+struct envelope<Box, box_tag>
{
template<typename BoxIn, typename BoxOut, typename Strategy>
- static inline void apply(BoxIn const& box_in,
- BoxOut& mbr,
- Strategy const&)
+ static inline void apply(BoxIn const& box_in, BoxOut& mbr, Strategy const& )
{
- 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);
+ Strategy::apply(box_in, mbr);
}
};
-struct envelope_box_on_spheroid
-{
- template <typename BoxIn, typename BoxOut, typename Strategy>
- static inline void apply(BoxIn const& box_in,
- BoxOut& mbr,
- Strategy const&)
- {
- BoxIn box_in_normalized = box_in;
-
- if (!is_inverse_spheroidal_coordinates(box_in))
- {
- 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>
-struct envelope<Box, box_tag, cartesian_tag>
- : detail::envelope::envelope_box
-{};
-
-
-template <typename Box>
-struct envelope<Box, box_tag, spherical_polar_tag>
- : detail::envelope::envelope_box_on_spheroid
-{};
-
-
-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
diff --git a/boost/geometry/algorithms/detail/envelope/interface.hpp b/boost/geometry/algorithms/detail/envelope/interface.hpp
index 8e9c35b395..28c815f4c2 100644
--- a/boost/geometry/algorithms/detail/envelope/interface.hpp
+++ b/boost/geometry/algorithms/detail/envelope/interface.hpp
@@ -4,8 +4,8 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2015, 2016, 2017.
-// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2016, 2017, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -21,19 +21,24 @@
#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>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
#include <boost/geometry/strategies/default_strategy.hpp>
#include <boost/geometry/strategies/envelope.hpp>
-#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
-#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
-#include <boost/geometry/strategies/geographic/envelope_segment.hpp>
+
+#include <boost/geometry/util/select_most_precise.hpp>
+
namespace boost { namespace geometry
{
@@ -57,13 +62,15 @@ struct envelope
Box& box,
default_strategy)
{
- typedef typename point_type<Geometry>::type point_type;
- typedef typename coordinate_type<point_type>::type coordinate_type;
-
typedef typename strategy::envelope::services::default_strategy
<
- typename cs_tag<point_type>::type,
- coordinate_type
+ typename tag<Geometry>::type,
+ typename cs_tag<Geometry>::type,
+ typename select_most_precise
+ <
+ typename coordinate_type<Geometry>::type,
+ typename coordinate_type<Box>::type
+ >::type
>::type strategy_type;
dispatch::envelope<Geometry>::apply(geometry, box, strategy_type());
diff --git a/boost/geometry/algorithms/detail/envelope/linear.hpp b/boost/geometry/algorithms/detail/envelope/linear.hpp
index 7fa788b738..e2f05f2e3a 100644
--- a/boost/geometry/algorithms/detail/envelope/linear.hpp
+++ b/boost/geometry/algorithms/detail/envelope/linear.hpp
@@ -4,11 +4,12 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2015, 2016.
-// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2016, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -17,92 +18,40 @@
#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/core/tags.hpp>
#include <boost/geometry/algorithms/detail/envelope/range.hpp>
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
+// For backward compatibility
+#include <boost/geometry/strategies/cartesian/envelope.hpp>
+#include <boost/geometry/strategies/spherical/envelope.hpp>
+#include <boost/geometry/strategies/geographic/envelope.hpp>
namespace boost { namespace geometry
{
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace envelope
-{
-
-struct envelope_linestring_or_ring_on_spheroid
-{
- template <typename LinestringRing, typename Box, typename Strategy>
- static inline void apply(LinestringRing const& linestring_or_ring,
- Box& mbr,
- Strategy const& strategy)
- {
- envelope_range::apply(geometry::segments_begin(linestring_or_ring),
- geometry::segments_end(linestring_or_ring),
- mbr,
- strategy);
- }
-};
-
-
-}} // 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_or_ring_on_spheroid
-{};
-
template <typename Linestring>
-struct envelope<Linestring, linestring_tag, geographic_tag>
- : detail::envelope::envelope_linestring_or_ring_on_spheroid
+struct envelope<Linestring, linestring_tag>
+ : detail::envelope::envelope_range
{};
-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
+struct envelope<MultiLinestring, multi_linestring_tag>
+ : detail::envelope::envelope_multi_range
<
- detail::envelope::envelope_linestring_or_ring_on_spheroid
+ detail::envelope::envelope_range
>
{};
-template <typename MultiLinestring>
-struct envelope
- <
- MultiLinestring, multi_linestring_tag, geographic_tag
- > : detail::envelope::envelope_multi_range_on_spheroid
- <
- detail::envelope::envelope_linestring_or_ring_on_spheroid
- >
-{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
diff --git a/boost/geometry/algorithms/detail/envelope/multipoint.hpp b/boost/geometry/algorithms/detail/envelope/multipoint.hpp
index eef7563796..ce112e4d78 100644
--- a/boost/geometry/algorithms/detail/envelope/multipoint.hpp
+++ b/boost/geometry/algorithms/detail/envelope/multipoint.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2015-2017, Oracle and/or its affiliates.
+// Copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -13,361 +13,32 @@
#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>
+// For backward compatibility
+#include <boost/geometry/strategies/cartesian/envelope_multipoint.hpp>
+#include <boost/geometry/strategies/spherical/envelope_multipoint.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, typename Strategy>
- static inline void apply(MultiPoint const& multipoint, Box& mbr, Strategy const& strategy)
- {
- typedef typename point_type<MultiPoint>::type point_type;
- typedef typename coordinate_type<MultiPoint>::type coordinate_type;
- 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, strategy);
- }
-
- // 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, strategy);
-
- for (++it; it != boost::end(multipoint); ++it)
- {
- detail::expand::point_loop
- <
- 2, dimension<Box>::value
- >::apply(mbr, *it, strategy);
- }
- }
-};
-
-
-}} // 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
-{};
+struct envelope<MultiPoint, multi_point_tag>
+{
+ template <typename Box, typename Strategy>
+ static inline void apply(MultiPoint const& multipoint, Box& mbr, Strategy const& )
+ {
+ Strategy::apply(multipoint, mbr);
+ }
+};
} // namespace dispatch
diff --git a/boost/geometry/algorithms/detail/envelope/point.hpp b/boost/geometry/algorithms/detail/envelope/point.hpp
index 86e73f3aa3..164274a280 100644
--- a/boost/geometry/algorithms/detail/envelope/point.hpp
+++ b/boost/geometry/algorithms/detail/envelope/point.hpp
@@ -4,8 +4,8 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2015, 2016, 2017.
-// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2016, 2017, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -18,23 +18,14 @@
#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>
+// For backward compatibility
+#include <boost/geometry/strategies/cartesian/envelope_point.hpp>
+#include <boost/geometry/strategies/spherical/envelope_point.hpp>
+
namespace boost { namespace geometry
{
@@ -44,53 +35,12 @@ namespace detail { namespace envelope
{
-template <std::size_t Dimension, std::size_t DimensionCount>
-struct envelope_one_point
+struct envelope_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, typename Strategy>
- static inline void apply(Point const& point, Box& mbr, Strategy const&)
+ static inline void apply(Point const& point, Box& mbr, Strategy const& )
{
- apply<min_corner>(point, mbr);
- apply<max_corner>(point, mbr);
- }
-};
-
-
-struct envelope_point_on_spheroid
-{
- template<typename Point, typename Box, typename Strategy>
- static inline void apply(Point const& point, Box& mbr, Strategy const& strategy)
- {
- Point normalized_point = detail::return_normalized<Point>(point);
-
- 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, strategy);
+ Strategy::apply(point, mbr);
}
};
@@ -104,26 +54,8 @@ namespace dispatch
template <typename Point>
-struct envelope<Point, point_tag, cartesian_tag>
- : detail::envelope::envelope_one_point<0, dimension<Point>::value>
-{};
-
-
-template <typename Point>
-struct envelope<Point, point_tag, spherical_polar_tag>
- : detail::envelope::envelope_point_on_spheroid
-{};
-
-
-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
+struct envelope<Point, point_tag>
+ : detail::envelope::envelope_point
{};
diff --git a/boost/geometry/algorithms/detail/envelope/range.hpp b/boost/geometry/algorithms/detail/envelope/range.hpp
index b5591f61ab..2d33600d0f 100644
--- a/boost/geometry/algorithms/detail/envelope/range.hpp
+++ b/boost/geometry/algorithms/detail/envelope/range.hpp
@@ -4,11 +4,12 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2015, 2016.
-// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2016, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -23,23 +24,17 @@
#include <iterator>
#include <vector>
-#include <boost/range.hpp>
-
-#include <boost/geometry/core/coordinate_dimension.hpp>
-
-#include <boost/geometry/util/range.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.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>
-
+#include <boost/geometry/core/coordinate_dimension.hpp>
namespace boost { namespace geometry
{
@@ -53,7 +48,7 @@ namespace detail { namespace envelope
struct envelope_range
{
template <typename Iterator, typename Box, typename Strategy>
- static inline void apply(Iterator first,
+ static inline void apply(Iterator it,
Iterator last,
Box& mbr,
Strategy const& strategy)
@@ -63,16 +58,21 @@ struct envelope_range
// 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, strategy);
+ dispatch::envelope
+ <
+ value_type
+ >::apply(*it, mbr, strategy.get_element_envelope_strategy());
// consider now the remaining elements in the range (if any)
for (++it; it != last; ++it)
{
- dispatch::expand<Box, value_type>::apply(mbr, *it, strategy);
+ dispatch::expand
+ <
+ Box, value_type
+ >::apply(mbr, *it, strategy.get_element_expand_strategy());
}
}
}
@@ -80,7 +80,7 @@ struct envelope_range
template <typename Range, typename Box, typename Strategy>
static inline void apply(Range const& range, Box& mbr, Strategy const& strategy)
{
- return apply(boost::begin(range), boost::end(range), mbr, strategy);
+ return apply(Strategy::begin(range), Strategy::end(range), mbr, strategy);
}
};
@@ -94,86 +94,26 @@ struct envelope_multi_range
Box& mbr,
Strategy const& strategy)
{
- 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, strategy);
-
- dispatch::expand<Box, Box>::apply(mbr, helper_mbr, strategy);
- }
- else
- {
- // compute the initial envelope
- EnvelopePolicy::apply(*it, mbr, strategy);
- initialized = true;
- }
- }
- }
-
- if (! initialized)
- {
- // if not already initialized, initialize MBR
- initialize<Box, 0, dimension<Box>::value>::apply(mbr);
- }
+ apply(boost::begin(multirange), boost::end(multirange), mbr, strategy);
}
-};
-
-// implementation for multi-range on a spheroid (longitude is periodic)
-template <typename EnvelopePolicy>
-struct envelope_multi_range_on_spheroid
-{
- template <typename MultiRange, typename Box, typename Strategy>
- static inline void apply(MultiRange const& multirange,
+ template <typename Iter, typename Box, typename Strategy>
+ static inline void apply(Iter it,
+ Iter last,
Box& mbr,
Strategy const& strategy)
{
- 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)
+ typename Strategy::template multi_state<Box> state;
+ for (; it != last; ++it)
{
if (! geometry::is_empty(*it))
{
- Box helper_box;
- EnvelopePolicy::apply(*it, helper_box, strategy);
- boxes.push_back(helper_box);
+ Box helper_mbr;
+ EnvelopePolicy::apply(*it, helper_mbr, strategy);
+ state.apply(helper_mbr);
}
}
-
- // 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, strategy);
- }
- else
- {
- initialize<Box, 0, dimension<Box>::value>::apply(mbr);
- }
-
+ state.result(mbr);
}
};
diff --git a/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp b/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp
index 92d1fe3959..28e76c4458 100644
--- a/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp
+++ b/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp
@@ -20,17 +20,20 @@
#include <boost/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>
+
#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/normalize_spheroidal_coordinates.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>
+#include <boost/geometry/views/detail/indexed_point_view.hpp>
namespace boost { namespace geometry
@@ -151,10 +154,8 @@ struct envelope_range_of_longitudes
template <std::size_t Dimension, std::size_t DimensionCount>
struct envelope_range_of_boxes_by_expansion
{
- template <typename RangeOfBoxes, typename Box, typename Strategy>
- static inline void apply(RangeOfBoxes const& range_of_boxes,
- Box& mbr,
- Strategy const& strategy)
+ 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;
@@ -198,14 +199,14 @@ struct envelope_range_of_boxes_by_expansion
min_corner,
Dimension,
DimensionCount
- >::apply(mbr, *it, strategy);
+ >::apply(mbr, *it);
detail::expand::indexed_loop
<
max_corner,
Dimension,
DimensionCount
- >::apply(mbr, *it, strategy);
+ >::apply(mbr, *it);
}
}
@@ -225,16 +226,14 @@ struct envelope_range_of_boxes
}
};
- template <typename RangeOfBoxes, typename Box, typename Strategy>
- static inline void apply(RangeOfBoxes const& range_of_boxes,
- Box& mbr,
- Strategy const& strategy)
+ 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 detail::cs_angular_units<box_type>::type units_type;
typedef typename boost::range_iterator
<
RangeOfBoxes const
@@ -326,7 +325,7 @@ struct envelope_range_of_boxes
envelope_range_of_boxes_by_expansion
<
2, dimension<Box>::value
- >::apply(range_of_boxes, mbr, strategy);
+ >::apply(range_of_boxes, mbr);
}
};
diff --git a/boost/geometry/algorithms/detail/envelope/segment.hpp b/boost/geometry/algorithms/detail/envelope/segment.hpp
index cfa139a087..af79f34508 100644
--- a/boost/geometry/algorithms/detail/envelope/segment.hpp
+++ b/boost/geometry/algorithms/detail/envelope/segment.hpp
@@ -19,33 +19,17 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_SEGMENT_HPP
#include <cstddef>
-#include <utility>
-#include <boost/core/ignore_unused.hpp>
-#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/formulas/meridian_segment.hpp>
-#include <boost/geometry/formulas/vertex_latitude.hpp>
-
#include <boost/geometry/algorithms/detail/assign_indexed_point.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>
+// For backward compatibility
+#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
+#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
+#include <boost/geometry/strategies/geographic/envelope_segment.hpp>
+
namespace boost { namespace geometry
{
@@ -53,385 +37,6 @@ namespace boost { namespace geometry
namespace detail { namespace envelope
{
-template <typename CalculationType, typename CS_Tag>
-struct envelope_segment_call_vertex_latitude
-{
- template <typename T1, typename T2, typename Strategy>
- static inline CalculationType apply(T1 const& lat1,
- T2 const& alp1,
- Strategy const& )
- {
- return geometry::formula::vertex_latitude<CalculationType, CS_Tag>
- ::apply(lat1, alp1);
- }
-};
-
-template <typename CalculationType>
-struct envelope_segment_call_vertex_latitude<CalculationType, geographic_tag>
-{
- template <typename T1, typename T2, typename Strategy>
- static inline CalculationType apply(T1 const& lat1,
- T2 const& alp1,
- Strategy const& strategy)
- {
- return geometry::formula::vertex_latitude<CalculationType, geographic_tag>
- ::apply(lat1, alp1, strategy.model());
- }
-};
-
-template <typename Units, typename CS_Tag>
-struct envelope_segment_convert_polar
-{
- template <typename T>
- static inline void pre(T & , T & ) {}
-
- template <typename T>
- static inline void post(T & , T & ) {}
-};
-
-template <typename Units>
-struct envelope_segment_convert_polar<Units, spherical_polar_tag>
-{
- template <typename T>
- static inline void pre(T & lat1, T & lat2)
- {
- lat1 = math::latitude_convert_ep<Units>(lat1);
- lat2 = math::latitude_convert_ep<Units>(lat2);
- }
-
- template <typename T>
- static inline void post(T & lat1, T & lat2)
- {
- lat1 = math::latitude_convert_ep<Units>(lat1);
- lat2 = math::latitude_convert_ep<Units>(lat2);
- std::swap(lat1, lat2);
- }
-};
-
-template <typename CS_Tag>
-class envelope_segment_impl
-{
-private:
-
- // degrees or radians
- template <typename CalculationType>
- static inline void swap(CalculationType& lon1,
- CalculationType& lat1,
- CalculationType& lon2,
- CalculationType& lat2)
- {
- std::swap(lon1, lon2);
- std::swap(lat1, lat2);
- }
-
- // radians
- 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);
- }
-
- // radians or degrees
- template <typename Units, typename CoordinateType>
- static inline bool crosses_antimeridian(CoordinateType const& lon1,
- CoordinateType const& lon2)
- {
- typedef math::detail::constants_on_spheroid
- <
- CoordinateType, Units
- > constants;
-
- return math::abs(lon1 - lon2) > constants::half_period(); // > pi
- }
-
- // degrees or radians
- template <typename Units, typename CalculationType, typename Strategy>
- static inline void compute_box_corners(CalculationType& lon1,
- CalculationType& lat1,
- CalculationType& lon2,
- CalculationType& lat2,
- CalculationType a1,
- CalculationType a2,
- Strategy const& strategy)
- {
- // coordinates are assumed to be in radians
- BOOST_GEOMETRY_ASSERT(lon1 <= lon2);
- boost::ignore_unused(lon1, lon2);
-
- CalculationType lat1_rad = math::as_radian<Units>(lat1);
- CalculationType lat2_rad = math::as_radian<Units>(lat2);
-
- if (math::equals(a1, a2))
- {
- // the segment must lie on the equator or is very short or is meridian
- return;
- }
-
- if (lat1 > lat2)
- {
- std::swap(lat1, lat2);
- std::swap(lat1_rad, lat2_rad);
- std::swap(a1, a2);
- }
-
- if (contains_pi_half(a1, a2))
- {
- CalculationType p_max = envelope_segment_call_vertex_latitude
- <CalculationType, CS_Tag>::apply(lat1_rad, a1, strategy);
-
- CalculationType const mid_lat = lat1 + lat2;
- if (mid_lat < 0)
- {
- // update using min latitude
- CalculationType const lat_min_rad = -p_max;
- CalculationType const lat_min
- = math::from_radian<Units>(lat_min_rad);
-
- if (lat1 > lat_min)
- {
- lat1 = lat_min;
- }
- }
- else
- {
- // update using max latitude
- CalculationType const lat_max_rad = p_max;
- CalculationType const lat_max
- = math::from_radian<Units>(lat_max_rad);
-
- if (lat2 < lat_max)
- {
- lat2 = lat_max;
- }
- }
- }
- }
-
- template <typename Units, typename CalculationType>
- static inline void special_cases(CalculationType& lon1,
- CalculationType& lat1,
- CalculationType& lon2,
- CalculationType& lat2)
- {
- typedef math::detail::constants_on_spheroid
- <
- CalculationType, Units
- > constants;
-
- bool is_pole1 = math::equals(math::abs(lat1), constants::max_latitude());
- bool is_pole2 = math::equals(math::abs(lat2), constants::max_latitude());
-
- if (is_pole1 && is_pole2)
- {
- // both points are poles; nothing more to do:
- // longitudes are already normalized to 0
- // but just in case
- lon1 = 0;
- lon2 = 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 (lon1 == lon2)
- {
- // segment lies on a meridian
- if (lat1 > lat2)
- {
- std::swap(lat1, lat2);
- }
- return;
- }
-
- BOOST_GEOMETRY_ASSERT(!is_pole1 && !is_pole2);
-
- if (lon1 > lon2)
- {
- swap(lon1, lat1, lon2, lat2);
- }
-
- if (crosses_antimeridian<Units>(lon1, lon2))
- {
- lon1 += constants::period();
- swap(lon1, lat1, lon2, lat2);
- }
- }
-
- template
- <
- typename Units,
- typename CalculationType,
- typename Box
- >
- static inline void create_box(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, Units
- >::type helper_box_type;
-
- helper_box_type helper_mbr;
-
- geometry::set
- <
- min_corner, 0
- >(helper_mbr, boost::numeric_cast<box_coordinate_type>(lon1));
-
- geometry::set
- <
- min_corner, 1
- >(helper_mbr, boost::numeric_cast<box_coordinate_type>(lat1));
-
- geometry::set
- <
- max_corner, 0
- >(helper_mbr, boost::numeric_cast<box_coordinate_type>(lon2));
-
- geometry::set
- <
- max_corner, 1
- >(helper_mbr, boost::numeric_cast<box_coordinate_type>(lat2));
-
- transform_units(helper_mbr, mbr);
- }
-
-
- template <typename Units, typename CalculationType, typename Strategy>
- static inline void apply(CalculationType& lon1,
- CalculationType& lat1,
- CalculationType& lon2,
- CalculationType& lat2,
- Strategy const& strategy)
- {
- special_cases<Units>(lon1, lat1, lon2, lat2);
-
- CalculationType lon1_rad = math::as_radian<Units>(lon1);
- CalculationType lat1_rad = math::as_radian<Units>(lat1);
- CalculationType lon2_rad = math::as_radian<Units>(lon2);
- CalculationType lat2_rad = math::as_radian<Units>(lat2);
- CalculationType alp1, alp2;
- strategy.apply(lon1_rad, lat1_rad, lon2_rad, lat2_rad, alp1, alp2);
-
- compute_box_corners<Units>(lon1, lat1, lon2, lat2, alp1, alp2, strategy);
- }
-
- template <typename Units, typename CalculationType, typename Strategy>
- static inline void apply(CalculationType& lon1,
- CalculationType& lat1,
- CalculationType& lon2,
- CalculationType& lat2,
- Strategy const& strategy,
- CalculationType alp1)
- {
- special_cases<Units>(lon1, lat1, lon2, lat2);
-
- CalculationType lon1_rad = math::as_radian<Units>(lon1);
- CalculationType lat1_rad = math::as_radian<Units>(lat1);
- CalculationType lon2_rad = math::as_radian<Units>(lon2);
- CalculationType lat2_rad = math::as_radian<Units>(lat2);
- CalculationType alp2;
- strategy.apply_reverse(lon1_rad, lat1_rad, lon2_rad, lat2_rad, alp2);
-
- compute_box_corners<Units>(lon1, lat1, lon2, lat2, alp1, alp2, strategy);
- }
-
-public:
- template
- <
- typename Units,
- typename CalculationType,
- typename Box,
- typename Strategy
- >
- static inline void apply(CalculationType lon1,
- CalculationType lat1,
- CalculationType lon2,
- CalculationType lat2,
- Box& mbr,
- Strategy const& strategy)
- {
- typedef envelope_segment_convert_polar<Units, typename cs_tag<Box>::type> convert_polar;
-
- convert_polar::pre(lat1, lat2);
-
- apply<Units>(lon1, lat1, lon2, lat2, strategy);
-
- convert_polar::post(lat1, lat2);
-
- create_box<Units>(lon1, lat1, lon2, lat2, mbr);
- }
-
- template
- <
- typename Units,
- typename CalculationType,
- typename Box,
- typename Strategy
- >
- static inline void apply(CalculationType lon1,
- CalculationType lat1,
- CalculationType lon2,
- CalculationType lat2,
- Box& mbr,
- Strategy const& strategy,
- CalculationType alp1)
- {
- typedef envelope_segment_convert_polar<Units, typename cs_tag<Box>::type> convert_polar;
-
- convert_polar::pre(lat1, lat2);
-
- apply<Units>(lon1, lat1, lon2, lat2, strategy, alp1);
-
- convert_polar::post(lat1, lat2);
-
- create_box<Units>(lon1, lat1, lon2, lat2, mbr);
- }
-};
-
-template <std::size_t Dimension, std::size_t DimensionCount>
-struct envelope_one_segment
-{
- template<typename Point, typename Box, typename Strategy>
- static inline void apply(Point const& p1,
- Point const& p2,
- Box& mbr,
- Strategy const& strategy)
- {
- envelope_one_point<Dimension, DimensionCount>::apply(p1, mbr, strategy);
- detail::expand::point_loop
- <
- Dimension,
- DimensionCount
- >::apply(mbr, p2, strategy);
- }
-};
-
-
template <std::size_t DimensionCount>
struct envelope_segment
{
@@ -441,12 +46,7 @@ struct envelope_segment
Box& mbr,
Strategy const& strategy)
{
- // first compute the envelope range for the first two coordinates
strategy.apply(p1, p2, mbr);
-
- // now compute the envelope range for coordinates of
- // dimension 2 and higher
- envelope_one_segment<2, DimensionCount>::apply(p1, p2, mbr, strategy);
}
template <typename Segment, typename Box, typename Strategy>
diff --git a/boost/geometry/algorithms/detail/equals/implementation.hpp b/boost/geometry/algorithms/detail/equals/implementation.hpp
index 310059a427..f39ae0b8b7 100644
--- a/boost/geometry/algorithms/detail/equals/implementation.hpp
+++ b/boost/geometry/algorithms/detail/equals/implementation.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2014, 2015, 2016, 2017.
-// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2015, 2016, 2017, 2018.
+// Modifications copyright (c) 2014-2018 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
@@ -64,13 +64,9 @@ template
struct point_point
{
template <typename Point1, typename Point2, typename Strategy>
- static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& strategy)
+ static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& )
{
- return ! detail::disjoint::point_point
- <
- Point1, Point2,
- Dimension, DimensionCount
- >::apply(point1, point2, strategy);
+ return Strategy::apply(point1, point2);
}
};
@@ -108,20 +104,28 @@ struct box_box<DimensionCount, DimensionCount>
struct segment_segment
{
template <typename Segment1, typename Segment2, typename Strategy>
- static inline bool apply(Segment1 const& segment1, Segment2 const& segment2, Strategy const& )
+ static inline bool apply(Segment1 const& segment1, Segment2 const& segment2,
+ Strategy const& strategy)
{
+ typename Strategy::point_in_point_strategy_type const&
+ pt_pt_strategy = strategy.get_point_in_point_strategy();
+
return equals::equals_point_point(
indexed_point_view<Segment1 const, 0>(segment1),
- indexed_point_view<Segment2 const, 0>(segment2) )
+ indexed_point_view<Segment2 const, 0>(segment2),
+ pt_pt_strategy)
? equals::equals_point_point(
indexed_point_view<Segment1 const, 1>(segment1),
- indexed_point_view<Segment2 const, 1>(segment2) )
+ indexed_point_view<Segment2 const, 1>(segment2),
+ pt_pt_strategy)
: ( equals::equals_point_point(
indexed_point_view<Segment1 const, 0>(segment1),
- indexed_point_view<Segment2 const, 1>(segment2) )
+ indexed_point_view<Segment2 const, 1>(segment2),
+ pt_pt_strategy)
&& equals::equals_point_point(
indexed_point_view<Segment1 const, 1>(segment1),
- indexed_point_view<Segment2 const, 0>(segment2) )
+ indexed_point_view<Segment2 const, 0>(segment2),
+ pt_pt_strategy)
);
}
};
diff --git a/boost/geometry/algorithms/detail/equals/point_point.hpp b/boost/geometry/algorithms/detail/equals/point_point.hpp
index 12daa85e9d..06a784284e 100644
--- a/boost/geometry/algorithms/detail/equals/point_point.hpp
+++ b/boost/geometry/algorithms/detail/equals/point_point.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland
-// This file was modified by Oracle on 2013-2014.
-// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013-2018.
+// Modifications copyright (c) 2013-2018, 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,13 +21,10 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_POINT_POINT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_POINT_POINT_HPP
-#include <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
-
namespace boost { namespace geometry
{
-
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace equals
{
@@ -36,17 +33,16 @@ namespace detail { namespace equals
\brief Internal utility function to detect of points are disjoint
\note To avoid circular references
*/
-template <typename Point1, typename Point2>
-inline bool equals_point_point(Point1 const& point1, Point2 const& point2)
+template <typename Point1, typename Point2, typename Strategy>
+inline bool equals_point_point(Point1 const& point1, Point2 const& point2,
+ Strategy const& )
{
- return ! detail::disjoint::disjoint_point_point(point1, point2);
+ return Strategy::apply(point1, point2);
}
-
}} // namespace detail::equals
#endif // DOXYGEN_NO_DETAIL
-
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_POINT_POINT_HPP
diff --git a/boost/geometry/algorithms/detail/expand/box.hpp b/boost/geometry/algorithms/detail/expand/box.hpp
index 485f4d25e6..41571dba6a 100644
--- a/boost/geometry/algorithms/detail/expand/box.hpp
+++ b/boost/geometry/algorithms/detail/expand/box.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
-// This file was modified by Oracle on 2015, 2016, 2017.
-// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2016, 2017, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -19,52 +19,19 @@
#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/algorithms/dispatch/expand.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>
+// For backward compatibility
+#include <boost/geometry/strategies/cartesian/expand_box.hpp>
+#include <boost/geometry/strategies/spherical/expand_box.hpp>
namespace boost { namespace geometry
{
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace expand
-{
-
-
-struct box_on_spheroid
-{
- template <typename BoxOut, typename BoxIn, typename Strategy>
- static inline void apply(BoxOut& box_out,
- BoxIn const& box_in,
- Strategy const& strategy)
- {
- // normalize both boxes and convert box-in to be of type of box-out
- BoxOut mbrs[2];
- detail::envelope::envelope_box_on_spheroid::apply(box_in, mbrs[0], strategy);
- detail::envelope::envelope_box_on_spheroid::apply(box_out, mbrs[1], strategy);
-
- // compute the envelope of the two boxes
- detail::envelope::envelope_range_of_boxes::apply(mbrs, box_out, strategy);
- }
-};
-
-
-}} // namespace detail::expand
-#endif // DOXYGEN_NO_DETAIL
-
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
@@ -73,59 +40,23 @@ namespace dispatch
// Box + box -> new box containing two input boxes
template
<
- typename BoxOut, typename BoxIn,
- typename CSTagOut, typename CSTag
+ typename BoxOut, typename BoxIn
>
struct expand
<
BoxOut, BoxIn,
- box_tag, box_tag,
- CSTagOut, CSTag
+ box_tag, box_tag
>
{
- BOOST_MPL_ASSERT_MSG((false),
- NOT_IMPLEMENTED_FOR_THESE_COORDINATE_SYSTEMS,
- (types<CSTagOut, CSTag>()));
+ template <typename Strategy>
+ static inline void apply(BoxOut& box_out,
+ BoxIn const& box_in,
+ Strategy const& )
+ {
+ Strategy::apply(box_out, box_in);
+ }
};
-template <typename BoxOut, typename BoxIn>
-struct expand
- <
- BoxOut, BoxIn,
- box_tag, box_tag,
- cartesian_tag, cartesian_tag
- > : detail::expand::expand_indexed
- <
- 0, dimension<BoxIn>::value
- >
-{};
-
-template <typename BoxOut, typename BoxIn>
-struct expand
- <
- BoxOut, BoxIn,
- box_tag, box_tag,
- spherical_equatorial_tag, spherical_equatorial_tag
- > : detail::expand::box_on_spheroid
-{};
-
-template <typename BoxOut, typename BoxIn>
-struct expand
- <
- BoxOut, BoxIn,
- box_tag, box_tag,
- spherical_polar_tag, spherical_polar_tag
- > : detail::expand::box_on_spheroid
-{};
-
-template <typename BoxOut, typename BoxIn>
-struct expand
- <
- BoxOut, BoxIn,
- box_tag, box_tag,
- geographic_tag, geographic_tag
- > : detail::expand::box_on_spheroid
-{};
} // namespace dispatch
diff --git a/boost/geometry/algorithms/detail/expand/indexed.hpp b/boost/geometry/algorithms/detail/expand/indexed.hpp
index fe7ee4f781..08463689de 100644
--- a/boost/geometry/algorithms/detail/expand/indexed.hpp
+++ b/boost/geometry/algorithms/detail/expand/indexed.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
-// This file was modified by Oracle on 2015, 2016, 2017.
-// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2016, 2017, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -48,8 +48,8 @@ template
>
struct indexed_loop
{
- template <typename Box, typename Geometry, typename Strategy>
- static inline void apply(Box& box, Geometry const& source, Strategy const& strategy)
+ template <typename Box, typename Geometry>
+ static inline void apply(Box& box, Geometry const& source)
{
typedef typename select_coordinate_type
<
@@ -75,7 +75,7 @@ struct indexed_loop
indexed_loop
<
Index, Dimension + 1, DimensionCount
- >::apply(box, source, strategy);
+ >::apply(box, source);
}
};
@@ -86,8 +86,8 @@ struct indexed_loop
Index, DimensionCount, DimensionCount
>
{
- template <typename Box, typename Geometry, typename Strategy>
- static inline void apply(Box&, Geometry const&, Strategy const&) {}
+ template <typename Box, typename Geometry>
+ static inline void apply(Box&, Geometry const&) {}
};
@@ -96,20 +96,18 @@ struct indexed_loop
template <std::size_t Dimension, std::size_t DimensionCount>
struct expand_indexed
{
- template <typename Box, typename Geometry, typename Strategy>
- static inline void apply(Box& box,
- Geometry const& geometry,
- Strategy const& strategy)
+ template <typename Box, typename Geometry>
+ static inline void apply(Box& box, Geometry const& geometry)
{
indexed_loop
<
0, Dimension, DimensionCount
- >::apply(box, geometry, strategy);
+ >::apply(box, geometry);
indexed_loop
<
1, Dimension, DimensionCount
- >::apply(box, geometry, strategy);
+ >::apply(box, geometry);
}
};
diff --git a/boost/geometry/algorithms/detail/expand/interface.hpp b/boost/geometry/algorithms/detail/expand/interface.hpp
index 5aacd8e72a..28241b379b 100644
--- a/boost/geometry/algorithms/detail/expand/interface.hpp
+++ b/boost/geometry/algorithms/detail/expand/interface.hpp
@@ -5,11 +5,12 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
-// This file was modified by Oracle on 2015, 2016.
-// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2016, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -25,16 +26,17 @@
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/algorithms/dispatch/expand.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
+#include <boost/geometry/strategies/expand.hpp>
-#include <boost/geometry/strategies/envelope.hpp>
-#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
-#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
-#include <boost/geometry/strategies/geographic/envelope_segment.hpp>
namespace boost { namespace geometry
{
@@ -58,14 +60,11 @@ struct expand
Geometry const& geometry,
default_strategy)
{
- typedef typename point_type<Geometry>::type point_type;
- typedef typename coordinate_type<point_type>::type coordinate_type;
-
- typedef typename strategy::envelope::services::default_strategy
- <
- typename cs_tag<point_type>::type,
- coordinate_type
- >::type strategy_type;
+ typedef typename strategy::expand::services::default_strategy
+ <
+ typename tag<Geometry>::type,
+ typename cs_tag<Geometry>::type
+ >::type strategy_type;
dispatch::expand<Box, Geometry>::apply(box, geometry, strategy_type());
}
diff --git a/boost/geometry/algorithms/detail/expand/point.hpp b/boost/geometry/algorithms/detail/expand/point.hpp
index 88ebe75db7..d4a9097cb3 100644
--- a/boost/geometry/algorithms/detail/expand/point.hpp
+++ b/boost/geometry/algorithms/detail/expand/point.hpp
@@ -22,202 +22,19 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_POINT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_POINT_HPP
-#include <cstddef>
-#include <algorithm>
-#include <functional>
-#include <boost/mpl/assert.hpp>
-#include <boost/type_traits/is_same.hpp>
+#include <boost/geometry/algorithms/dispatch/expand.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/is_inverse_spheroidal_coordinates.hpp>
-#include <boost/geometry/util/math.hpp>
-#include <boost/geometry/util/select_coordinate_type.hpp>
-
-#include <boost/geometry/algorithms/detail/normalize.hpp>
-#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
+// For backward compatibility
+#include <boost/geometry/strategies/cartesian/expand_point.hpp>
+#include <boost/geometry/strategies/spherical/expand_point.hpp>
-#include <boost/geometry/algorithms/dispatch/expand.hpp>
namespace boost { namespace geometry
{
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace expand
-{
-
-
-template <std::size_t Dimension, std::size_t DimensionCount>
-struct point_loop
-{
- template <typename Box, typename Point, typename Strategy>
- static inline void apply(Box& box, Point const& source, Strategy const& strategy)
- {
- typedef typename select_coordinate_type
- <
- Point, Box
- >::type coordinate_type;
-
- std::less<coordinate_type> less;
- std::greater<coordinate_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<Dimension + 1, DimensionCount>::apply(box, source, strategy);
- }
-};
-
-
-template <std::size_t DimensionCount>
-struct point_loop<DimensionCount, DimensionCount>
-{
- template <typename Box, typename Point, typename Strategy>
- static inline void apply(Box&, Point const&, Strategy const&) {}
-};
-
-
-// implementation for the spherical and geographic coordinate systems
-template <std::size_t DimensionCount, bool IsEquatorial = true>
-struct point_loop_on_spheroid
-{
- template <typename Box, typename Point, typename Strategy>
- static inline void apply(Box& box,
- Point const& point,
- Strategy const& strategy)
- {
- typedef typename point_type<Box>::type box_point_type;
- typedef typename coordinate_type<Box>::type box_coordinate_type;
- typedef typename coordinate_system<Box>::type::units units_type;
-
- typedef math::detail::constants_on_spheroid
- <
- box_coordinate_type,
- units_type
- > constants;
-
- // normalize input point and input box
- Point p_normalized = detail::return_normalized<Point>(point);
-
- // 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);
-
- if (is_inverse_spheroidal_coordinates(box))
- {
- geometry::set_from_radian<min_corner, 0>(box, geometry::get_as_radian<0>(p_normalized));
- geometry::set_from_radian<min_corner, 1>(box, geometry::get_as_radian<1>(p_normalized));
- geometry::set_from_radian<max_corner, 0>(box, geometry::get_as_radian<0>(p_normalized));
- geometry::set_from_radian<max_corner, 1>(box, geometry::get_as_radian<1>(p_normalized));
-
- } else {
-
- detail::normalize(box, box);
-
- 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::is_latitude_pole<units_type, IsEquatorial>(p_lat))
- {
- // 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::is_latitude_pole<units_type, IsEquatorial>(b_lat_min))
- {
- // 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
- <
- 2, DimensionCount
- >::apply(box, point, strategy);
- }
-};
-
-
-}} // namespace detail::expand
-#endif // DOXYGEN_NO_DETAIL
-
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
@@ -226,74 +43,24 @@ namespace dispatch
// Box + point -> new box containing also point
template
<
- typename BoxOut, typename Point,
- typename CSTagOut, typename CSTag
+ typename BoxOut, typename Point
>
struct expand
<
BoxOut, Point,
- box_tag, point_tag,
- CSTagOut, CSTag
+ box_tag, point_tag
>
{
- BOOST_MPL_ASSERT_MSG((false),
- NOT_IMPLEMENTED_FOR_THESE_COORDINATE_SYSTEMS,
- (types<CSTagOut, CSTag>()));
+ template <typename Strategy>
+ static inline void apply(BoxOut& box,
+ Point const& point,
+ Strategy const& )
+ {
+ Strategy::apply(box, point);
+ }
};
-template <typename BoxOut, typename Point>
-struct expand
- <
- BoxOut, Point,
- box_tag, point_tag,
- cartesian_tag, cartesian_tag
- > : detail::expand::point_loop
- <
- 0, dimension<Point>::value
- >
-{};
-
-template <typename BoxOut, typename Point>
-struct expand
- <
- BoxOut, Point,
- box_tag, point_tag,
- spherical_equatorial_tag, spherical_equatorial_tag
- > : detail::expand::point_loop_on_spheroid
- <
- dimension<Point>::value
- >
-{};
-
-template <typename BoxOut, typename Point>
-struct expand
- <
- BoxOut, Point,
- box_tag, point_tag,
- spherical_polar_tag, spherical_polar_tag
- > : detail::expand::point_loop_on_spheroid
- <
- dimension<Point>::value,
- false
- >
-{};
-
-template
-<
- typename BoxOut, typename Point
->
-struct expand
- <
- BoxOut, Point,
- box_tag, point_tag,
- geographic_tag, geographic_tag
- > : detail::expand::point_loop_on_spheroid
- <
- dimension<Point>::value
- >
-{};
-
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
diff --git a/boost/geometry/algorithms/detail/expand/segment.hpp b/boost/geometry/algorithms/detail/expand/segment.hpp
index dddd3d2c7a..3f6f196026 100644
--- a/boost/geometry/algorithms/detail/expand/segment.hpp
+++ b/boost/geometry/algorithms/detail/expand/segment.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
-// This file was modified by Oracle on 2015, 2016, 2017.
-// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2016, 2017, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -19,57 +19,21 @@
#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/core/ignore_unused.hpp>
#include <boost/geometry/algorithms/dispatch/expand.hpp>
+#include <boost/geometry/core/tags.hpp>
-namespace boost { namespace geometry
-{
+// For backward compatibility
+#include <boost/geometry/strategies/cartesian/expand_segment.hpp>
+#include <boost/geometry/strategies/geographic/expand_segment.hpp>
+#include <boost/geometry/strategies/spherical/expand_segment.hpp>
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace expand
-{
-struct segment
+namespace boost { namespace geometry
{
- template <typename Box, typename Segment, typename Strategy>
- static inline void apply(Box& box,
- Segment const& segment,
- Strategy const& strategy)
- {
- Box mbrs[2];
-
- // compute the envelope of the segment
- typename point_type<Segment>::type p[2];
- detail::assign_point_from_index<0>(segment, p[0]);
- detail::assign_point_from_index<1>(segment, p[1]);
- detail::envelope::envelope_segment
- <
- dimension<Segment>::value
- >::apply(p[0], p[1], mbrs[0], strategy);
-
- // normalize the box
- detail::envelope::envelope_box_on_spheroid::apply(box, mbrs[1], strategy);
-
- // compute the envelope of the two boxes
- detail::envelope::envelope_range_of_boxes::apply(mbrs, box, strategy);
- }
-};
-
-
-}} // namespace detail::expand
-#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
@@ -77,62 +41,24 @@ namespace dispatch
template
<
- typename Box, typename Segment,
- typename CSTagOut, typename CSTag
+ typename Box, typename Segment
>
struct expand
<
Box, Segment,
- box_tag, segment_tag,
- CSTagOut, CSTag
+ box_tag, segment_tag
>
{
- BOOST_MPL_ASSERT_MSG((false),
- NOT_IMPLEMENTED_FOR_THESE_COORDINATE_SYSTEMS,
- (types<CSTagOut, CSTag>()));
+ template <typename Strategy>
+ static inline void apply(Box& box,
+ Segment const& segment,
+ Strategy const& strategy)
+ {
+ boost::ignore_unused(strategy);
+ strategy.apply(box, segment);
+ }
};
-template
-<
- typename Box, typename Segment
->
-struct expand
- <
- Box, Segment,
- box_tag, segment_tag,
- cartesian_tag, cartesian_tag
- > : detail::expand::expand_indexed
- <
- 0, dimension<Segment>::value
- >
-{};
-
-template <typename Box, typename Segment>
-struct expand
- <
- Box, Segment,
- box_tag, segment_tag,
- spherical_polar_tag, spherical_polar_tag
- > : detail::expand::segment
-{};
-
-template <typename Box, typename Segment>
-struct expand
- <
- Box, Segment,
- box_tag, segment_tag,
- spherical_equatorial_tag, spherical_equatorial_tag
- > : detail::expand::segment
-{};
-
-template <typename Box, typename Segment>
-struct expand
- <
- Box, Segment,
- box_tag, segment_tag,
- geographic_tag, geographic_tag
- > : detail::expand::segment
-{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
diff --git a/boost/geometry/algorithms/detail/extreme_points.hpp b/boost/geometry/algorithms/detail/extreme_points.hpp
index 607997813c..842c441f41 100644
--- a/boost/geometry/algorithms/detail/extreme_points.hpp
+++ b/boost/geometry/algorithms/detail/extreme_points.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2013 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2017.
-// Modifications copyright (c) 2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2017, 2018.
+// Modifications copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -25,6 +25,7 @@
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/point_order.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/ring_type.hpp>
#include <boost/geometry/core/tags.hpp>
diff --git a/boost/geometry/algorithms/detail/get_left_turns.hpp b/boost/geometry/algorithms/detail/get_left_turns.hpp
index e9f6a50859..1fec47a01f 100644
--- a/boost/geometry/algorithms/detail/get_left_turns.hpp
+++ b/boost/geometry/algorithms/detail/get_left_turns.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2017.
-// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2017, 2018.
+// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -14,11 +14,14 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_LEFT_TURNS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_LEFT_TURNS_HPP
+#include <set>
+#include <vector>
+
#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>
+#include <boost/geometry/arithmetic/arithmetic.hpp>
#include <boost/geometry/iterators/closing_iterator.hpp>
#include <boost/geometry/iterators/ever_circling_iterator.hpp>
#include <boost/geometry/strategies/side.hpp>
diff --git a/boost/geometry/algorithms/detail/get_max_size.hpp b/boost/geometry/algorithms/detail/get_max_size.hpp
index 8ac43e78b8..f4741824a7 100644
--- a/boost/geometry/algorithms/detail/get_max_size.hpp
+++ b/boost/geometry/algorithms/detail/get_max_size.hpp
@@ -5,6 +5,11 @@
// Copyright (c) 2014 Mateusz Loskot, London, UK.
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018, 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)
@@ -12,10 +17,10 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_MAX_SIZE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_MAX_SIZE_HPP
-
#include <cstddef>
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry
diff --git a/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp b/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp
index f08e70242c..1d3bda191a 100644
--- a/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp
@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014, 2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -19,6 +20,7 @@
#include <boost/core/addressof.hpp>
+#include <boost/geometry/algorithms/detail/signed_size_type.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/policies/compare.hpp>
@@ -221,9 +223,11 @@ public:
return false;
}
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
template <typename OStream, typename TP>
friend inline
void debug_print_complement_graph(OStream&, complement_graph<TP> const&);
+#endif // BOOST_GEOMETRY_TEST_DEBUG
private:
std::size_t m_num_rings, m_num_turns;
diff --git a/boost/geometry/algorithms/detail/is_valid/debug_complement_graph.hpp b/boost/geometry/algorithms/detail/is_valid/debug_complement_graph.hpp
index 60f597e296..749dd3fc25 100644
--- a/boost/geometry/algorithms/detail/is_valid/debug_complement_graph.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/debug_complement_graph.hpp
@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014, 2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -14,6 +15,8 @@
#include <iostream>
#endif
+#include <boost/geometry/algorithms/detail/is_valid/complement_graph.hpp>
+
namespace boost { namespace geometry
{
diff --git a/boost/geometry/algorithms/detail/is_valid/debug_validity_phase.hpp b/boost/geometry/algorithms/detail/is_valid/debug_validity_phase.hpp
index a10e0fe596..b072f7ad43 100644
--- a/boost/geometry/algorithms/detail/is_valid/debug_validity_phase.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/debug_validity_phase.hpp
@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014, 2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -12,11 +13,10 @@
#ifdef GEOMETRY_TEST_DEBUG
#include <iostream>
+#endif
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
-#endif
-
namespace boost { namespace geometry
{
diff --git a/boost/geometry/algorithms/detail/is_valid/has_invalid_coordinate.hpp b/boost/geometry/algorithms/detail/is_valid/has_invalid_coordinate.hpp
index 6e6823d62f..cf3a41069a 100644
--- a/boost/geometry/algorithms/detail/is_valid/has_invalid_coordinate.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/has_invalid_coordinate.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014-2015, Oracle and/or its affiliates.
+// Copyright (c) 2014-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -15,15 +15,17 @@
#include <boost/type_traits/is_floating_point.hpp>
+#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
+#include <boost/geometry/algorithms/validity_failure_type.hpp>
+
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/point_type.hpp>
-#include <boost/geometry/util/has_non_finite_coordinate.hpp>
-
#include <boost/geometry/iterators/point_iterator.hpp>
+
#include <boost/geometry/views/detail/indexed_point_view.hpp>
-#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
+#include <boost/geometry/util/has_non_finite_coordinate.hpp>
namespace boost { namespace geometry
{
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 b36e9f38b7..82818b0990 100644
--- a/boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014-2017, Oracle and/or its affiliates.
+// Copyright (c) 2014-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -16,6 +16,12 @@
#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
+#include <boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp>
+#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
+#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
+#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
+#include <boost/geometry/algorithms/validity_failure_type.hpp>
+
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/point_type.hpp>
@@ -23,12 +29,6 @@
#include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
-#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
-#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
-#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
-
-#include <boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp>
-
namespace boost { namespace geometry
{
diff --git a/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp b/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp
index ed24b13810..8fe5803323 100644
--- a/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp
@@ -116,19 +116,12 @@ private:
}
// prepare strategies
- typedef typename std::iterator_traits<PolygonIterator>::value_type polygon_type;
- typedef typename Strategy::template point_in_geometry_strategy
- <
- polygon_type, polygon_type
- >::type within_strategy_type;
- within_strategy_type const within_strategy
- = strategy.template get_point_in_geometry_strategy<polygon_type, polygon_type>();
typedef typename Strategy::envelope_strategy_type envelope_strategy_type;
envelope_strategy_type const envelope_strategy
= strategy.get_envelope_strategy();
// call partition to check if polygons are disjoint from each other
- typename base::template item_visitor_type<within_strategy_type> item_visitor(within_strategy);
+ typename base::template item_visitor_type<Strategy> item_visitor(strategy);
geometry::partition
<
diff --git a/boost/geometry/algorithms/detail/is_valid/polygon.hpp b/boost/geometry/algorithms/detail/is_valid/polygon.hpp
index 5c6229b793..834ce5af2c 100644
--- a/boost/geometry/algorithms/detail/is_valid/polygon.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/polygon.hpp
@@ -2,7 +2,7 @@
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
-// Copyright (c) 2014-2017, Oracle and/or its affiliates.
+// Copyright (c) 2014-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -217,26 +217,19 @@ protected:
, m_strategy(strategy)
{}
- template <typename Item>
- inline bool is_within(Item const& first, Item const& second)
- {
- typename point_type<Polygon>::type point;
- typedef detail::point_on_border::point_on_range<true> pob;
-
- // TODO: this should check for a point on the interior, instead
- // of on border. Or it should check using the overlap function.
-
- return pob::apply(point, points_begin(first), points_end(first))
- && geometry::within(point, second, m_strategy);
- }
-
template <typename Iterator, typename Box>
inline bool apply(partition_item<Iterator, Box> const& item1,
partition_item<Iterator, Box> const& item2)
{
- if (! items_overlap
- && (is_within(*item1.get(), *item2.get())
- || is_within(*item2.get(), *item1.get())))
+ typedef boost::mpl::vector
+ <
+ geometry::de9im::static_mask<'T'>,
+ geometry::de9im::static_mask<'*', 'T'>,
+ geometry::de9im::static_mask<'*', '*', '*', 'T'>
+ > relate_mask_t;
+
+ if ( ! items_overlap
+ && geometry::relate(*item1.get(), *item2.get(), relate_mask_t(), m_strategy) )
{
items_overlap = true;
return false; // interrupt
@@ -326,19 +319,13 @@ protected:
}
// prepare strategies
- typedef typename Strategy::template point_in_geometry_strategy
- <
- inter_ring_type, inter_ring_type
- >::type in_interior_strategy_type;
- in_interior_strategy_type const in_interior_strategy
- = strategy.template get_point_in_geometry_strategy<inter_ring_type, inter_ring_type>();
typedef typename Strategy::envelope_strategy_type envelope_strategy_type;
envelope_strategy_type const envelope_strategy
= strategy.get_envelope_strategy();
// call partition to check if interior rings are disjoint from
// each other
- item_visitor_type<in_interior_strategy_type> item_visitor(in_interior_strategy);
+ item_visitor_type<Strategy> item_visitor(strategy);
geometry::partition
<
diff --git a/boost/geometry/algorithms/detail/is_valid/ring.hpp b/boost/geometry/algorithms/detail/is_valid/ring.hpp
index 40698155b5..5a55d998e4 100644
--- a/boost/geometry/algorithms/detail/is_valid/ring.hpp
+++ b/boost/geometry/algorithms/detail/is_valid/ring.hpp
@@ -2,7 +2,7 @@
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
-// Copyright (c) 2014-2017, Oracle and/or its affiliates.
+// Copyright (c) 2014-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -20,6 +20,7 @@
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/point_order.hpp>
+#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/order_as_direction.hpp>
#include <boost/geometry/util/range.hpp>
@@ -36,6 +37,7 @@
#include <boost/geometry/algorithms/detail/is_valid/has_invalid_coordinate.hpp>
#include <boost/geometry/algorithms/detail/is_valid/has_spikes.hpp>
#include <boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp>
+#include <boost/geometry/algorithms/dispatch/is_valid.hpp>
#include <boost/geometry/strategies/area.hpp>
diff --git a/boost/geometry/algorithms/detail/normalize.hpp b/boost/geometry/algorithms/detail/normalize.hpp
index 7a761d42bb..b53243f08f 100644
--- a/boost/geometry/algorithms/detail/normalize.hpp
+++ b/boost/geometry/algorithms/detail/normalize.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2015-2017, Oracle and/or its affiliates.
+// Copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -11,298 +11,31 @@
#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>
+// For backward compatibility
+#include <boost/geometry/strategies/normalize.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, bool IsEquatorial = true>
-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,
- IsEquatorial,
- in_coordinate_type
- >(longitude, latitude);
-
- assign_loop
- <
- 0, dimension<PointIn>::value
- >::apply(longitude, latitude, point_in, point_out);
- }
-};
-
-
-template <typename BoxIn, typename BoxOut, bool IsEquatorial = true>
-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,
- IsEquatorial,
- 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,
- spherical_polar_tag, spherical_polar_tag
- > : detail::normalization::normalize_point<PointIn, PointOut, false>
-{};
-
-
-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,
- spherical_polar_tag, spherical_polar_tag
- > : detail::normalization::normalize_box<BoxIn, BoxOut, false>
-{};
-
-
-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)
+template <typename GeometryIn, typename GeometryOut, typename Strategy>
+inline void normalize(GeometryIn const& geometry_in, GeometryOut& geometry_out, Strategy const& )
{
- dispatch::normalize
- <
- GeometryIn, GeometryOut
- >::apply(geometry_in, geometry_out);
+ Strategy::apply(geometry_in, geometry_out);
}
-template <typename GeometryOut, typename GeometryIn>
-inline GeometryOut return_normalized(GeometryIn const& geometry_in)
+template <typename GeometryOut, typename GeometryIn, typename Strategy>
+inline GeometryOut return_normalized(GeometryIn const& geometry_in, Strategy const& strategy)
{
GeometryOut geometry_out;
- detail::normalize(geometry_in, geometry_out);
+ detail::normalize(geometry_in, geometry_out, strategy);
return geometry_out;
}
diff --git a/boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp b/boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp
index 0fd1fe4de9..34e9fc79c7 100644
--- a/boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp
+++ b/boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp
@@ -2,6 +2,11 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018 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)
@@ -10,11 +15,10 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_APPEND_NO_DUPLICATES_HPP
-#include <boost/range.hpp>
-
#include <boost/geometry/algorithms/append.hpp>
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
+#include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry
@@ -26,11 +30,24 @@ namespace detail { namespace overlay
{
template <typename Range, typename Point>
-inline void append_no_duplicates(Range& range, Point const& point, bool force = false)
+inline void append_with_duplicates(Range& range, Point const& point)
+{
+#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
+ std::cout << " add: ("
+ << geometry::get<0>(point) << ", " << geometry::get<1>(point) << ")"
+ << std::endl;
+#endif
+ geometry::append(range, point);
+}
+
+template <typename Range, typename Point, typename EqPPStrategy>
+inline void append_no_duplicates(Range& range, Point const& point,
+ EqPPStrategy const& strategy)
{
- if (boost::size(range) == 0
- || force
- || ! geometry::detail::equals::equals_point_point(*(boost::end(range)-1), point))
+ if ( boost::empty(range)
+ || ! geometry::detail::equals::equals_point_point(geometry::range::back(range),
+ point,
+ strategy) )
{
#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
std::cout << " add: ("
diff --git a/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp b/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp
index 724996ae33..aac39df141 100644
--- a/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp
+++ b/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2014, 2017.
-// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2017, 2018.
+// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -15,11 +15,14 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_APPEND_NO_DUPS_OR_SPIKES_HPP
#include <boost/range.hpp>
+#include <boost/static_assert.hpp>
#include <boost/geometry/algorithms/append.hpp>
#include <boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp>
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
+#include <boost/geometry/core/closure.hpp>
+
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/range.hpp>
@@ -33,12 +36,13 @@ namespace detail { namespace overlay
{
// TODO: move this / rename this
-template <typename Point1, typename Point2, typename RobustPolicy>
+template <typename Point1, typename Point2, typename EqualsStrategy, typename RobustPolicy>
inline bool points_equal_or_close(Point1 const& point1,
Point2 const& point2,
+ EqualsStrategy const& strategy,
RobustPolicy const& robust_policy)
{
- if (detail::equals::equals_point_point(point1, point2))
+ if (detail::equals::equals_point_point(point1, point2, strategy))
{
return true;
}
@@ -59,7 +63,14 @@ inline bool points_equal_or_close(Point1 const& point1,
geometry::recalculate(point1_rob, point1, robust_policy);
geometry::recalculate(point2_rob, point2, robust_policy);
- return detail::equals::equals_point_point(point1_rob, point2_rob);
+ // Only if this is the case the same strategy can be used.
+ BOOST_STATIC_ASSERT((boost::is_same
+ <
+ typename geometry::cs_tag<Point1>::type,
+ typename geometry::cs_tag<robust_point_type>::type
+ >::value));
+
+ return detail::equals::equals_point_point(point1_rob, point2_rob, strategy);
}
@@ -76,8 +87,10 @@ inline void append_no_dups_or_spikes(Range& range, Point const& point,
// The code below this condition checks all spikes/dups
// for geometries >= 3 points.
// So we have to check the first potential duplicate differently
- if (boost::size(range) == 1
- && points_equal_or_close(*(boost::begin(range)), point, robust_policy))
+ if ( boost::size(range) == 1
+ && points_equal_or_close(*(boost::begin(range)), point,
+ strategy.get_equals_point_point_strategy(),
+ robust_policy) )
{
return;
}
@@ -113,8 +126,10 @@ inline void append_no_collinear(Range& range, Point const& point,
// The code below this condition checks all spikes/dups
// for geometries >= 3 points.
// So we have to check the first potential duplicate differently
- if (boost::size(range) == 1
- && points_equal_or_close(*(boost::begin(range)), point, robust_policy))
+ if ( boost::size(range) == 1
+ && points_equal_or_close(*(boost::begin(range)), point,
+ strategy.get_equals_point_point_strategy(),
+ robust_policy) )
{
return;
}
diff --git a/boost/geometry/algorithms/detail/overlay/assign_parents.hpp b/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
index 3be5393486..6d3c602ff2 100644
--- a/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
+++ b/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
@@ -3,8 +3,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2017.
-// Modifications copyright (c) 2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2017, 2018.
+// Modifications copyright (c) 2017-2018 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,
@@ -16,7 +16,6 @@
#include <boost/range.hpp>
-#include <boost/geometry/algorithms/area.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
#include <boost/geometry/algorithms/expand.hpp>
#include <boost/geometry/algorithms/detail/partition.hpp>
@@ -135,12 +134,14 @@ struct ring_info_helper_get_box
}
};
+template <typename DisjointBoxBoxStrategy>
struct ring_info_helper_ovelaps_box
{
template <typename Box, typename InputItem>
static inline bool apply(Box const& box, InputItem const& item)
{
- return ! geometry::detail::disjoint::disjoint_box_box(box, item.envelope);
+ return ! geometry::detail::disjoint::disjoint_box_box(
+ box, item.envelope, DisjointBoxBoxStrategy());
}
};
@@ -328,11 +329,16 @@ inline void assign_parents(Geometry1 const& geometry1,
Strategy
> visitor(geometry1, geometry2, collection, ring_map, strategy, check_for_orientation);
+ typedef ring_info_helper_ovelaps_box
+ <
+ typename Strategy::disjoint_box_box_strategy_type
+ > overlaps_box_type;
+
geometry::partition
<
box_type
>::apply(vector, visitor, ring_info_helper_get_box(),
- ring_info_helper_ovelaps_box());
+ overlaps_box_type());
}
if (check_for_orientation)
diff --git a/boost/geometry/algorithms/detail/overlay/check_enrich.hpp b/boost/geometry/algorithms/detail/overlay/check_enrich.hpp
index 25e442982b..e07e056c33 100644
--- a/boost/geometry/algorithms/detail/overlay/check_enrich.hpp
+++ b/boost/geometry/algorithms/detail/overlay/check_enrich.hpp
@@ -2,6 +2,11 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -9,11 +14,18 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CHECK_ENRICH_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CHECK_ENRICH_HPP
+#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
+#include <iostream>
+#endif // BOOST_GEOMETRY_DEBUG_ENRICH
#include <cstddef>
+#include <vector>
-#include <boost/range.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
@@ -42,7 +54,7 @@ struct meta_turn
template <typename MetaTurn>
-inline void display(MetaTurn const& meta_turn, std::string const& reason = "")
+inline void display(MetaTurn const& meta_turn, const char* reason = "")
{
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
std::cout << meta_turn.index
diff --git a/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp b/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp
index 8cb37d6954..ead9e7014a 100644
--- a/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp
+++ b/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp
@@ -2,10 +2,11 @@
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2018.
+// Modifications copyright (c) 2015-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -24,6 +25,8 @@
#include <boost/geometry/util/select_coordinate_type.hpp>
#include <boost/geometry/geometries/segment.hpp>
+#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
+
namespace boost { namespace geometry
{
@@ -83,6 +86,15 @@ private:
public:
+// TODO: Temporary, this strategy should be moved, it is cartesian-only
+
+ typedef strategy::within::cartesian_point_point equals_point_point_strategy_type;
+
+ static inline equals_point_point_strategy_type get_equals_point_point_strategy()
+ {
+ return equals_point_point_strategy_type();
+ }
+
inline bool clip_segment(Box const& b, segment_type& s, bool& sp1_clipped, bool& sp2_clipped) const
{
typedef typename select_coordinate_type<Box, Point>::type coordinate_type;
@@ -224,9 +236,10 @@ OutputIterator clip_range_with_box(Box const& b, Range const& range,
// b. Add p1 only if it is the first point, then add p2
if (boost::empty(line_out))
{
- detail::overlay::append_no_duplicates(line_out, p1, true);
+ detail::overlay::append_with_duplicates(line_out, p1);
}
- detail::overlay::append_no_duplicates(line_out, p2);
+ detail::overlay::append_no_duplicates(line_out, p2,
+ strategy.get_equals_point_point_strategy());
// c. If c2 is clipped, finish the line
if (c2)
diff --git a/boost/geometry/algorithms/detail/overlay/convert_ring.hpp b/boost/geometry/algorithms/detail/overlay/convert_ring.hpp
index 51955b515d..e2b3cfe069 100644
--- a/boost/geometry/algorithms/detail/overlay/convert_ring.hpp
+++ b/boost/geometry/algorithms/detail/overlay/convert_ring.hpp
@@ -2,6 +2,11 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -9,18 +14,16 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CONVERT_RING_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CONVERT_RING_HPP
-
#include <boost/mpl/assert.hpp>
-#include <boost/range.hpp>
#include <boost/range/algorithm/reverse.hpp>
+#include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
+#include <boost/geometry/algorithms/num_points.hpp>
+
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
-#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
-
-#include <boost/geometry/algorithms/convert.hpp>
-
namespace boost { namespace geometry
{
diff --git a/boost/geometry/algorithms/detail/overlay/copy_segments.hpp b/boost/geometry/algorithms/detail/overlay/copy_segments.hpp
index c6f540a978..d5bdf7eb82 100644
--- a/boost/geometry/algorithms/detail/overlay/copy_segments.hpp
+++ b/boost/geometry/algorithms/detail/overlay/copy_segments.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2014, 2017.
-// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2017, 2018.
+// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -23,23 +23,27 @@
#include <boost/range.hpp>
#include <boost/type_traits/integral_constant.hpp>
+#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
+#include <boost/geometry/algorithms/detail/signed_size_type.hpp>
+#include <boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp>
+#include <boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp>
+#include <boost/geometry/algorithms/not_implemented.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>
#include <boost/geometry/core/tags.hpp>
-#include <boost/geometry/algorithms/not_implemented.hpp>
+
#include <boost/geometry/geometries/concepts/check.hpp>
-#include <boost/geometry/iterators/ever_circling_iterator.hpp>
-#include <boost/geometry/views/closeable_view.hpp>
-#include <boost/geometry/views/reversible_view.hpp>
-#include <boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp>
-#include <boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp>
-#include <boost/geometry/algorithms/detail/signed_size_type.hpp>
+#include <boost/geometry/iterators/ever_circling_iterator.hpp>
#include <boost/geometry/util/range.hpp>
+#include <boost/geometry/views/closeable_view.hpp>
+#include <boost/geometry/views/reversible_view.hpp>
+
namespace boost { namespace geometry
{
@@ -137,11 +141,11 @@ private:
template <typename RangeOut, typename Point, typename SideStrategy, typename RobustPolicy>
static inline void append_to_output(RangeOut& current_output,
Point const& point,
- SideStrategy const&,
+ SideStrategy const& strategy,
RobustPolicy const&,
boost::false_type const&)
{
- detail::overlay::append_no_duplicates(current_output, point);
+ detail::overlay::append_no_duplicates(current_output, point, strategy.get_equals_point_point_strategy());
}
public:
diff --git a/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp b/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp
index a35be052a0..287a06b081 100644
--- a/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp
+++ b/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp
@@ -441,18 +441,21 @@ inline void enrich_intersection_points(Turns& turns,
if (turn.both(detail::overlay::operation_none)
|| turn.both(opposite_operation)
+ || turn.both(detail::overlay::operation_blocked)
|| (detail::overlay::is_self_turn<OverlayType>(turn)
&& ! turn.is_clustered()
&& ! turn.both(target_operation)))
{
+ // For all operations, discard xx and none/none
// For intersections, remove uu to avoid the need to travel
// a union (during intersection) in uu/cc clusters (e.g. #31,#32,#33)
+ // The ux is necessary to indicate impossible paths
+ // (especially if rescaling is removed)
- // Similarly, for union, discard ii
+ // Similarly, for union, discard ii and ix
- // Only keep self-uu-turns or self-ii-turns
+ // For self-turns, only keep uu / ii
- // Blocked (or combination with blocked is still needed for difference)
turn.discarded = true;
turn.cluster_id = -1;
continue;
diff --git a/boost/geometry/algorithms/detail/overlay/follow.hpp b/boost/geometry/algorithms/detail/overlay/follow.hpp
index d948c4f670..5d62e0c476 100644
--- a/boost/geometry/algorithms/detail/overlay/follow.hpp
+++ b/boost/geometry/algorithms/detail/overlay/follow.hpp
@@ -3,8 +3,8 @@
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2014, 2017.
-// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2017, 2018.
+// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -159,7 +159,7 @@ struct action_selector<overlay_intersection, RemoveSpikes>
typename LineString,
typename Point,
typename Operation,
- typename SideStrategy,
+ typename Strategy,
typename RobustPolicy
>
static inline void enter(LineStringOut& current_piece,
@@ -167,13 +167,13 @@ struct action_selector<overlay_intersection, RemoveSpikes>
segment_identifier& segment_id,
signed_size_type , Point const& point,
Operation const& operation,
- SideStrategy const& ,
+ Strategy const& strategy,
RobustPolicy const& ,
OutputIterator& )
{
// On enter, append the intersection point and remember starting point
// TODO: we don't check on spikes for linestrings (?). Consider this.
- detail::overlay::append_no_duplicates(current_piece, point);
+ detail::overlay::append_no_duplicates(current_piece, point, strategy.get_equals_point_point_strategy());
segment_id = operation.seg_id;
}
@@ -184,7 +184,7 @@ struct action_selector<overlay_intersection, RemoveSpikes>
typename LineString,
typename Point,
typename Operation,
- typename SideStrategy,
+ typename Strategy,
typename RobustPolicy
>
static inline void leave(LineStringOut& current_piece,
@@ -192,7 +192,7 @@ struct action_selector<overlay_intersection, RemoveSpikes>
segment_identifier& segment_id,
signed_size_type index, Point const& point,
Operation const& ,
- SideStrategy const& strategy,
+ Strategy const& strategy,
RobustPolicy const& robust_policy,
OutputIterator& out)
{
@@ -202,7 +202,7 @@ struct action_selector<overlay_intersection, RemoveSpikes>
<
false, RemoveSpikes
>::apply(linestring, segment_id, index, strategy, robust_policy, current_piece);
- detail::overlay::append_no_duplicates(current_piece, point);
+ detail::overlay::append_no_duplicates(current_piece, point, strategy.get_equals_point_point_strategy());
if (::boost::size(current_piece) > 1)
{
*out++ = current_piece;
@@ -260,7 +260,7 @@ struct action_selector<overlay_difference, RemoveSpikes>
typename LineString,
typename Point,
typename Operation,
- typename SideStrategy,
+ typename Strategy,
typename RobustPolicy
>
static inline void enter(LineStringOut& current_piece,
@@ -268,7 +268,7 @@ struct action_selector<overlay_difference, RemoveSpikes>
segment_identifier& segment_id,
signed_size_type index, Point const& point,
Operation const& operation,
- SideStrategy const& strategy,
+ Strategy const& strategy,
RobustPolicy const& robust_policy,
OutputIterator& out)
{
@@ -283,7 +283,7 @@ struct action_selector<overlay_difference, RemoveSpikes>
typename LineString,
typename Point,
typename Operation,
- typename SideStrategy,
+ typename Strategy,
typename RobustPolicy
>
static inline void leave(LineStringOut& current_piece,
@@ -291,7 +291,7 @@ struct action_selector<overlay_difference, RemoveSpikes>
segment_identifier& segment_id,
signed_size_type index, Point const& point,
Operation const& operation,
- SideStrategy const& strategy,
+ Strategy const& strategy,
RobustPolicy const& robust_policy,
OutputIterator& out)
{
diff --git a/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp b/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp
index 94667d0ed0..5a3360375a 100644
--- a/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp
@@ -44,12 +44,16 @@ template
>
struct get_turn_without_info
{
- template <typename Strategy, typename RobustPolicy, typename OutputIterator>
- static inline OutputIterator apply(
- Point1 const& pi, Point1 const& pj, Point1 const& /*pk*/,
- Point2 const& qi, Point2 const& qj, Point2 const& /*qk*/,
- bool /*is_p_first*/, bool /*is_p_last*/,
- bool /*is_q_first*/, bool /*is_q_last*/,
+ template
+ <
+ typename UniqueSubRange1,
+ typename UniqueSubRange2,
+ typename Strategy,
+ typename RobustPolicy,
+ typename OutputIterator
+ >
+ static inline OutputIterator apply(UniqueSubRange1 const& range_p,
+ UniqueSubRange2 const& range_q,
TurnInfo const& ,
Strategy const& strategy,
RobustPolicy const& robust_policy,
@@ -71,6 +75,10 @@ struct get_turn_without_info
typedef model::referring_segment<Point1 const> segment_type1;
typedef model::referring_segment<Point2 const> segment_type2;
+ Point1 const& pi = range_p.at(0);
+ Point1 const& pj = range_p.at(1);
+ Point2 const& qi = range_q.at(0);
+ Point2 const& qj = range_q.at(1);
segment_type1 p1(pi, pj);
segment_type2 q1(qi, qj);
diff --git a/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp b/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp
index 895952c8fc..6d92b1bd3c 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp
@@ -3,8 +3,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2015, 2017.
-// Modifications copyright (c) 2015-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2017, 2018, 2019.
+// Modifications copyright (c) 2015-2019 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -21,6 +21,7 @@
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/exception.hpp>
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
@@ -84,7 +85,7 @@ struct base_turn_handler
return side1 * side2 == 1;
}
- // Both continue
+ // Both get the same operation
template <typename TurnInfo>
static inline void both(TurnInfo& ti, operation_type const op)
{
@@ -130,6 +131,17 @@ struct base_turn_handler
? 1 : 0;
}
+ template <typename Point1, typename Point2>
+ static inline typename geometry::coordinate_type<Point1>::type
+ distance_measure(Point1 const& a, Point2 const& b)
+ {
+ // TODO: use comparable distance for point-point instead - but that
+ // causes currently cycling include problems
+ typedef typename geometry::coordinate_type<Point1>::type ctype;
+ ctype const dx = get<0>(a) - get<0>(b);
+ ctype const dy = get<1>(a) - get<1>(b);
+ return dx * dx + dy * dy;
+ }
};
@@ -143,15 +155,14 @@ struct touch_interior : public base_turn_handler
template
<
unsigned int Index,
- typename Point1,
- typename Point2,
+ typename UniqueSubRange1,
+ typename UniqueSubRange2,
typename IntersectionInfo,
typename DirInfo,
typename SidePolicy
>
- static inline void apply(
- Point1 const& , Point1 const& , Point1 const& ,
- Point2 const& , Point2 const& , Point2 const& ,
+ static inline void apply(UniqueSubRange1 const& range_p,
+ UniqueSubRange2 const& range_q,
TurnInfo& ti,
IntersectionInfo const& intersection_info,
DirInfo const& dir_info,
@@ -169,8 +180,10 @@ struct touch_interior : public base_turn_handler
static unsigned int const index_p = Index;
static unsigned int const index_q = 1 - Index;
+ bool const has_pk = ! range_p.is_last_segment();
+ bool const has_qk = ! range_q.is_last_segment();
int const side_qi_p = dir_info.sides.template get<index_q, 0>();
- int const side_qk_p = side.qk_wrt_p1();
+ int const side_qk_p = has_qk ? side.qk_wrt_p1() : 0;
if (side_qi_p == -side_qk_p)
{
@@ -183,7 +196,10 @@ struct touch_interior : public base_turn_handler
return;
}
- int const side_qk_q = side.qk_wrt_q1();
+ int const side_qk_q = has_qk ? side.qk_wrt_q1() : 0;
+
+ // Only necessary if rescaling is turned off:
+ int const side_pj_q2 = has_qk ? side.pj_wrt_q2() : 0;
if (side_qi_p == -1 && side_qk_p == -1 && side_qk_q == 1)
{
@@ -194,10 +210,21 @@ struct touch_interior : public base_turn_handler
}
else if (side_qi_p == 1 && side_qk_p == 1 && side_qk_q == -1)
{
- // Q turns right on the left side of P (test "ML3")
- // Union: take both operation
- // Intersection: skip
- both(ti, operation_union);
+ if (has_qk && side_pj_q2 == -1)
+ {
+ // Q turns right on the left side of P (test "ML3")
+ // Union: take both operations
+ // Intersection: skip
+ both(ti, operation_union);
+ }
+ else
+ {
+ // q2 is collinear with p1, so it does not turn back. This
+ // can happen in floating point precision. In this case,
+ // block one of the operations to avoid taking that path.
+ ti.operations[index_p].operation = operation_union;
+ ti.operations[index_q].operation = operation_blocked;
+ }
ti.touch_only = true;
}
else if (side_qi_p == side_qk_p && side_qi_p == side_qk_q)
@@ -207,6 +234,29 @@ struct touch_interior : public base_turn_handler
// Union: take left turn (Q if Q turns left, P if Q turns right)
// Intersection: other turn
unsigned int index = side_qk_q == 1 ? index_q : index_p;
+ if (has_qk && side_pj_q2 == 0)
+ {
+ // Even though sides xk w.r.t. 1 are distinct, pj is collinear
+ // with q. Therefore swap the path
+ index = 1 - index;
+ }
+
+ if (has_pk && has_qk && opposite(side_pj_q2, side_qi_p))
+ {
+ // Without rescaling, floating point requires extra measures
+ int const side_qj_p1 = side.qj_wrt_p1();
+ int const side_qj_p2 = side.qj_wrt_p2();
+
+ if (same(side_qj_p1, side_qj_p2))
+ {
+ int const side_pj_q1 = side.pj_wrt_q1();
+ if (opposite(side_pj_q1, side_pj_q2))
+ {
+ index = 1 - index;
+ }
+ }
+ }
+
ti.operations[index].operation = operation_union;
ti.operations[1 - index].operation = operation_intersection;
ti.touch_only = true;
@@ -219,10 +269,16 @@ struct touch_interior : public base_turn_handler
// Collinearly in the same direction
// (Q comes from left of P and turns left,
// OR Q comes from right of P and turns right)
- // Omit intersection point.
+ // Omit second intersection point.
// Union: just continue
// Intersection: just continue
both(ti, operation_continue);
+
+ // Calculate remaining distance.
+ // Q arrives at p, at point qj, so use qk for q
+ // and use pj for p
+ ti.operations[index_p].remaining_distance = distance_measure(ti.point, range_p.at(1));
+ ti.operations[index_q].remaining_distance = distance_measure(ti.point, range_q.at(2));
}
else
{
@@ -266,15 +322,14 @@ struct touch : public base_turn_handler
template
<
- typename Point1,
- typename Point2,
+ typename UniqueSubRange1,
+ typename UniqueSubRange2,
typename IntersectionInfo,
typename DirInfo,
typename SidePolicy
>
- static inline void apply(
- Point1 const& , Point1 const& , Point1 const& ,
- Point2 const& , Point2 const& , Point2 const& ,
+ static inline void apply(UniqueSubRange1 const& range_p,
+ UniqueSubRange2 const& range_q,
TurnInfo& ti,
IntersectionInfo const& intersection_info,
DirInfo const& dir_info,
@@ -282,17 +337,20 @@ struct touch : public base_turn_handler
{
assign_point(ti, method_touch, intersection_info, 0);
+ bool const has_pk = ! range_p.is_last_segment();
+ bool const has_qk = ! range_q.is_last_segment();
+
int const side_qi_p1 = dir_info.sides.template get<1, 0>();
- int const side_qk_p1 = side.qk_wrt_p1();
+ int const side_qk_p1 = has_qk ? side.qk_wrt_p1() : 0;
// If Qi and Qk are both at same side of Pi-Pj,
// or collinear (so: not opposite sides)
if (! opposite(side_qi_p1, side_qk_p1))
{
- int const side_pk_q2 = side.pk_wrt_q2();
- int const side_pk_p = side.pk_wrt_p1();
- int const side_qk_q = side.qk_wrt_q1();
+ int const side_pk_q2 = has_pk && has_qk ? side.pk_wrt_q2() : 0;
+ int const side_pk_p = has_pk ? side.pk_wrt_p1() : 0;
+ int const side_qk_q = has_qk ? side.qk_wrt_q1() : 0;
bool const q_turns_left = side_qk_q == 1;
bool const block_q = side_qk_p1 == 0
@@ -315,7 +373,7 @@ struct touch : public base_turn_handler
return;
}
- int const side_pk_q1 = side.pk_wrt_q1();
+ int const side_pk_q1 = has_pk && has_qk ? side.pk_wrt_q1() : 0;
// Collinear opposite case -> block P
@@ -392,13 +450,13 @@ struct touch : public base_turn_handler
else
{
// From left to right or from right to left
- int const side_pk_p = side.pk_wrt_p1();
+ int const side_pk_p = has_pk ? side.pk_wrt_p1() : 0;
bool const right_to_left = side_qk_p1 == 1;
// If p turns into direction of qi (1,2)
if (side_pk_p == side_qi_p1)
{
- int const side_pk_q1 = side.pk_wrt_q1();
+ int const side_pk_q1 = has_pk ? side.pk_wrt_q1() : 0;
// Collinear opposite case -> block P
if (side_pk_q1 == 0)
@@ -420,7 +478,7 @@ struct touch : public base_turn_handler
// If p turns into direction of qk (4,5)
if (side_pk_p == side_qk_p1)
{
- int const side_pk_q2 = side.pk_wrt_q2();
+ int const side_pk_q2 = has_pk ? side.pk_wrt_q2() : 0;
// Collinear case -> lines join, continue
if (side_pk_q2 == 0)
@@ -439,21 +497,6 @@ struct touch : public base_turn_handler
ui_else_iu(! right_to_left, ti);
return;
}
-
-#ifdef BOOST_GEOMETRY_DEBUG_GET_TURNS
- // Normally a robustness issue.
- // TODO: more research if still occuring
- std::cout << "Not yet handled" << std::endl
- << "pi " << get<0>(pi) << " , " << get<1>(pi)
- << " pj " << get<0>(pj) << " , " << get<1>(pj)
- << " pk " << get<0>(pk) << " , " << get<1>(pk)
- << std::endl
- << "qi " << get<0>(qi) << " , " << get<1>(qi)
- << " qj " << get<0>(qj) << " , " << get<1>(qj)
- << " qk " << get<0>(qk) << " , " << get<1>(qk)
- << std::endl;
-#endif
-
}
};
@@ -466,15 +509,14 @@ struct equal : public base_turn_handler
{
template
<
- typename Point1,
- typename Point2,
+ typename UniqueSubRange1,
+ typename UniqueSubRange2,
typename IntersectionInfo,
typename DirInfo,
typename SidePolicy
>
- static inline void apply(
- Point1 const& , Point1 const& , Point1 const& ,
- Point2 const& , Point2 const& , Point2 const& ,
+ static inline void apply(UniqueSubRange1 const& range_p,
+ UniqueSubRange2 const& range_q,
TurnInfo& ti,
IntersectionInfo const& info,
DirInfo const& ,
@@ -483,10 +525,12 @@ struct equal : public base_turn_handler
// Copy the intersection point in TO direction
assign_point(ti, method_equal, info, non_opposite_to_index(info));
- int const side_pk_q2 = side.pk_wrt_q2();
- int const side_pk_p = side.pk_wrt_p1();
- int const side_qk_p = side.qk_wrt_p1();
+ bool const has_pk = ! range_p.is_last_segment();
+ bool const has_qk = ! range_q.is_last_segment();
+ int const side_pk_q2 = has_pk && has_qk ? side.pk_wrt_q2() : 0;
+ int const side_pk_p = has_pk ? side.pk_wrt_p1() : 0;
+ int const side_qk_p = has_qk ? side.qk_wrt_p1() : 0;
// If pk is collinear with qj-qk, they continue collinearly.
// This can be on either side of p1 (== q1), or collinear
@@ -525,12 +569,14 @@ struct equal_opposite : public base_turn_handler
{
template
<
- typename Point1,
- typename Point2,
+ typename UniqueSubRange1,
+ typename UniqueSubRange2,
typename OutputIterator,
typename IntersectionInfo
>
- static inline void apply(Point1 const& pi, Point2 const& qi,
+ static inline void apply(
+ UniqueSubRange1 const& /*range_p*/,
+ UniqueSubRange2 const& /*range_q*/,
/* by value: */ TurnInfo tp,
OutputIterator& out,
IntersectionInfo const& intersection_info)
@@ -546,7 +592,6 @@ struct equal_opposite : public base_turn_handler
for (unsigned int i = 0; i < intersection_info.i_info().count; i++)
{
assign_point(tp, method_none, intersection_info.i_info(), i);
- AssignPolicy::apply(tp, pi, qi, intersection_info);
*out++ = tp;
}
}
@@ -593,15 +638,15 @@ struct collinear : public base_turn_handler
*/
template
<
- typename Point1,
- typename Point2,
+ typename UniqueSubRange1,
+ typename UniqueSubRange2,
typename IntersectionInfo,
typename DirInfo,
typename SidePolicy
>
static inline void apply(
- Point1 const& , Point1 const& pj, Point1 const& pk,
- Point2 const& , Point2 const& qj, Point2 const& qk,
+ UniqueSubRange1 const& range_p,
+ UniqueSubRange2 const& range_q,
TurnInfo& ti,
IntersectionInfo const& info,
DirInfo const& dir_info,
@@ -614,8 +659,10 @@ struct collinear : public base_turn_handler
// Should not be 0, this is checked before
BOOST_GEOMETRY_ASSERT(arrival != 0);
- int const side_p = side.pk_wrt_p1();
- int const side_q = side.qk_wrt_q1();
+ bool const has_pk = ! range_p.is_last_segment();
+ bool const has_qk = ! range_q.is_last_segment();
+ int const side_p = has_pk ? side.pk_wrt_p1() : 0;
+ int const side_q = has_qk ? side.qk_wrt_q1() : 0;
// If p arrives, use p, else use q
int const side_p_or_q = arrival == 1
@@ -642,25 +689,13 @@ struct collinear : public base_turn_handler
// Calculate remaining distance. If it continues collinearly it is
// measured until the end of the next segment
ti.operations[0].remaining_distance
- = side_p == 0
- ? distance_measure(ti.point, pk)
- : distance_measure(ti.point, pj);
+ = side_p == 0 && has_pk
+ ? distance_measure(ti.point, range_p.at(2))
+ : distance_measure(ti.point, range_p.at(1));
ti.operations[1].remaining_distance
- = side_q == 0
- ? distance_measure(ti.point, qk)
- : distance_measure(ti.point, qj);
- }
-
- template <typename Point1, typename Point2>
- static inline typename geometry::coordinate_type<Point1>::type
- distance_measure(Point1 const& a, Point2 const& b)
- {
- // TODO: use comparable distance for point-point instead - but that
- // causes currently cycling include problems
- typedef typename geometry::coordinate_type<Point1>::type ctype;
- ctype const dx = get<0>(a) - get<0>(b);
- ctype const dy = get<1>(a) - get<1>(b);
- return dx * dx + dy * dy;
+ = side_q == 0 && has_qk
+ ? distance_measure(ti.point, range_q.at(2))
+ : distance_measure(ti.point, range_q.at(1));
}
};
@@ -699,13 +734,10 @@ private :
template
<
unsigned int Index,
- typename Point1,
- typename Point2,
typename IntersectionInfo
>
- static inline bool set_tp(Point1 const& , Point1 const& , Point1 const& , int side_rk_r,
- bool const handle_robustness,
- Point2 const& , Point2 const& , int side_rk_s,
+ static inline bool set_tp(int side_rk_r, bool handle_robustness,
+ int side_rk_s,
TurnInfo& tp, IntersectionInfo const& intersection_info)
{
BOOST_STATIC_ASSERT(Index <= 1);
@@ -757,15 +789,15 @@ public:
template
<
- typename Point1,
- typename Point2,
+ typename UniqueSubRange1,
+ typename UniqueSubRange2,
typename OutputIterator,
typename IntersectionInfo,
typename SidePolicy
>
static inline void apply(
- Point1 const& pi, Point1 const& pj, Point1 const& pk,
- Point2 const& qi, Point2 const& qj, Point2 const& qk,
+ UniqueSubRange1 const& range_p,
+ UniqueSubRange2 const& range_q,
// Opposite collinear can deliver 2 intersection points,
TurnInfo const& tp_model,
@@ -774,22 +806,24 @@ public:
IntersectionInfo const& intersection_info,
SidePolicy const& side)
{
- apply(pi, pj, pk, qi, qj, qk, tp_model, out, intersection_info, side, empty_transformer);
+ apply(range_p, range_q,
+ tp_model, out, intersection_info, side, empty_transformer);
}
public:
+
template
<
- typename Point1,
- typename Point2,
+ typename UniqueSubRange1,
+ typename UniqueSubRange2,
typename OutputIterator,
typename IntersectionInfo,
typename SidePolicy,
typename TurnTransformer
>
static inline void apply(
- Point1 const& pi, Point1 const& pj, Point1 const& pk,
- Point2 const& qi, Point2 const& qj, Point2 const& qk,
+ UniqueSubRange1 const& range_p,
+ UniqueSubRange2 const& range_q,
// Opposite collinear can deliver 2 intersection points,
TurnInfo const& tp_model,
@@ -797,8 +831,7 @@ public:
IntersectionInfo const& info,
SidePolicy const& side,
- TurnTransformer turn_transformer,
- bool const is_pk_valid = true, bool const is_qk_valid = true)
+ TurnTransformer turn_transformer)
{
TurnInfo tp = tp_model;
@@ -807,23 +840,21 @@ public:
// If P arrives within Q, there is a turn dependent on P
if ( p_arrival == 1
- && is_pk_valid
- && set_tp<0>(pi, pj, pk, side.pk_wrt_p1(), true, qi, qj, side.pk_wrt_q1(), tp, info.i_info()) )
+ && ! range_p.is_last_segment()
+ && set_tp<0>(side.pk_wrt_p1(), true, side.pk_wrt_q1(), tp, info.i_info()) )
{
turn_transformer(tp);
- AssignPolicy::apply(tp, pi, qi, info);
*out++ = tp;
}
// If Q arrives within P, there is a turn dependent on Q
if ( q_arrival == 1
- && is_qk_valid
- && set_tp<1>(qi, qj, qk, side.qk_wrt_q1(), false, pi, pj, side.qk_wrt_p1(), tp, info.i_info()) )
+ && ! range_q.is_last_segment()
+ && set_tp<1>(side.qk_wrt_q1(), false, side.qk_wrt_p1(), tp, info.i_info()) )
{
turn_transformer(tp);
- AssignPolicy::apply(tp, pi, qi, info);
*out++ = tp;
}
@@ -840,7 +871,6 @@ public:
for (unsigned int i = 0; i < info.i_info().count; i++)
{
assign_point(tp, method_collinear, info.i_info(), i);
- AssignPolicy::apply(tp, pi, qi, info);
*out++ = tp;
}
}
@@ -856,23 +886,14 @@ template
>
struct crosses : public base_turn_handler
{
- template
- <
- typename Point1,
- typename Point2,
- typename IntersectionInfo,
- typename DirInfo
- >
- static inline void apply(
- Point1 const& , Point1 const& , Point1 const& ,
- Point2 const& , Point2 const& , Point2 const& ,
- TurnInfo& ti,
+ template <typename IntersectionInfo, typename DirInfo>
+ static inline void apply(TurnInfo& ti,
IntersectionInfo const& intersection_info,
DirInfo const& dir_info)
{
assign_point(ti, method_crosses, intersection_info, 0);
- // In all casees:
+ // In all cases:
// If Q crosses P from left to right
// Union: take P
// Intersection: take Q
@@ -897,37 +918,21 @@ struct only_convert : public base_turn_handler
/*!
\brief Policy doing nothing
-\details get_turn_info can have an optional policy to get/assign some
- extra information. By default it does not, and this class
- is that default.
+\details get_turn_info can have an optional policy include extra
+ truns. By default it does not, and this class is that default.
*/
struct assign_null_policy
{
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& , Point1 const& , Point2 const&, IntersectionInfo const&)
- {}
-
};
-
/*!
\brief Turn information: intersection point, method, and turn information
\details Information necessary for traversal phase (a phase
of the overlay process). The information is gathered during the
get_turns (segment intersection) phase.
- \tparam Point1 point type of first segment
- \tparam Point2 point type of second segment
- \tparam TurnInfo type of class getting intersection and turn info
\tparam AssignPolicy policy to assign extra info,
e.g. to calculate distance from segment's first points
to intersection points.
@@ -937,23 +942,21 @@ struct assign_null_policy
template<typename AssignPolicy>
struct get_turn_info
{
- // Intersect pi-pj with qi-qj
- // The points pk and qk are used do determine more information
- // about the turn (turn left/right)
+ // Intersect a segment p with a segment q
+ // Both p and q are modelled as sub_ranges to provide more points
+ // to be able to give more information about the turn (left/right)
template
<
- typename Point1,
- typename Point2,
+ typename UniqueSubRange1,
+ typename UniqueSubRange2,
typename TurnInfo,
typename IntersectionStrategy,
typename RobustPolicy,
typename OutputIterator
>
static inline OutputIterator apply(
- Point1 const& pi, Point1 const& pj, Point1 const& pk,
- Point2 const& qi, Point2 const& qj, Point2 const& qk,
- bool /*is_p_first*/, bool /*is_p_last*/,
- bool /*is_q_first*/, bool /*is_q_last*/,
+ UniqueSubRange1 const& range_p,
+ UniqueSubRange2 const& range_q,
TurnInfo const& tp_model,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
@@ -961,13 +964,14 @@ struct get_turn_info
{
typedef intersection_info
<
- Point1, Point2,
+ UniqueSubRange1, UniqueSubRange2,
typename TurnInfo::point_type,
IntersectionStrategy,
RobustPolicy
> inters_info;
- inters_info inters(pi, pj, pk, qi, qj, qk, intersection_strategy, robust_policy);
+ inters_info inters(range_p, range_q,
+ intersection_strategy, robust_policy);
char const method = inters.d_info().how;
@@ -984,7 +988,6 @@ struct get_turn_info
&& inters.i_info().count > 0)
{
only_convert::apply(tp, inters.i_info());
- AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
break;
@@ -1002,45 +1005,28 @@ struct get_turn_info
// If Q (1) arrives (1)
if ( inters.d_info().arrival[1] == 1 )
{
- policy::template apply<0>(pi, pj, pk, qi, qj, qk,
- tp, inters.i_info(), inters.d_info(),
+ policy::template apply<0>(range_p, range_q, tp, inters.i_info(), inters.d_info(),
inters.sides());
}
else
{
// Swap p/q
- side_calculator
- <
- typename inters_info::cs_tag,
- typename inters_info::robust_point2_type,
- typename inters_info::robust_point1_type,
- typename inters_info::side_strategy_type
- > swapped_side_calc(inters.rqi(), inters.rqj(), inters.rqk(),
- inters.rpi(), inters.rpj(), inters.rpk(),
- inters.get_side_strategy());
-
- policy::template apply<1>(qi, qj, qk, pi, pj, pk,
- tp, inters.i_info(), inters.d_info(),
- swapped_side_calc);
+ policy::template apply<1>(range_q, range_p, tp, inters.i_info(), inters.d_info(),
+ inters.get_swapped_sides());
}
- AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
break;
case 'i' :
{
- crosses<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
- tp, inters.i_info(), inters.d_info());
- AssignPolicy::apply(tp, pi, qi, inters);
+ crosses<TurnInfo>::apply(tp, inters.i_info(), inters.d_info());
*out++ = tp;
}
break;
case 't' :
{
// Both touch (both arrive there)
- touch<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
- tp, inters.i_info(), inters.d_info(), inters.sides());
- AssignPolicy::apply(tp, pi, qi, inters);
+ touch<TurnInfo>::apply(range_p, range_q, tp, inters.i_info(), inters.d_info(), inters.sides());
*out++ = tp;
}
break;
@@ -1050,9 +1036,7 @@ struct get_turn_info
{
// Both equal
// or collinear-and-ending at intersection point
- equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
- tp, inters.i_info(), inters.d_info(), inters.sides());
- AssignPolicy::apply(tp, pi, qi, inters);
+ equal<TurnInfo>::apply(range_p, range_q, tp, inters.i_info(), inters.d_info(), inters.sides());
*out++ = tp;
}
else
@@ -1061,8 +1045,7 @@ struct get_turn_info
<
TurnInfo,
AssignPolicy
- >::apply(pi, qi,
- tp, out, inters);
+ >::apply(range_p, range_q, tp, out, inters);
}
}
break;
@@ -1075,19 +1058,18 @@ struct get_turn_info
if ( inters.d_info().arrival[0] == 0 )
{
// Collinear, but similar thus handled as equal
- equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
- tp, inters.i_info(), inters.d_info(), inters.sides());
+ equal<TurnInfo>::apply(range_p, range_q, tp,
+ inters.i_info(), inters.d_info(), inters.sides());
// override assigned method
tp.method = method_collinear;
}
else
{
- collinear<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
- tp, inters.i_info(), inters.d_info(), inters.sides());
+ collinear<TurnInfo>::apply(range_p, range_q, tp,
+ inters.i_info(), inters.d_info(), inters.sides());
}
- AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
else
@@ -1096,7 +1078,7 @@ struct get_turn_info
<
TurnInfo,
AssignPolicy
- >::apply(pi, pj, pk, qi, qj, qk,
+ >::apply(range_p, range_q,
tp, out, inters, inters.sides());
}
}
@@ -1107,7 +1089,6 @@ struct get_turn_info
if (AssignPolicy::include_degenerate)
{
only_convert::apply(tp, inters.i_info());
- AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
}
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 f9b4dee2cd..521744df88 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014, 2017.
-// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2017, 2018.
+// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -15,8 +15,10 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_FOR_ENDPOINT_HPP
#include <boost/core/ignore_unused.hpp>
-#include <boost/geometry/core/assert.hpp>
+
+#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
namespace boost { namespace geometry {
@@ -109,11 +111,12 @@ namespace detail { namespace overlay {
class linear_intersections
{
public:
- template <typename Point1, typename Point2, typename IntersectionResult>
+ template <typename Point1, typename Point2, typename IntersectionResult, typename EqPPStrategy>
linear_intersections(Point1 const& pi,
Point2 const& qi,
IntersectionResult const& result,
- bool is_p_last, bool is_q_last)
+ bool is_p_last, bool is_q_last,
+ EqPPStrategy const& strategy)
{
int arrival_a = result.template get<1>().arrival[0];
int arrival_b = result.template get<1>().arrival[1];
@@ -133,10 +136,10 @@ public:
ips[0].is_pi
= equals::equals_point_point(
- pi, result.template get<0>().intersections[0]);
+ pi, result.template get<0>().intersections[0], strategy);
ips[0].is_qi
= equals::equals_point_point(
- qi, result.template get<0>().intersections[0]);
+ qi, result.template get<0>().intersections[0], strategy);
ips[1].is_pj = arrival_a != -1;
ips[1].is_qj = arrival_b != -1;
}
@@ -222,39 +225,53 @@ private:
ip_info ips[2];
};
-template <typename AssignPolicy, bool EnableFirst, bool EnableLast>
+template <bool EnableFirst, bool EnableLast>
struct get_turn_info_for_endpoint
{
+ typedef std::pair<operation_type, operation_type> operations_pair;
+
BOOST_STATIC_ASSERT(EnableFirst || EnableLast);
- template<typename Point1,
- typename Point2,
+ template<typename UniqueSubRange1,
+ typename UniqueSubRange2,
typename TurnInfo,
typename IntersectionInfo,
- typename OutputIterator
+ typename OutputIterator,
+ typename EqPPStrategy
>
- static inline bool apply(Point1 const& pi, Point1 const& pj, Point1 const& pk,
- Point2 const& qi, Point2 const& qj, Point2 const& qk,
- bool is_p_first, bool is_p_last,
- bool is_q_first, bool is_q_last,
+ static inline bool apply(UniqueSubRange1 const& range_p,
+ UniqueSubRange2 const& range_q,
TurnInfo const& tp_model,
IntersectionInfo const& inters,
method_type /*method*/,
- OutputIterator out)
+ OutputIterator out,
+ EqPPStrategy const& strategy)
{
std::size_t ip_count = inters.i_info().count;
// no intersection points
- if ( ip_count == 0 )
+ if (ip_count == 0)
+ {
return false;
+ }
- if ( !is_p_first && !is_p_last && !is_q_first && !is_q_last )
+ if (! range_p.is_first_segment()
+ && ! range_q.is_first_segment()
+ && ! range_p.is_last_segment()
+ && ! range_q.is_last_segment())
+ {
+ // Not an end-point from segment p or q
return false;
+ }
- linear_intersections intersections(pi, qi, inters.result(), is_p_last, is_q_last);
+ linear_intersections intersections(range_p.at(0),
+ range_q.at(0),
+ inters.result(),
+ range_p.is_last_segment(),
+ range_q.is_last_segment(),
+ strategy);
bool append0_last
- = analyse_segment_and_assign_ip(pi, pj, pk, qi, qj, qk,
- is_p_first, is_p_last, is_q_first, is_q_last,
+ = analyse_segment_and_assign_ip(range_p, range_q,
intersections.template get<0>(),
tp_model, inters, 0, out);
@@ -268,8 +285,7 @@ struct get_turn_info_for_endpoint
return result_ignore_ip0;
bool append1_last
- = analyse_segment_and_assign_ip(pi, pj, pk, qi, qj, qk,
- is_p_first, is_p_last, is_q_first, is_q_last,
+ = analyse_segment_and_assign_ip(range_p, range_q,
intersections.template get<1>(),
tp_model, inters, 1, out);
@@ -279,37 +295,25 @@ struct get_turn_info_for_endpoint
return result_ignore_ip0 || result_ignore_ip1;
}
- template <typename Point1,
- typename Point2,
+ template <typename UniqueSubRange1,
+ typename UniqueSubRange2,
typename TurnInfo,
typename IntersectionInfo,
typename OutputIterator>
static inline
- bool analyse_segment_and_assign_ip(Point1 const& pi, Point1 const& pj, Point1 const& pk,
- Point2 const& qi, Point2 const& qj, Point2 const& qk,
- bool is_p_first, bool is_p_last,
- bool is_q_first, bool is_q_last,
+ bool analyse_segment_and_assign_ip(UniqueSubRange1 const& range_p,
+ UniqueSubRange2 const& range_q,
linear_intersections::ip_info const& ip_info,
TurnInfo const& tp_model,
IntersectionInfo const& inters,
unsigned int ip_index,
OutputIterator out)
{
-#ifdef BOOST_GEOMETRY_DEBUG_GET_TURNS_LINEAR_LINEAR
- // may this give false positives for INTs?
- typename IntersectionResult::point_type const&
- inters_pt = result.template get<0>().intersections[ip_index];
- 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
- bool is_p_first_ip = is_p_first && ip_info.is_pi;
- bool is_p_last_ip = is_p_last && ip_info.is_pj;
- bool is_q_first_ip = is_q_first && ip_info.is_qi;
- bool is_q_last_ip = is_q_last && ip_info.is_qj;
+ bool is_p_first_ip = range_p.is_first_segment() && ip_info.is_pi;
+ bool is_p_last_ip = range_p.is_last_segment() && ip_info.is_pj;
+ bool is_q_first_ip = range_q.is_first_segment() && ip_info.is_qi;
+ bool is_q_last_ip = range_q.is_last_segment() && ip_info.is_qj;
bool append_first = EnableFirst && (is_p_first_ip || is_q_first_ip);
bool append_last = EnableLast && (is_p_last_ip || is_q_last_ip);
@@ -318,9 +322,7 @@ struct get_turn_info_for_endpoint
if ( append_first || append_last )
{
- bool handled = handle_internal<0>(pi, pj, pk, qi, qj, qk,
- inters.rpi(), inters.rpj(), inters.rpk(),
- inters.rqi(), inters.rqj(), inters.rqk(),
+ bool handled = handle_internal<0>(range_p, range_q,
is_p_first_ip, is_p_last_ip,
is_q_first_ip, is_q_last_ip,
ip_info.is_qi, ip_info.is_qj,
@@ -328,9 +330,8 @@ struct get_turn_info_for_endpoint
p_operation, q_operation);
if ( !handled )
{
- handle_internal<1>(qi, qj, qk, pi, pj, pk,
- inters.rqi(), inters.rqj(), inters.rqk(),
- inters.rpi(), inters.rpj(), inters.rpk(),
+ // Reverse p/q
+ handle_internal<1>(range_q, range_p,
is_q_first_ip, is_q_last_ip,
is_p_first_ip, is_p_last_ip,
ip_info.is_pi, ip_info.is_pj,
@@ -348,31 +349,29 @@ struct get_turn_info_for_endpoint
// handle spikes
// P is spike and should be handled
- if ( !is_p_last
- && ip_info.is_pj // this check is redundant (also in is_spike_p) but faster
+ if (ip_info.is_pj // this check is redundant (also in is_spike_p) but faster
&& inters.i_info().count == 2
&& inters.is_spike_p() )
{
- assign(pi, qi, inters.result(), ip_index, method, operation_blocked, q_operation,
+ assign(inters.result(), ip_index, method, operation_blocked, q_operation,
p_pos, q_pos, is_p_first_ip, is_q_first_ip, true, false, tp_model, out);
- assign(pi, qi, inters.result(), ip_index, method, operation_intersection, q_operation,
+ assign(inters.result(), ip_index, method, operation_intersection, q_operation,
p_pos, q_pos, is_p_first_ip, is_q_first_ip, true, false, tp_model, out);
}
// Q is spike and should be handled
- else if ( !is_q_last
- && ip_info.is_qj // this check is redundant (also in is_spike_q) but faster
+ else if (ip_info.is_qj // this check is redundant (also in is_spike_q) but faster
&& inters.i_info().count == 2
&& inters.is_spike_q() )
{
- assign(pi, qi, inters.result(), ip_index, method, p_operation, operation_blocked,
+ assign(inters.result(), ip_index, method, p_operation, operation_blocked,
p_pos, q_pos, is_p_first_ip, is_q_first_ip, false, true, tp_model, out);
- assign(pi, qi, inters.result(), ip_index, method, p_operation, operation_intersection,
+ assign(inters.result(), ip_index, method, p_operation, operation_intersection,
p_pos, q_pos, is_p_first_ip, is_q_first_ip, false, true, tp_model, out);
}
// no spikes
else
{
- assign(pi, qi, inters.result(), ip_index, method, p_operation, q_operation,
+ assign(inters.result(), ip_index, method, p_operation, q_operation,
p_pos, q_pos, is_p_first_ip, is_q_first_ip, false, false, tp_model, out);
}
}
@@ -385,25 +384,22 @@ struct get_turn_info_for_endpoint
// however now it's lazily calculated and then it would be always calculated
template<std::size_t G1Index,
- typename Point1,
- typename Point2,
- typename RobustPoint1,
- typename RobustPoint2,
+ typename UniqueRange1,
+ typename UniqueRange2,
typename TurnInfo,
typename IntersectionInfo
>
- static inline bool handle_internal(Point1 const& /*i1*/, Point1 const& /*j1*/, Point1 const& /*k1*/,
- Point2 const& i2, Point2 const& j2, Point2 const& /*k2*/,
- RobustPoint1 const& ri1, RobustPoint1 const& rj1, RobustPoint1 const& /*rk1*/,
- RobustPoint2 const& ri2, RobustPoint2 const& rj2, RobustPoint2 const& rk2,
+ static inline bool handle_internal(UniqueRange1 const& range1,
+ UniqueRange2 const& range2,
bool first1, bool last1, bool first2, bool last2,
bool ip_i2, bool ip_j2, TurnInfo const& tp_model,
IntersectionInfo const& inters, unsigned int ip_index,
operation_type & op1, operation_type & op2)
{
- typedef typename cs_tag<typename TurnInfo::point_type>::type cs_tag;
+ boost::ignore_unused(ip_index, tp_model);
- boost::ignore_unused(i2, j2, ip_index, tp_model);
+ typename IntersectionInfo::side_strategy_type const& sides
+ = inters.get_side_strategy();
if ( !first2 && !last2 )
{
@@ -425,14 +421,11 @@ struct get_turn_info_for_endpoint
}
else if ( ip_j2 )
{
- side_calculator<cs_tag,
- RobustPoint1, RobustPoint2,
- typename IntersectionInfo::side_strategy_type,
- RobustPoint2>
- side_calc(ri2, ri1, rj1, ri2, rj2, rk2, inters.get_side_strategy());
+ int const side_pj_q2 = sides.apply(range2.at(1), range2.at(2), range1.at(1));
+ int const side_pj_q1 = sides.apply(range2.at(0), range2.at(1), range1.at(1));
+ int const side_qk_q1 = sides.apply(range2.at(0), range2.at(1), range2.at(2));
- std::pair<operation_type, operation_type>
- operations = operations_of_equal(side_calc);
+ operations_pair operations = operations_of_equal(side_pj_q2, side_pj_q1, side_qk_q1);
// TODO: must the above be calculated?
// wouldn't it be enough to check if segments are collinear?
@@ -479,13 +472,11 @@ struct get_turn_info_for_endpoint
}
else if ( ip_j2 )
{
- side_calculator<cs_tag, RobustPoint1, RobustPoint2,
- typename IntersectionInfo::side_strategy_type,
- RobustPoint2>
- side_calc(ri2, rj1, ri1, ri2, rj2, rk2, inters.get_side_strategy());
-
- std::pair<operation_type, operation_type>
- operations = operations_of_equal(side_calc);
+ int const side_pi_q2 = sides.apply(range2.at(1), range2.at(2), range1.at(0));
+ int const side_pi_q1 = sides.apply(range2.at(0), range2.at(1), range1.at(0));
+ int const side_qk_q1 = sides.apply(range2.at(0), range2.at(1), range2.at(2));
+
+ operations_pair operations = operations_of_equal(side_pi_q2, side_pi_q1, side_qk_q1);
// TODO: must the above be calculated?
// wouldn't it be enough to check if segments are collinear?
@@ -534,13 +525,10 @@ struct get_turn_info_for_endpoint
( is_ip_last_j ? position_back : position_middle );
}
- template <typename Point1,
- typename Point2,
- typename IntersectionResult,
+ template <typename IntersectionResult,
typename TurnInfo,
typename OutputIterator>
- static inline void assign(Point1 const& pi, Point2 const& qi,
- IntersectionResult const& result,
+ static inline void assign(IntersectionResult const& result,
unsigned int ip_index,
method_type method,
operation_type op0, operation_type op1,
@@ -591,33 +579,27 @@ struct get_turn_info_for_endpoint
}
}
- // TODO: this should get an intersection_info, which is unavailable here
- // Because the assign_null policy accepts any structure, we pass the result instead for now
- AssignPolicy::apply(tp, pi, qi, result);
*out++ = tp;
}
- template <typename SidePolicy>
- static inline std::pair<operation_type, operation_type> operations_of_equal(SidePolicy const& side)
+ static inline operations_pair operations_of_equal(int side_px_q2,
+ int side_px_q1,
+ int side_qk_q1)
{
- int const side_pk_q2 = side.pk_wrt_q2();
- int const side_pk_p = side.pk_wrt_p1();
- int const side_qk_p = side.qk_wrt_p1();
-
- // If pk is collinear with qj-qk, they continue collinearly.
- // This can be on either side of p1 (== q1), or collinear
+ // If px (pi or pj) is collinear with qj-qk (q2), they continue collinearly.
+ // This can be on either side of q1, or collinear
// The second condition checks if they do not continue
// oppositely
- if ( side_pk_q2 == 0 && side_pk_p == side_qk_p )
+ if (side_px_q2 == 0 && side_px_q1 == side_qk_q1)
{
return std::make_pair(operation_continue, operation_continue);
}
// If they turn to same side (not opposite sides)
- if ( ! base_turn_handler::opposite(side_pk_p, side_qk_p) )
+ if ( ! base_turn_handler::opposite(side_px_q1, side_qk_q1) )
{
- // If pk is left of q2 or collinear: p: union, q: intersection
- if ( side_pk_q2 != -1 )
+ // If px is left of q2 or collinear: p: union, q: intersection
+ if (side_px_q2 != -1 )
{
return std::make_pair(operation_union, operation_intersection);
}
@@ -630,7 +612,7 @@ struct get_turn_info_for_endpoint
{
// They turn opposite sides. If p turns left (or collinear),
// p: union, q: intersection
- if ( side_pk_p != -1 )
+ if (side_px_q1 != -1 )
{
return std::make_pair(operation_union, operation_intersection);
}
@@ -641,16 +623,15 @@ struct get_turn_info_for_endpoint
}
}
- static inline bool operations_both(
- std::pair<operation_type, operation_type> const& operations,
- operation_type const op)
+ static inline bool operations_both(operations_pair const& operations,
+ operation_type const op)
{
return operations.first == op && operations.second == op;
}
- static inline bool operations_combination(
- std::pair<operation_type, operation_type> const& operations,
- operation_type const op1, operation_type const op2)
+ static inline bool operations_combination(operations_pair const& operations,
+ operation_type const op1,
+ operation_type const op2)
{
return ( operations.first == op1 && operations.second == op2 )
|| ( operations.first == op2 && operations.second == op1 );
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 f8247cd240..087ca80602 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014, 2015, 2017.
-// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018.
+// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -14,7 +14,16 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HELPERS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HELPERS_HPP
+#include <boost/geometry/algorithms/detail/direction_code.hpp>
+#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
+#include <boost/geometry/algorithms/detail/recalculate.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/geometries/segment.hpp> // referring_segment
+#include <boost/geometry/policies/relate/direction.hpp>
+#include <boost/geometry/policies/relate/intersection_points.hpp>
+#include <boost/geometry/policies/relate/tupled.hpp>
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
+#include <boost/geometry/strategies/intersection_result.hpp>
namespace boost { namespace geometry {
@@ -36,183 +45,324 @@ struct turn_operation_linear
bool is_collinear; // valid only for Linear geometry
};
-template <typename TurnPointCSTag, typename PointP, typename PointQ,
- typename SideStrategy,
- typename Pi = PointP, typename Pj = PointP, typename Pk = PointP,
- typename Qi = PointQ, typename Qj = PointQ, typename Qk = PointQ
+template
+<
+ typename TurnPointCSTag,
+ typename UniqueSubRange1,
+ typename UniqueSubRange2,
+ typename SideStrategy
>
struct side_calculator
{
- inline side_calculator(Pi const& pi, Pj const& pj, Pk const& pk,
- Qi const& qi, Qj const& qj, Qk const& qk,
+ typedef typename UniqueSubRange1::point_type point1_type;
+ typedef typename UniqueSubRange2::point_type point2_type;
+
+ inline side_calculator(UniqueSubRange1 const& range_p,
+ UniqueSubRange2 const& range_q,
SideStrategy const& side_strategy)
- : m_pi(pi), m_pj(pj), m_pk(pk)
- , m_qi(qi), m_qj(qj), m_qk(qk)
- , m_side_strategy(side_strategy)
+ : m_side_strategy(side_strategy)
+ , m_range_p(range_p)
+ , m_range_q(range_q)
{}
- inline int pk_wrt_p1() const { return m_side_strategy.apply(m_pi, m_pj, m_pk); }
- inline int pk_wrt_q1() const { return m_side_strategy.apply(m_qi, m_qj, m_pk); }
- inline int qk_wrt_p1() const { return m_side_strategy.apply(m_pi, m_pj, m_qk); }
- inline int qk_wrt_q1() const { return m_side_strategy.apply(m_qi, m_qj, m_qk); }
+ inline int pk_wrt_p1() const { return m_side_strategy.apply(get_pi(), get_pj(), get_pk()); }
+ inline int pk_wrt_q1() const { return m_side_strategy.apply(get_qi(), get_qj(), get_pk()); }
+ inline int qk_wrt_p1() const { return m_side_strategy.apply(get_pi(), get_pj(), get_qk()); }
+ inline int qk_wrt_q1() const { return m_side_strategy.apply(get_qi(), get_qj(), get_qk()); }
- inline int pk_wrt_q2() const { return m_side_strategy.apply(m_qj, m_qk, m_pk); }
- inline int qk_wrt_p2() const { return m_side_strategy.apply(m_pj, m_pk, m_qk); }
+ inline int pk_wrt_q2() const { return m_side_strategy.apply(get_qj(), get_qk(), get_pk()); }
+ inline int qk_wrt_p2() const { return m_side_strategy.apply(get_pj(), get_pk(), get_qk()); }
- Pi const& m_pi;
- Pj const& m_pj;
- Pk const& m_pk;
- Qi const& m_qi;
- Qj const& m_qj;
- Qk const& m_qk;
+ // Necessary when rescaling turns off:
+ inline int qj_wrt_p1() const { return m_side_strategy.apply(get_pi(), get_pj(), get_qj()); }
+ inline int qj_wrt_p2() const { return m_side_strategy.apply(get_pj(), get_pk(), get_qj()); }
+ inline int pj_wrt_q1() const { return m_side_strategy.apply(get_qi(), get_qj(), get_pj()); }
+ inline int pj_wrt_q2() const { return m_side_strategy.apply(get_qj(), get_qk(), get_pj()); }
+ inline point1_type const& get_pi() const { return m_range_p.at(0); }
+ inline point1_type const& get_pj() const { return m_range_p.at(1); }
+ inline point1_type const& get_pk() const { return m_range_p.at(2); }
+
+ inline point2_type const& get_qi() const { return m_range_q.at(0); }
+ inline point2_type const& get_qj() const { return m_range_q.at(1); }
+ inline point2_type const& get_qk() const { return m_range_q.at(2); }
+
+ // Used side-strategy, owned by the calculator,
+ // created from .get_side_strategy()
SideStrategy m_side_strategy;
+
+ // Used ranges - owned by get_turns or (for robust points) by intersection_info_base
+ UniqueSubRange1 const& m_range_p;
+ UniqueSubRange2 const& m_range_q;
};
-template <typename Point1, typename Point2, typename RobustPolicy>
+template<typename Point, typename UniqueSubRange, typename RobustPolicy>
+struct robust_subrange_adapter
+{
+ typedef Point point_type;
+
+ robust_subrange_adapter(UniqueSubRange const& unique_sub_range,
+ Point const& robust_point_i, Point const& robust_point_j,
+ RobustPolicy const& robust_policy)
+
+ : m_unique_sub_range(unique_sub_range)
+ , m_robust_policy(robust_policy)
+ , m_robust_point_i(robust_point_i)
+ , m_robust_point_j(robust_point_j)
+ , m_k_retrieved(false)
+ {}
+
+ std::size_t size() const { return m_unique_sub_range.size(); }
+
+ //! Get precalculated point
+ Point const& at(std::size_t index) const
+ {
+ BOOST_GEOMETRY_ASSERT(index < size());
+ switch (index)
+ {
+ case 0 : return m_robust_point_i;
+ case 1 : return m_robust_point_j;
+ case 2 : return get_point_k();
+ default : return m_robust_point_i;
+ }
+ }
+
+private :
+ Point const& get_point_k() const
+ {
+ if (! m_k_retrieved)
+ {
+ geometry::recalculate(m_robust_point_k, m_unique_sub_range.at(2), m_robust_policy);
+ m_k_retrieved = true;
+ }
+ return m_robust_point_k;
+ }
+
+ UniqueSubRange const& m_unique_sub_range;
+ RobustPolicy const& m_robust_policy;
+
+ Point const& m_robust_point_i;
+ Point const& m_robust_point_j;
+ mutable Point m_robust_point_k;
+
+ mutable bool m_k_retrieved;
+};
+
+template
+<
+ typename UniqueSubRange1, typename UniqueSubRange2,
+ typename RobustPolicy
+>
struct robust_points
{
typedef typename geometry::robust_point_type
<
- Point1, RobustPolicy
+ typename UniqueSubRange1::point_type, RobustPolicy
>::type robust_point1_type;
- // TODO: define robust_point2_type using Point2?
typedef robust_point1_type robust_point2_type;
- inline robust_points(Point1 const& pi, Point1 const& pj, Point1 const& pk,
- Point2 const& qi, Point2 const& qj, Point2 const& qk,
+ inline robust_points(UniqueSubRange1 const& range_p,
+ UniqueSubRange2 const& range_q,
RobustPolicy const& robust_policy)
+ : m_robust_policy(robust_policy)
+ , m_range_p(range_p)
+ , m_range_q(range_q)
+ , m_pk_retrieved(false)
+ , m_qk_retrieved(false)
+ {
+ // Calculate pi,pj and qi,qj which are almost always necessary
+ // But don't calculate pk/qk yet, which is retrieved (taking
+ // more time) and not always necessary.
+ geometry::recalculate(m_rpi, range_p.at(0), robust_policy);
+ geometry::recalculate(m_rpj, range_p.at(1), robust_policy);
+ geometry::recalculate(m_rqi, range_q.at(0), robust_policy);
+ geometry::recalculate(m_rqj, range_q.at(1), robust_policy);
+ }
+
+ inline robust_point1_type const& get_rpk() const
{
- geometry::recalculate(m_rpi, pi, robust_policy);
- geometry::recalculate(m_rpj, pj, robust_policy);
- geometry::recalculate(m_rpk, pk, robust_policy);
- geometry::recalculate(m_rqi, qi, robust_policy);
- geometry::recalculate(m_rqj, qj, robust_policy);
- geometry::recalculate(m_rqk, qk, robust_policy);
+ if (! m_pk_retrieved)
+ {
+ geometry::recalculate(m_rpk, m_range_p.at(2), m_robust_policy);
+ m_pk_retrieved = true;
+ }
+ return m_rpk;
}
+ inline robust_point2_type const& get_rqk() const
+ {
+ if (! m_qk_retrieved)
+ {
+ geometry::recalculate(m_rqk, m_range_q.at(2), m_robust_policy);
+ m_qk_retrieved = true;
+ }
+ return m_rqk;
+ }
+
+ robust_point1_type m_rpi, m_rpj;
+ robust_point2_type m_rqi, m_rqj;
- robust_point1_type m_rpi, m_rpj, m_rpk;
- robust_point2_type m_rqi, m_rqj, m_rqk;
+private :
+ RobustPolicy const& m_robust_policy;
+ UniqueSubRange1 const& m_range_p;
+ UniqueSubRange2 const& m_range_q;
+
+ // On retrieval
+ mutable robust_point1_type m_rpk;
+ mutable robust_point2_type m_rqk;
+ mutable bool m_pk_retrieved;
+ mutable bool m_qk_retrieved;
};
-template <typename Point1, typename Point2, typename TurnPoint, typename IntersectionStrategy, typename RobustPolicy>
+template
+<
+ typename UniqueSubRange1, typename UniqueSubRange2,
+ typename TurnPoint, typename IntersectionStrategy, typename RobustPolicy>
class intersection_info_base
- : private robust_points<Point1, Point2, RobustPolicy>
+ : private robust_points<UniqueSubRange1, UniqueSubRange2, RobustPolicy>
{
- typedef robust_points<Point1, Point2, RobustPolicy> base;
+ typedef robust_points<UniqueSubRange1, UniqueSubRange2, RobustPolicy> base;
public:
- typedef Point1 point1_type;
- typedef Point2 point2_type;
-
typedef typename base::robust_point1_type robust_point1_type;
typedef typename base::robust_point2_type robust_point2_type;
+ typedef robust_subrange_adapter<robust_point1_type, UniqueSubRange1, RobustPolicy> robust_subrange1;
+ typedef robust_subrange_adapter<robust_point2_type, UniqueSubRange2, RobustPolicy> robust_subrange2;
+
typedef typename cs_tag<TurnPoint>::type cs_tag;
typedef typename IntersectionStrategy::side_strategy_type side_strategy_type;
- typedef side_calculator<cs_tag, robust_point1_type, robust_point2_type, side_strategy_type> side_calculator_type;
-
- intersection_info_base(Point1 const& pi, Point1 const& pj, Point1 const& pk,
- Point2 const& qi, Point2 const& qj, Point2 const& qk,
+ typedef side_calculator<cs_tag, robust_subrange1, robust_subrange2,
+ side_strategy_type> side_calculator_type;
+
+ typedef side_calculator
+ <
+ cs_tag, robust_subrange2, robust_subrange1,
+ side_strategy_type
+ > robust_swapped_side_calculator_type;
+
+ intersection_info_base(UniqueSubRange1 const& range_p,
+ UniqueSubRange2 const& range_q,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy)
- : base(pi, pj, pk, qi, qj, qk, robust_policy)
- , m_side_calc(base::m_rpi, base::m_rpj, base::m_rpk,
- base::m_rqi, base::m_rqj, base::m_rqk,
+ : base(range_p, range_q, robust_policy)
+ , m_range_p(range_p)
+ , m_range_q(range_q)
+ , m_robust_range_p(range_p, base::m_rpi, base::m_rpj, robust_policy)
+ , m_robust_range_q(range_q, base::m_rqi, base::m_rqj, robust_policy)
+ , m_side_calc(m_robust_range_p, m_robust_range_q,
intersection_strategy.get_side_strategy())
- , m_pi(pi), m_pj(pj), m_pk(pk)
- , m_qi(qi), m_qj(qj), m_qk(qk)
{}
- inline Point1 const& pi() const { return m_pi; }
- inline Point1 const& pj() const { return m_pj; }
- inline Point1 const& pk() const { return m_pk; }
-
- inline Point2 const& qi() const { return m_qi; }
- inline Point2 const& qj() const { return m_qj; }
- inline Point2 const& qk() const { return m_qk; }
+ inline typename UniqueSubRange1::point_type const& pi() const { return m_range_p.at(0); }
+ inline typename UniqueSubRange2::point_type const& qi() const { return m_range_q.at(0); }
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_point1_type const& rpk() const { return base::get_rpk(); }
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 robust_point2_type const& rqk() const { return base::get_rqk(); }
inline side_calculator_type const& sides() const { return m_side_calc; }
-private:
- side_calculator_type m_side_calc;
+ robust_swapped_side_calculator_type get_swapped_sides() const
+ {
+ robust_swapped_side_calculator_type result(
+ m_robust_range_q, m_robust_range_p,
+ m_side_calc.m_side_strategy);
+ return result;
+ }
- point1_type const& m_pi;
- point1_type const& m_pj;
- point1_type const& m_pk;
- point2_type const& m_qi;
- point2_type const& m_qj;
- point2_type const& m_qk;
+ // Owned by get_turns
+ UniqueSubRange1 const& m_range_p;
+ UniqueSubRange2 const& m_range_q;
+private :
+ // Owned by this class
+ robust_subrange1 m_robust_range_p;
+ robust_subrange2 m_robust_range_q;
+ side_calculator_type m_side_calc;
};
-template <typename Point1, typename Point2, typename TurnPoint, typename IntersectionStrategy>
-class intersection_info_base<Point1, Point2, TurnPoint, IntersectionStrategy, detail::no_rescale_policy>
+template
+<
+ typename UniqueSubRange1, typename UniqueSubRange2,
+ typename TurnPoint, typename IntersectionStrategy
+>
+class intersection_info_base<UniqueSubRange1, UniqueSubRange2,
+ TurnPoint, IntersectionStrategy, detail::no_rescale_policy>
{
public:
- typedef Point1 point1_type;
- typedef Point2 point2_type;
+ typedef typename UniqueSubRange1::point_type point1_type;
+ typedef typename UniqueSubRange2::point_type point2_type;
- typedef Point1 robust_point1_type;
- typedef Point2 robust_point2_type;
+ typedef typename UniqueSubRange1::point_type robust_point1_type;
+ typedef typename UniqueSubRange2::point_type robust_point2_type;
typedef typename cs_tag<TurnPoint>::type cs_tag;
typedef typename IntersectionStrategy::side_strategy_type side_strategy_type;
- typedef side_calculator<cs_tag, Point1, Point2, side_strategy_type> side_calculator_type;
+ typedef side_calculator<cs_tag, UniqueSubRange1, UniqueSubRange2, side_strategy_type> side_calculator_type;
+
+ typedef side_calculator
+ <
+ cs_tag, UniqueSubRange2, UniqueSubRange1,
+ side_strategy_type
+ > swapped_side_calculator_type;
- intersection_info_base(Point1 const& pi, Point1 const& pj, Point1 const& pk,
- Point2 const& qi, Point2 const& qj, Point2 const& qk,
+ intersection_info_base(UniqueSubRange1 const& range_p,
+ UniqueSubRange2 const& range_q,
IntersectionStrategy const& intersection_strategy,
no_rescale_policy const& /*robust_policy*/)
- : m_side_calc(pi, pj, pk, qi, qj, qk,
+ : m_range_p(range_p)
+ , m_range_q(range_q)
+ , m_side_calc(range_p, range_q,
intersection_strategy.get_side_strategy())
{}
- inline Point1 const& pi() const { return m_side_calc.m_pi; }
- inline Point1 const& pj() const { return m_side_calc.m_pj; }
- inline Point1 const& pk() const { return m_side_calc.m_pk; }
+ inline point1_type const& rpi() const { return m_side_calc.get_pi(); }
+ inline point1_type const& rpj() const { return m_side_calc.get_pj(); }
+ inline point1_type const& rpk() const { return m_side_calc.get_pk(); }
- inline Point2 const& qi() const { return m_side_calc.m_qi; }
- inline Point2 const& qj() const { return m_side_calc.m_qj; }
- inline Point2 const& qk() const { return m_side_calc.m_qk; }
+ inline point2_type const& rqi() const { return m_side_calc.get_qi(); }
+ inline point2_type const& rqj() const { return m_side_calc.get_qj(); }
+ inline point2_type const& rqk() const { return m_side_calc.get_qk(); }
- inline Point1 const& rpi() const { return pi(); }
- inline Point1 const& rpj() const { return pj(); }
- inline Point1 const& rpk() const { return pk(); }
+ inline side_calculator_type const& sides() const { return m_side_calc; }
- inline Point2 const& rqi() const { return qi(); }
- inline Point2 const& rqj() const { return qj(); }
- inline Point2 const& rqk() const { return qk(); }
+ swapped_side_calculator_type get_swapped_sides() const
+ {
+ swapped_side_calculator_type result(
+ m_range_q, m_range_p,
+ m_side_calc.m_side_strategy);
+ return result;
+ }
- inline side_calculator_type const& sides() const { return m_side_calc; }
-
-private:
+protected :
+ // Owned by get_turns
+ UniqueSubRange1 const& m_range_p;
+ UniqueSubRange2 const& m_range_q;
+private :
+ // Owned here, passed by .get_side_strategy()
side_calculator_type m_side_calc;
};
template
<
- typename Point1,
- typename Point2,
+ typename UniqueSubRange1, typename UniqueSubRange2,
typename TurnPoint,
typename IntersectionStrategy,
typename RobustPolicy
>
class intersection_info
- : public intersection_info_base<Point1, Point2, TurnPoint, IntersectionStrategy, RobustPolicy>
+ : public intersection_info_base<UniqueSubRange1, UniqueSubRange2,
+ TurnPoint, IntersectionStrategy, RobustPolicy>
{
- typedef intersection_info_base<Point1, Point2, TurnPoint, IntersectionStrategy, RobustPolicy> base;
+ typedef intersection_info_base<UniqueSubRange1, UniqueSubRange2,
+ TurnPoint, IntersectionStrategy, RobustPolicy> base;
public:
typedef segment_intersection_points
@@ -224,6 +374,9 @@ public:
>::type
> intersection_point_type;
+ typedef typename UniqueSubRange1::point_type point1_type;
+ typedef typename UniqueSubRange2::point_type point2_type;
+
// NOTE: formerly defined in intersection_strategies
typedef policies::relate::segments_tupled
<
@@ -237,22 +390,23 @@ public:
typedef IntersectionStrategy intersection_strategy_type;
typedef typename IntersectionStrategy::side_strategy_type side_strategy_type;
- typedef model::referring_segment<Point1 const> segment_type1;
- typedef model::referring_segment<Point2 const> segment_type2;
+ typedef model::referring_segment<point1_type const> segment_type1;
+ typedef model::referring_segment<point2_type const> segment_type2;
typedef typename base::side_calculator_type side_calculator_type;
typedef typename intersection_policy_type::return_type result_type;
typedef typename boost::tuples::element<0, result_type>::type i_info_type; // intersection_info
typedef typename boost::tuples::element<1, result_type>::type d_info_type; // dir_info
- intersection_info(Point1 const& pi, Point1 const& pj, Point1 const& pk,
- Point2 const& qi, Point2 const& qj, Point2 const& qk,
+ intersection_info(UniqueSubRange1 const& range_p,
+ UniqueSubRange2 const& range_q,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy)
- : base(pi, pj, pk, qi, qj, qk, intersection_strategy, robust_policy)
+ : base(range_p, range_q,
+ intersection_strategy, robust_policy)
, m_result(intersection_strategy.apply(
- segment_type1(pi, pj),
- segment_type2(qi, qj),
+ segment_type1(range_p.at(0), range_p.at(1)),
+ segment_type2(range_q.at(0), range_q.at(1)),
intersection_policy_type(),
robust_policy,
base::rpi(), base::rpj(),
@@ -265,11 +419,6 @@ public:
inline i_info_type const& i_info() const { return m_result.template get<0>(); }
inline d_info_type const& d_info() const { return m_result.template get<1>(); }
- inline intersection_strategy_type const& get_intersection_strategy() const
- {
- return m_intersection_strategy;
- }
-
inline side_strategy_type get_side_strategy() const
{
return m_intersection_strategy.get_side_strategy();
@@ -278,24 +427,36 @@ public:
// TODO: it's more like is_spike_ip_p
inline bool is_spike_p() const
{
+ if (base::m_range_p.is_last_segment())
+ {
+ return false;
+ }
if (base::sides().pk_wrt_p1() == 0)
{
+ // p: pi--------pj--------pk
+ // or: pi----pk==pj
+
if (! is_ip_j<0>())
{
return false;
}
- int const qk_p1 = base::sides().qk_wrt_p1();
- int const qk_p2 = base::sides().qk_wrt_p2();
-
+ // TODO: why is q used to determine spike property in p?
+ bool const has_qk = ! base::m_range_q.is_last_segment();
+ int const qk_p1 = has_qk ? base::sides().qk_wrt_p1() : 0;
+ int const qk_p2 = has_qk ? base::sides().qk_wrt_p2() : 0;
+
if (qk_p1 == -qk_p2)
{
if (qk_p1 == 0)
{
- return is_spike_of_collinear(base::pi(), base::pj(),
- base::pk());
+ // qk is collinear with both p1 and p2,
+ // verify if pk goes backwards w.r.t. pi/pj
+ return direction_code(base::rpi(), base::rpj(), base::rpk()) == -1;
}
-
+
+ // qk is at opposite side of p1/p2, therefore
+ // p1/p2 (collinear) are opposite and form a spike
return true;
}
}
@@ -303,9 +464,14 @@ public:
return false;
}
- // TODO: it's more like is_spike_ip_q
inline bool is_spike_q() const
{
+ if (base::m_range_q.is_last_segment())
+ {
+ return false;
+ }
+
+ // See comments at is_spike_p
if (base::sides().qk_wrt_q1() == 0)
{
if (! is_ip_j<1>())
@@ -313,15 +479,16 @@ public:
return false;
}
- int const pk_q1 = base::sides().pk_wrt_q1();
- int const pk_q2 = base::sides().pk_wrt_q2();
+ // TODO: why is p used to determine spike property in q?
+ bool const has_pk = ! base::m_range_p.is_last_segment();
+ int const pk_q1 = has_pk ? base::sides().pk_wrt_q1() : 0;
+ int const pk_q2 = has_pk ? base::sides().pk_wrt_q2() : 0;
if (pk_q1 == -pk_q2)
{
if (pk_q1 == 0)
{
- return is_spike_of_collinear(base::qi(), base::qj(),
- base::qk());
+ return direction_code(base::rqi(), base::rqj(), base::rqk()) == -1;
}
return true;
@@ -332,26 +499,6 @@ public:
}
private:
- template <typename Point>
- inline bool is_spike_of_collinear(Point const& i, Point const& j,
- Point const& k) const
- {
- typedef model::referring_segment<Point const> seg;
-
- // no need to calcualte direction info
- typedef policies::relate::segments_intersection_points
- <
- intersection_point_type
- > policy_type;
-
- typename policy_type::return_type const result
- = m_intersection_strategy.apply(seg(i, j), seg(j, k),
- policy_type(),
- m_robust_policy);
-
- return result.count == 2;
- }
-
template <std::size_t OpId>
bool is_ip_j() const
{
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 46c1305cd7..f8272794bd 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp
@@ -3,8 +3,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013, 2014, 2015, 2017.
-// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018.
+// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -41,32 +41,30 @@ struct get_turn_info_linear_areal
template
<
- typename Point1,
- typename Point2,
+ typename UniqueSubRange1,
+ typename UniqueSubRange2,
typename TurnInfo,
typename IntersectionStrategy,
typename RobustPolicy,
typename OutputIterator
>
static inline OutputIterator apply(
- Point1 const& pi, Point1 const& pj, Point1 const& pk,
- Point2 const& qi, Point2 const& qj, Point2 const& qk,
- bool is_p_first, bool is_p_last,
- bool is_q_first, bool is_q_last,
+ UniqueSubRange1 const& range_p,
+ UniqueSubRange2 const& range_q,
TurnInfo const& tp_model,
- IntersectionStrategy const& intersection_strategy,
+ IntersectionStrategy const& strategy,
RobustPolicy const& robust_policy,
OutputIterator out)
{
typedef intersection_info
<
- Point1, Point2,
+ UniqueSubRange1, UniqueSubRange2,
typename TurnInfo::point_type,
IntersectionStrategy,
RobustPolicy
> inters_info;
- inters_info inters(pi, pj, pk, qi, qj, qk, intersection_strategy, robust_policy);
+ inters_info inters(range_p, range_q, strategy, robust_policy);
char const method = inters.d_info().how;
@@ -79,10 +77,9 @@ struct get_turn_info_linear_areal
case 'a' : // collinear, "at"
case 'f' : // collinear, "from"
case 's' : // starts from the middle
- get_turn_info_for_endpoint<true, true>(
- pi, pj, pk, qi, qj, qk,
- is_p_first, is_p_last, is_q_first, is_q_last,
- tp_model, inters, method_none, out);
+ get_turn_info_for_endpoint<true, true>(range_p, range_q,
+ tp_model, inters, method_none, out,
+ strategy.get_point_in_point_strategy());
break;
case 'd' : // disjoint: never do anything
@@ -90,10 +87,9 @@ struct get_turn_info_linear_areal
case 'm' :
{
- if ( get_turn_info_for_endpoint<false, true>(
- pi, pj, pk, qi, qj, qk,
- is_p_first, is_p_last, is_q_first, is_q_last,
- tp_model, inters, method_touch_interior, out) )
+ if ( get_turn_info_for_endpoint<false, true>(range_p, range_q,
+ tp_model, inters, method_touch_interior, out,
+ strategy.get_point_in_point_strategy()) )
{
// do nothing
}
@@ -107,25 +103,16 @@ struct get_turn_info_linear_areal
// If Q (1) arrives (1)
if ( inters.d_info().arrival[1] == 1 )
{
- policy::template apply<0>(pi, pj, pk, qi, qj, qk,
- tp, inters.i_info(), inters.d_info(),
+ policy::template apply<0>(range_p, range_q, tp,
+ inters.i_info(), inters.d_info(),
inters.sides());
}
else
{
// Swap p/q
- side_calculator
- <
- typename inters_info::cs_tag,
- typename inters_info::robust_point2_type,
- typename inters_info::robust_point1_type,
- typename inters_info::side_strategy_type
- > swapped_side_calc(inters.rqi(), inters.rqj(), inters.rqk(),
- inters.rpi(), inters.rpj(), inters.rpk(),
- inters.get_side_strategy());
- policy::template apply<1>(qi, qj, qk, pi, pj, pk,
+ policy::template apply<1>(range_q, range_p,
tp, inters.i_info(), inters.d_info(),
- swapped_side_calc);
+ inters.get_swapped_sides());
}
if ( tp.operations[1].operation == operation_blocked )
@@ -139,39 +126,35 @@ struct get_turn_info_linear_areal
// this function assumes that 'u' must be set for a spike
calculate_spike_operation(tp.operations[0].operation,
- inters, is_p_last);
+ inters,
+ strategy.get_point_in_point_strategy());
- AssignPolicy::apply(tp, pi, qi, inters);
-
*out++ = tp;
}
}
break;
case 'i' :
{
- crosses<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
- tp, inters.i_info(), inters.d_info());
+ crosses<TurnInfo>::apply(tp, inters.i_info(), inters.d_info());
replace_operations_i(tp.operations[0].operation, tp.operations[1].operation);
- AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
break;
case 't' :
{
// Both touch (both arrive there)
- if ( get_turn_info_for_endpoint<false, true>(
- pi, pj, pk, qi, qj, qk,
- is_p_first, is_p_last, is_q_first, is_q_last,
- tp_model, inters, method_touch, out) )
+ if ( get_turn_info_for_endpoint<false, true>(range_p, range_q,
+ tp_model, inters, method_touch, out,
+ strategy.get_point_in_point_strategy()) )
{
// do nothing
}
else
{
- touch<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
- tp, inters.i_info(), inters.d_info(), inters.sides());
+ touch<TurnInfo>::apply(range_p, range_q, tp,
+ inters.i_info(), inters.d_info(), inters.sides());
if ( tp.operations[1].operation == operation_blocked )
{
@@ -236,15 +219,13 @@ struct get_turn_info_linear_areal
bool ignore_spike
= calculate_spike_operation(tp.operations[0].operation,
- inters, is_p_last);
-
-// TODO: move this into the append_xxx and call for each turn?
- AssignPolicy::apply(tp, pi, qi, inters);
+ inters,
+ strategy.get_point_in_point_strategy());
if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes)
|| ignore_spike
|| ! append_opposite_spikes<append_touches>( // for 'i' or 'c' i???
- tp, inters, is_p_last, is_q_last, out) )
+ tp, inters, out) )
{
*out++ = tp;
}
@@ -253,10 +234,9 @@ struct get_turn_info_linear_areal
break;
case 'e':
{
- if ( get_turn_info_for_endpoint<true, true>(
- pi, pj, pk, qi, qj, qk,
- is_p_first, is_p_last, is_q_first, is_q_last,
- tp_model, inters, method_equal, out) )
+ if ( get_turn_info_for_endpoint<true, true>(range_p, range_q,
+ tp_model, inters, method_equal, out,
+ strategy.get_point_in_point_strategy()) )
{
// do nothing
}
@@ -268,18 +248,15 @@ struct get_turn_info_linear_areal
{
// Both equal
// or collinear-and-ending at intersection point
- equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
- tp, inters.i_info(), inters.d_info(), inters.sides());
+ equal<TurnInfo>::apply(range_p, range_q, tp,
+ inters.i_info(), inters.d_info(), inters.sides());
turn_transformer_ec<false> transformer(method_touch);
transformer(tp);
-
-// TODO: move this into the append_xxx and call for each turn?
- AssignPolicy::apply(tp, pi, qi, inters);
-
+
// conditionally handle spikes
if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes)
- || ! append_collinear_spikes(tp, inters, is_p_last, is_q_last,
+ || ! append_collinear_spikes(tp, inters,
method_touch, append_equal, out) )
{
*out++ = tp; // no spikes
@@ -291,7 +268,7 @@ struct get_turn_info_linear_areal
<
TurnInfo,
AssignPolicy
- >::apply(pi, qi,
+ >::apply(range_p, range_q,
tp, out, inters);
}
}
@@ -301,9 +278,9 @@ struct get_turn_info_linear_areal
{
// Collinear
if ( get_turn_info_for_endpoint<true, true>(
- pi, pj, pk, qi, qj, qk,
- is_p_first, is_p_last, is_q_first, is_q_last,
- tp_model, inters, method_collinear, out) )
+ range_p, range_q,
+ tp_model, inters, method_collinear, out,
+ strategy.get_point_in_point_strategy()) )
{
// do nothing
}
@@ -319,16 +296,16 @@ struct get_turn_info_linear_areal
if ( inters.d_info().arrival[0] == 0 )
{
// Collinear, but similar thus handled as equal
- equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
- tp, inters.i_info(), inters.d_info(), inters.sides());
+ equal<TurnInfo>::apply(range_p, range_q, tp,
+ inters.i_info(), inters.d_info(), inters.sides());
method_replace = method_touch;
version = append_equal;
}
else
{
- collinear<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
- tp, inters.i_info(), inters.d_info(), inters.sides());
+ collinear<TurnInfo>::apply(range_p, range_q, tp,
+ inters.i_info(), inters.d_info(), inters.sides());
//method_replace = method_touch_interior;
//version = append_collinear;
@@ -337,12 +314,9 @@ struct get_turn_info_linear_areal
turn_transformer_ec<false> transformer(method_replace);
transformer(tp);
-// TODO: move this into the append_xxx and call for each turn?
- AssignPolicy::apply(tp, pi, qi, inters);
-
// conditionally handle spikes
if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes)
- || ! append_collinear_spikes(tp, inters, is_p_last, is_q_last,
+ || ! append_collinear_spikes(tp, inters,
method_replace, version, out) )
{
// no spikes
@@ -358,7 +332,7 @@ struct get_turn_info_linear_areal
if ( BOOST_GEOMETRY_CONDITION(handle_spikes) )
{
append_opposite_spikes<append_collinear_opposite>(
- tp, inters, is_p_last, is_q_last, out);
+ tp, inters, out);
}
// TODO: ignore for spikes?
@@ -369,10 +343,9 @@ struct get_turn_info_linear_areal
<
TurnInfo,
AssignPolicy
- >::apply(pi, pj, pk, qi, qj, qk,
+ >::apply(range_p, range_q,
tp, out, inters,
- inters.sides(), transformer,
- !is_p_last, true); // qk is always valid
+ inters.sides(), transformer);
}
}
}
@@ -384,19 +357,20 @@ struct get_turn_info_linear_areal
{
only_convert::apply(tp, inters.i_info());
- if ( is_p_first
- && equals::equals_point_point(pi, tp.point) )
+ if ( range_p.is_first_segment()
+ && equals::equals_point_point(range_p.at(0), tp.point,
+ strategy.get_point_in_point_strategy()) )
{
tp.operations[0].position = position_front;
}
- else if ( is_p_last
- && equals::equals_point_point(pj, tp.point) )
+ else if ( range_p.is_last_segment()
+ && equals::equals_point_point(range_p.at(1), tp.point,
+ strategy.get_point_in_point_strategy()) )
{
tp.operations[0].position = position_back;
}
// tp.operations[1].position = position_middle;
- AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
}
@@ -417,13 +391,13 @@ struct get_turn_info_linear_areal
}
template <typename Operation,
- typename IntersectionInfo>
+ typename IntersectionInfo,
+ typename EqPPStrategy>
static inline bool calculate_spike_operation(Operation & op,
IntersectionInfo const& inters,
- bool is_p_last)
+ EqPPStrategy const& strategy)
{
bool is_p_spike = ( op == operation_union || op == operation_intersection )
- && ! is_p_last
&& inters.is_spike_p();
if ( is_p_spike )
@@ -441,7 +415,7 @@ struct get_turn_info_linear_areal
// spike on the edge point
// if it's already known that the spike is going out this musn't be checked
if ( ! going_out
- && equals::equals_point_point(inters.rpj(), inters.rqj()) )
+ && detail::equals::equals_point_point(inters.rpj(), inters.rqj(), strategy) )
{
int const pk_q2 = inters.sides().pk_wrt_q2();
going_in = pk_q1 < 0 && pk_q2 < 0; // Pk on the right of both
@@ -453,7 +427,7 @@ struct get_turn_info_linear_areal
// spike on the edge point
// if it's already known that the spike is going in this musn't be checked
if ( ! going_in
- && equals::equals_point_point(inters.rpj(), inters.rqj()) )
+ && detail::equals::equals_point_point(inters.rpj(), inters.rqj(), strategy) )
{
int const pk_q2 = inters.sides().pk_wrt_q2();
going_in = pk_q1 < 0 || pk_q2 < 0; // Pk on the right of one of them
@@ -483,7 +457,6 @@ struct get_turn_info_linear_areal
typename OutIt>
static inline bool append_collinear_spikes(TurnInfo & tp,
IntersectionInfo const& inters,
- bool is_p_last, bool /*is_q_last*/,
method_type method, append_version_c version,
OutIt out)
{
@@ -494,7 +467,6 @@ struct get_turn_info_linear_areal
( tp.operations[0].operation == operation_union
|| tp.operations[0].operation == operation_intersection ) :
tp.operations[0].operation == operation_continue )
- && ! is_p_last
&& inters.is_spike_p();
// TODO: throw an exception for spike in Areal?
@@ -543,7 +515,6 @@ struct get_turn_info_linear_areal
typename OutIt>
static inline bool append_opposite_spikes(TurnInfo & tp,
IntersectionInfo const& inters,
- bool is_p_last, bool /*is_q_last*/,
OutIt out)
{
static const bool is_version_touches = (Version == append_touches);
@@ -552,7 +523,6 @@ struct get_turn_info_linear_areal
( tp.operations[0].operation == operation_continue
|| tp.operations[0].operation == operation_intersection ) : // i ???
true )
- && ! is_p_last
&& inters.is_spike_p();
// TODO: throw an exception for spike in Areal?
@@ -586,8 +556,6 @@ struct get_turn_info_linear_areal
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);
}
tp.operations[0].operation = operation_blocked;
@@ -706,35 +674,46 @@ struct get_turn_info_linear_areal
template <bool EnableFirst,
bool EnableLast,
- typename Point1,
- typename Point2,
+ typename UniqueSubRange1,
+ typename UniqueSubRange2,
typename TurnInfo,
typename IntersectionInfo,
- typename OutputIterator>
+ typename OutputIterator,
+ typename EqPPStrategy>
static inline bool get_turn_info_for_endpoint(
- Point1 const& pi, Point1 const& /*pj*/, Point1 const& /*pk*/,
- Point2 const& qi, Point2 const& /*qj*/, Point2 const& /*qk*/,
- bool is_p_first, bool is_p_last,
- bool /*is_q_first*/, bool is_q_last,
+ UniqueSubRange1 const& range_p,
+ UniqueSubRange2 const& range_q,
TurnInfo const& tp_model,
IntersectionInfo const& inters,
method_type /*method*/,
- OutputIterator out)
+ OutputIterator out,
+ EqPPStrategy const& strategy)
{
namespace ov = overlay;
- typedef ov::get_turn_info_for_endpoint<AssignPolicy, EnableFirst, EnableLast> get_info_e;
+ typedef ov::get_turn_info_for_endpoint<EnableFirst, EnableLast> get_info_e;
const std::size_t ip_count = inters.i_info().count;
// no intersection points
- if ( ip_count == 0 )
+ if (ip_count == 0)
+ {
return false;
+ }
- if ( !is_p_first && !is_p_last )
+ if (! range_p.is_first_segment() && ! range_p.is_last_segment())
+ {
+ // P sub-range has no end-points
return false;
+ }
-// TODO: is_q_last could probably be replaced by false and removed from parameters
+ typename IntersectionInfo::side_strategy_type const& sides
+ = inters.get_side_strategy();
- linear_intersections intersections(pi, qi, inters.result(), is_p_last, is_q_last);
+ linear_intersections intersections(range_p.at(0),
+ range_q.at(0),
+ inters.result(),
+ range_p.is_last_segment(),
+ range_q.is_last_segment(),
+ strategy);
linear_intersections::ip_info const& ip0 = intersections.template get<0>();
linear_intersections::ip_info const& ip1 = intersections.template get<1>();
@@ -745,7 +724,7 @@ struct get_turn_info_linear_areal
// IP on the first point of Linear Geometry
bool was_first_point_handled = false;
if ( BOOST_GEOMETRY_CONDITION(EnableFirst)
- && is_p_first && ip0.is_pi && !ip0.is_qi ) // !q0i prevents duplication
+ && range_p.is_first_segment() && ip0.is_pi && !ip0.is_qi ) // !q0i prevents duplication
{
TurnInfo tp = tp_model;
tp.operations[0].position = position_front;
@@ -759,51 +738,40 @@ struct get_turn_info_linear_areal
}
else
{
- typedef typename IntersectionInfo::robust_point1_type rp1_type;
- typedef typename IntersectionInfo::robust_point2_type rp2_type;
-
- method_type replaced_method = method_touch_interior;
-
+ // pi is the intersection point at qj or in the middle of q1
+ // so consider segments
+ // 1. pi at qj: qi-qj-pj and qi-qj-qk
+ // x: qi-qj, y: qj-qk, qz: qk
+ // 2. pi in the middle of q1: qi-pi-pj and qi-pi-qj
+ // x: qi-pi, y: pi-qj, qz: qj
+ // qi-pi, side the same as WRT q1
+ // pi-qj, side the same as WRT q1
+ // qj WRT q1 is 0
+ method_type replaced_method = method_none;
+ int side_pj_y = 0, side_pj_x = 0, side_qz_x = 0;
+ // 1. ip0 or pi at qj
if ( ip0.is_qj )
{
- side_calculator
- <
- typename IntersectionInfo::cs_tag,
- rp1_type, rp2_type,
- typename IntersectionInfo::side_strategy_type,
- rp2_type
- > side_calc(inters.rqi(), inters.rpi(), inters.rpj(),
- inters.rqi(), inters.rqj(), inters.rqk(),
- inters.get_side_strategy());
-
- std::pair<operation_type, operation_type>
- operations = get_info_e::operations_of_equal(side_calc);
-
- tp.operations[0].operation = operations.first;
- tp.operations[1].operation = operations.second;
-
replaced_method = method_touch;
+ side_pj_y = sides.apply(range_q.at(1), range_q.at(2), range_p.at(1)); // pj wrt q2
+ side_pj_x = sides.apply(range_q.at(0), range_q.at(1), range_p.at(1)); // pj wrt q1
+ side_qz_x = sides.apply(range_q.at(0), range_q.at(1), range_q.at(2)); // qk wrt q1
}
+ // 2. ip0 or pi in the middle of q1
else
{
- side_calculator
- <
- typename IntersectionInfo::cs_tag,
- rp1_type, rp2_type,
- typename IntersectionInfo::side_strategy_type,
- rp2_type, rp1_type, rp1_type,
- rp2_type, rp1_type, rp2_type
- > side_calc(inters.rqi(), inters.rpi(), inters.rpj(),
- inters.rqi(), inters.rpi(), inters.rqj(),
- inters.get_side_strategy());
-
- std::pair<operation_type, operation_type>
- operations = get_info_e::operations_of_equal(side_calc);
-
- tp.operations[0].operation = operations.first;
- tp.operations[1].operation = operations.second;
+ replaced_method = method_touch_interior;
+ side_pj_y = sides.apply(range_q.at(0), range_q.at(1), range_p.at(1)); // pj wrt q1
+ side_pj_x = side_pj_y; // pj wrt q1
+ side_qz_x = 0; // qj wrt q1
}
+ std::pair<operation_type, operation_type> operations
+ = get_info_e::operations_of_equal(side_pj_y, side_pj_x, side_qz_x);
+
+ tp.operations[0].operation = operations.first;
+ tp.operations[1].operation = operations.second;
+
turn_transformer_ec<true> transformer(replaced_method);
transformer(tp);
}
@@ -817,7 +785,6 @@ struct get_turn_info_linear_areal
// here is_p_first_ip == true
tp.operations[0].is_collinear = false;
- AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
was_first_point_handled = true;
@@ -827,7 +794,7 @@ struct get_turn_info_linear_areal
// IP on the last point of Linear Geometry
if ( BOOST_GEOMETRY_CONDITION(EnableLast)
- && is_p_last
+ && range_p.is_last_segment()
&& ( ip_count > 1 ? (ip1.is_pj && !ip1.is_qi) : (ip0.is_pj && !ip0.is_qi) ) ) // prevents duplication
{
TurnInfo tp = tp_model;
@@ -840,19 +807,33 @@ struct get_turn_info_linear_areal
}
else //if ( result.template get<0>().count == 1 )
{
- side_calculator
- <
- typename IntersectionInfo::cs_tag,
- typename IntersectionInfo::robust_point1_type,
- typename IntersectionInfo::robust_point2_type,
- typename IntersectionInfo::side_strategy_type,
- typename IntersectionInfo::robust_point2_type
- > side_calc(inters.rqi(), inters.rpj(), inters.rpi(),
- inters.rqi(), inters.rqj(), inters.rqk(),
- inters.get_side_strategy());
-
- std::pair<operation_type, operation_type>
- operations = get_info_e::operations_of_equal(side_calc);
+ // pj is the intersection point at qj or in the middle of q1
+ // so consider segments
+ // 1. pj at qj: qi-qj-pi and qi-qj-qk
+ // x: qi-qj, y: qj-qk, qz: qk
+ // 2. pj in the middle of q1: qi-pj-pi and qi-pj-qj
+ // x: qi-pj, y: pj-qj, qz: qj
+ // qi-pj, the side is the same as WRT q1
+ // pj-qj, the side is the same as WRT q1
+ // side of qj WRT q1 is 0
+ int side_pi_y = 0, side_pi_x = 0, side_qz_x = 0;
+ // 1. ip0 or pj at qj
+ if ( ip0.is_qj )
+ {
+ side_pi_y = sides.apply(range_q.at(1), range_q.at(2), range_p.at(0)); // pi wrt q2
+ side_pi_x = sides.apply(range_q.at(0), range_q.at(1), range_p.at(0)); // pi wrt q1
+ side_qz_x = sides.apply(range_q.at(0), range_q.at(1), range_q.at(2)); // qk wrt q1
+ }
+ // 2. ip0 or pj in the middle of q1
+ else
+ {
+ side_pi_y = sides.apply(range_q.at(0), range_q.at(1), range_p.at(0)); // pi wrt q1
+ side_pi_x = side_pi_y; // pi wrt q1
+ side_qz_x = 0; // qj wrt q1
+ }
+
+ std::pair<operation_type, operation_type> operations
+ = get_info_e::operations_of_equal(side_pi_y, side_pi_x, side_qz_x);
tp.operations[0].operation = operations.first;
tp.operations[1].operation = operations.second;
@@ -873,7 +854,6 @@ struct get_turn_info_linear_areal
unsigned int ip_index = ip_count > 1 ? 1 : 0;
base_turn_handler::assign_point(tp, tp.method, inters.i_info(), ip_index);
- AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
// don't ignore the first IP if the segment is opposite
@@ -883,6 +863,14 @@ struct get_turn_info_linear_areal
// don't ignore anything for now
return false;
}
+
+ template <typename Point1, typename Point2, typename IntersectionStrategy>
+ static inline bool equals_point_point(Point1 const& point1, Point2 const& point2,
+ IntersectionStrategy const& strategy)
+ {
+ return detail::equals::equals_point_point(point1, point2,
+ strategy.get_point_in_point_strategy());
+ }
};
}} // namespace detail::overlay
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 58fd4bb5c7..217f4a340b 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp
@@ -3,8 +3,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013, 2014, 2015, 2017.
-// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018.
+// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -36,18 +36,16 @@ struct get_turn_info_linear_linear
template
<
- typename Point1,
- typename Point2,
+ typename UniqueSubRange1,
+ typename UniqueSubRange2,
typename TurnInfo,
typename IntersectionStrategy,
typename RobustPolicy,
typename OutputIterator
>
static inline OutputIterator apply(
- Point1 const& pi, Point1 const& pj, Point1 const& pk,
- Point2 const& qi, Point2 const& qj, Point2 const& qk,
- bool is_p_first, bool is_p_last,
- bool is_q_first, bool is_q_last,
+ UniqueSubRange1 const& range_p,
+ UniqueSubRange2 const& range_q,
TurnInfo const& tp_model,
IntersectionStrategy const& strategy,
RobustPolicy const& robust_policy,
@@ -55,13 +53,13 @@ struct get_turn_info_linear_linear
{
typedef intersection_info
<
- Point1, Point2,
+ UniqueSubRange1, UniqueSubRange2,
typename TurnInfo::point_type,
IntersectionStrategy,
RobustPolicy
> inters_info;
- inters_info inters(pi, pj, pk, qi, qj, qk, strategy, robust_policy);
+ inters_info inters(range_p, range_q, strategy, robust_policy);
char const method = inters.d_info().how;
@@ -74,10 +72,10 @@ struct get_turn_info_linear_linear
case 'a' : // collinear, "at"
case 'f' : // collinear, "from"
case 's' : // starts from the middle
- get_turn_info_for_endpoint<AssignPolicy, true, true>
- ::apply(pi, pj, pk, qi, qj, qk,
- is_p_first, is_p_last, is_q_first, is_q_last,
- tp_model, inters, method_none, out);
+ get_turn_info_for_endpoint<true, true>
+ ::apply(range_p, range_q,
+ tp_model, inters, method_none, out,
+ strategy.get_point_in_point_strategy());
break;
case 'd' : // disjoint: never do anything
@@ -85,10 +83,10 @@ struct get_turn_info_linear_linear
case 'm' :
{
- if ( get_turn_info_for_endpoint<AssignPolicy, false, true>
- ::apply(pi, pj, pk, qi, qj, qk,
- is_p_first, is_p_last, is_q_first, is_q_last,
- tp_model, inters, method_touch_interior, out) )
+ if ( get_turn_info_for_endpoint<false, true>
+ ::apply(range_p, range_q,
+ tp_model, inters, method_touch_interior, out,
+ strategy.get_point_in_point_strategy()) )
{
// do nothing
}
@@ -102,26 +100,16 @@ struct get_turn_info_linear_linear
// If Q (1) arrives (1)
if ( inters.d_info().arrival[1] == 1)
{
- policy::template apply<0>(pi, pj, pk, qi, qj, qk,
- tp, inters.i_info(), inters.d_info(),
+ policy::template apply<0>(range_p, range_q, tp,
+ inters.i_info(), inters.d_info(),
inters.sides());
}
else
{
// Swap p/q
- side_calculator
- <
- typename inters_info::cs_tag,
- typename inters_info::robust_point2_type,
- typename inters_info::robust_point1_type,
- typename inters_info::side_strategy_type
- > swapped_side_calc(inters.rqi(), inters.rqj(), inters.rqk(),
- inters.rpi(), inters.rpj(), inters.rpk(),
- inters.get_side_strategy());
-
- policy::template apply<1>(qi, qj, qk, pi, pj, pk,
- tp, inters.i_info(), inters.d_info(),
- swapped_side_calc);
+ policy::template apply<1>(range_q, range_p, tp,
+ inters.i_info(), inters.d_info(),
+ inters.get_swapped_sides());
}
if ( tp.operations[0].operation == operation_blocked )
@@ -137,36 +125,33 @@ struct get_turn_info_linear_linear
tp.operations[0].operation,
tp.operations[1].operation);
- AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
}
break;
case 'i' :
{
- crosses<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
- tp, inters.i_info(), inters.d_info());
+ crosses<TurnInfo>::apply(tp, inters.i_info(), inters.d_info());
replace_operations_i(tp.operations[0].operation, tp.operations[1].operation);
- AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
break;
case 't' :
{
// Both touch (both arrive there)
- if ( get_turn_info_for_endpoint<AssignPolicy, false, true>
- ::apply(pi, pj, pk, qi, qj, qk,
- is_p_first, is_p_last, is_q_first, is_q_last,
- tp_model, inters, method_touch, out) )
+ if ( get_turn_info_for_endpoint<false, true>
+ ::apply(range_p, range_q,
+ tp_model, inters, method_touch, out,
+ strategy.get_point_in_point_strategy()) )
{
// do nothing
}
else
{
- touch<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
- tp, inters.i_info(), inters.d_info(), inters.sides());
+ touch<TurnInfo>::apply(range_p, range_q, tp,
+ inters.i_info(), inters.d_info(), inters.sides());
// workarounds for touch<> not taking spikes into account starts here
// those was discovered empirically
@@ -276,13 +261,8 @@ struct get_turn_info_linear_linear
tp.operations[0].operation,
tp.operations[1].operation);
-// TODO: move this into the append_xxx and call for each turn?
- AssignPolicy::apply(tp, pi, qi, inters);
-
if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes)
- || ! append_opposite_spikes<append_touches>(tp, inters,
- is_p_last, is_q_last,
- out) )
+ || ! append_opposite_spikes<append_touches>(tp, inters, out) )
{
*out++ = tp;
}
@@ -291,10 +271,10 @@ struct get_turn_info_linear_linear
break;
case 'e':
{
- if ( get_turn_info_for_endpoint<AssignPolicy, true, true>
- ::apply(pi, pj, pk, qi, qj, qk,
- is_p_first, is_p_last, is_q_first, is_q_last,
- tp_model, inters, method_equal, out) )
+ if ( get_turn_info_for_endpoint<true, true>
+ ::apply(range_p, range_q,
+ tp_model, inters, method_equal, out,
+ strategy.get_point_in_point_strategy()) )
{
// do nothing
}
@@ -307,8 +287,8 @@ struct get_turn_info_linear_linear
{
// Both equal
// or collinear-and-ending at intersection point
- equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
- tp, inters.i_info(), inters.d_info(), inters.sides());
+ equal<TurnInfo>::apply(range_p, range_q, tp,
+ inters.i_info(), inters.d_info(), inters.sides());
operation_type spike_op
= ( tp.operations[0].operation != operation_continue
@@ -320,13 +300,9 @@ struct get_turn_info_linear_linear
turn_transformer_ec transformer(method_touch);
transformer(tp);
-// TODO: move this into the append_xxx and call for each turn?
- AssignPolicy::apply(tp, pi, qi, inters);
-
// conditionally handle spikes
if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes)
|| ! append_collinear_spikes(tp, inters,
- is_p_last, is_q_last,
method_touch, spike_op,
out) )
{
@@ -341,7 +317,7 @@ struct get_turn_info_linear_linear
<
TurnInfo,
AssignPolicy
- >::apply(pi, qi, tp, out, inters);
+ >::apply(range_p, range_q, tp, out, inters);
}
}
}
@@ -349,10 +325,10 @@ struct get_turn_info_linear_linear
case 'c' :
{
// Collinear
- if ( get_turn_info_for_endpoint<AssignPolicy, true, true>
- ::apply(pi, pj, pk, qi, qj, qk,
- is_p_first, is_p_last, is_q_first, is_q_last,
- tp_model, inters, method_collinear, out) )
+ if ( get_turn_info_for_endpoint<true, true>
+ ::apply(range_p, range_q,
+ tp_model, inters, method_collinear, out,
+ strategy.get_point_in_point_strategy()) )
{
// do nothing
}
@@ -370,8 +346,8 @@ struct get_turn_info_linear_linear
if ( inters.d_info().arrival[0] == 0 )
{
// Collinear, but similar thus handled as equal
- equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
- tp, inters.i_info(), inters.d_info(), inters.sides());
+ equal<TurnInfo>::apply(range_p, range_q, tp,
+ inters.i_info(), inters.d_info(), inters.sides());
method_replace = method_touch;
if ( tp.operations[0].operation != operation_continue
@@ -382,7 +358,7 @@ struct get_turn_info_linear_linear
}
else
{
- collinear<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
+ collinear<TurnInfo>::apply(range_p, range_q,
tp, inters.i_info(), inters.d_info(), inters.sides());
//method_replace = method_touch_interior;
@@ -393,13 +369,9 @@ struct get_turn_info_linear_linear
turn_transformer_ec transformer(method_replace);
transformer(tp);
-// TODO: move this into the append_xxx and call for each turn?
- AssignPolicy::apply(tp, pi, qi, inters);
-
// conditionally handle spikes
if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes)
|| ! append_collinear_spikes(tp, inters,
- is_p_last, is_q_last,
method_replace, spike_op,
out) )
{
@@ -415,9 +387,7 @@ struct get_turn_info_linear_linear
// conditionally handle spikes
if ( BOOST_GEOMETRY_CONDITION(handle_spikes) )
{
- append_opposite_spikes<append_collinear_opposite>(tp, inters,
- is_p_last, is_q_last,
- out);
+ append_opposite_spikes<append_collinear_opposite>(tp, inters, out);
}
// TODO: ignore for spikes?
@@ -428,9 +398,9 @@ struct get_turn_info_linear_linear
<
TurnInfo,
AssignPolicy
- >::apply(pi, pj, pk, qi, qj, qk,
+ >::apply(range_p, range_q,
tp, out, inters, inters.sides(),
- transformer, !is_p_last, !is_q_last);
+ transformer);
}
}
}
@@ -440,31 +410,33 @@ struct get_turn_info_linear_linear
// degenerate points
if ( BOOST_GEOMETRY_CONDITION(AssignPolicy::include_degenerate) )
{
+ typedef typename IntersectionStrategy::point_in_point_strategy_type
+ equals_strategy_type;
+
only_convert::apply(tp, inters.i_info());
// if any, only one of those should be true
- if ( is_p_first
- && equals::equals_point_point(pi, tp.point) )
+ if ( range_p.is_first_segment()
+ && equals::equals_point_point(range_p.at(0), tp.point, equals_strategy_type()) )
{
tp.operations[0].position = position_front;
}
- else if ( is_p_last
- && equals::equals_point_point(pj, tp.point) )
+ else if ( range_p.is_last_segment()
+ && equals::equals_point_point(range_p.at(1), tp.point, equals_strategy_type()) )
{
tp.operations[0].position = position_back;
}
- else if ( is_q_first
- && equals::equals_point_point(qi, tp.point) )
+ else if ( range_q.is_first_segment()
+ && equals::equals_point_point(range_q.at(0), tp.point, equals_strategy_type()) )
{
tp.operations[1].position = position_front;
}
- else if ( is_q_last
- && equals::equals_point_point(qj, tp.point) )
+ else if ( range_q.is_last_segment()
+ && equals::equals_point_point(range_q.at(1), tp.point, equals_strategy_type()) )
{
tp.operations[1].position = position_back;
}
- AssignPolicy::apply(tp, pi, qi, inters);
*out++ = tp;
}
}
@@ -489,7 +461,6 @@ struct get_turn_info_linear_linear
typename OutIt>
static inline bool append_collinear_spikes(TurnInfo & tp,
IntersectionInfo const& inters_info,
- bool is_p_last, bool is_q_last,
method_type method, operation_type spike_op,
OutIt out)
{
@@ -497,10 +468,8 @@ struct get_turn_info_linear_linear
// both position == middle
bool is_p_spike = tp.operations[0].operation == spike_op
- && ! is_p_last
&& inters_info.is_spike_p();
bool is_q_spike = tp.operations[1].operation == spike_op
- && ! is_q_last
&& inters_info.is_spike_q();
if ( is_p_spike && is_q_spike )
@@ -559,7 +528,6 @@ struct get_turn_info_linear_linear
typename OutIt>
static inline bool append_opposite_spikes(TurnInfo & tp,
IntersectionInfo const& inters,
- bool is_p_last, bool is_q_last,
OutIt out)
{
static const bool is_version_touches = (Version == append_touches);
@@ -568,13 +536,11 @@ struct get_turn_info_linear_linear
( tp.operations[0].operation == operation_continue
|| tp.operations[0].operation == operation_intersection ) :
true )
- && ! is_p_last
&& inters.is_spike_p();
bool is_q_spike = ( is_version_touches ?
( tp.operations[1].operation == operation_continue
|| tp.operations[1].operation == operation_intersection ) :
true )
- && ! is_q_last
&& inters.is_spike_q();
bool res = false;
@@ -598,8 +564,6 @@ struct get_turn_info_linear_linear
base_turn_handler::assign_point(tp, method_touch_interior,
inters.i_info(), 1);
-
- AssignPolicy::apply(tp, inters.pi(), inters.qi(), inters);
}
tp.operations[0].operation = operation_blocked;
@@ -630,8 +594,6 @@ struct get_turn_info_linear_linear
BOOST_GEOMETRY_ASSERT(inters.i_info().count > 0);
base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 0);
-
- AssignPolicy::apply(tp, inters.pi(), inters.qi(), inters);
}
tp.operations[0].operation = operation_intersection;
diff --git a/boost/geometry/algorithms/detail/overlay/get_turns.hpp b/boost/geometry/algorithms/detail/overlay/get_turns.hpp
index 042e65b4e1..886f8b683f 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turns.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turns.hpp
@@ -3,8 +3,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2014-2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2014, 2016, 2017.
-// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2016, 2017, 2018.
+// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -27,6 +27,7 @@
#include <boost/range.hpp>
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
@@ -101,6 +102,113 @@ struct no_interrupt_policy
}
};
+template
+<
+ bool IsAreal,
+ typename Section,
+ typename Point,
+ typename CircularIterator,
+ typename IntersectionStrategy,
+ typename RobustPolicy
+>
+struct unique_sub_range_from_section
+{
+ typedef Point point_type;
+
+ unique_sub_range_from_section(Section const& section, signed_size_type index,
+ CircularIterator circular_iterator,
+ Point const& previous, Point const& current,
+ RobustPolicy const& robust_policy)
+ : m_section(section)
+ , m_index(index)
+ , m_previous_point(previous)
+ , m_current_point(current)
+ , m_circular_iterator(circular_iterator)
+ , m_point_retrieved(false)
+ , m_robust_policy(robust_policy)
+ {
+ }
+
+ inline bool is_first_segment() const
+ {
+ return !IsAreal && m_section.is_non_duplicate_first && m_index == m_section.begin_index;
+ }
+ inline bool is_last_segment() const
+ {
+ return size() == 2u;
+ }
+
+ inline std::size_t size() const
+ {
+ return IsAreal ? 3
+ : m_section.is_non_duplicate_last && m_index + 1 >= m_section.end_index ? 2 : 3;
+ }
+
+ inline Point const& at(std::size_t index) const
+ {
+ BOOST_GEOMETRY_ASSERT(index < size());
+ switch (index)
+ {
+ case 0 : return m_previous_point;
+ case 1 : return m_current_point;
+ case 2 : return get_next_point();
+ default : return m_previous_point;
+ }
+ }
+
+private :
+ inline Point const& get_next_point() const
+ {
+ if (! m_point_retrieved)
+ {
+ advance_to_non_duplicate_next(m_current_point, m_circular_iterator);
+ m_point = *m_circular_iterator;
+ m_point_retrieved = true;
+ }
+ return m_point;
+ }
+
+ inline void advance_to_non_duplicate_next(Point const& current, CircularIterator& circular_iterator) const
+ {
+ typedef typename IntersectionStrategy::point_in_point_strategy_type disjoint_strategy_type;
+ typedef typename robust_point_type<Point, RobustPolicy>::type robust_point_type;
+ robust_point_type current_robust_point;
+ robust_point_type next_robust_point;
+ geometry::recalculate(current_robust_point, current, m_robust_policy);
+ geometry::recalculate(next_robust_point, *circular_iterator, m_robust_policy);
+
+ // To see where the next segments bend to, in case of touch/intersections
+ // on end points, we need (in case of degenerate/duplicate points) an extra
+ // iterator which moves to the REAL next point, so non duplicate.
+ // This needs an extra comparison (disjoint).
+ // (Note that within sections, non duplicate points are already asserted,
+ // by the sectionalize process).
+
+ // So advance to the "non duplicate next"
+ // (the check is defensive, to avoid endless loops)
+ std::size_t check = 0;
+ while(! detail::disjoint::disjoint_point_point
+ (
+ current_robust_point, next_robust_point,
+ disjoint_strategy_type()
+ )
+ && check++ < m_section.range_count)
+ {
+ circular_iterator++;
+ geometry::recalculate(next_robust_point, *circular_iterator, m_robust_policy);
+ }
+ }
+
+ Section const& m_section;
+ signed_size_type m_index;
+ Point const& m_previous_point;
+ Point const& m_current_point;
+ mutable CircularIterator m_circular_iterator;
+ mutable Point m_point;
+ mutable bool m_point_retrieved;
+ RobustPolicy m_robust_policy;
+};
+
template
<
@@ -143,6 +251,8 @@ class get_turns_in_sections
view_type2 const
>::type range2_iterator;
+ typedef ever_circling_iterator<range1_iterator> circular1_iterator;
+ typedef ever_circling_iterator<range2_iterator> circular2_iterator;
template <typename Geometry, typename Section>
static inline bool adjacent(Section const& section,
@@ -187,6 +297,18 @@ public :
{
boost::ignore_unused(interrupt_policy);
+ static bool const areal1 = boost::is_same
+ <
+ typename tag_cast<typename tag<Geometry1>::type, areal_tag>::type,
+ areal_tag
+ >::type::value;
+ static bool const areal2 = boost::is_same
+ <
+ typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
+ areal_tag
+ >::type::value;
+
+
if ((sec1.duplicate && (sec1.count + 1) < sec1.range_count)
|| (sec2.duplicate && (sec2.count + 1) < sec2.range_count))
{
@@ -230,9 +352,14 @@ public :
it1 != end1 && ! detail::section::exceeding<0>(dir1, *prev1, sec1.bounding_box, sec2.bounding_box, robust_policy);
++prev1, ++it1, ++index1, ++next1, ++ndi1)
{
- ever_circling_iterator<range1_iterator> nd_next1(
- begin_range_1, end_range_1, next1, true);
- advance_to_non_duplicate_next(nd_next1, it1, sec1, robust_policy);
+ unique_sub_range_from_section
+ <
+ areal1, Section1, point1_type, circular1_iterator,
+ IntersectionStrategy, RobustPolicy
+ > unique_sub_range1(sec1, index1,
+ circular1_iterator(begin_range_1, end_range_1, next1, true),
+ *prev1, *it1,
+ robust_policy);
signed_size_type index2 = sec2.begin_index;
signed_size_type ndi2 = sec2.non_duplicate_index;
@@ -278,10 +405,14 @@ public :
if (! skip)
{
- // Move to the "non duplicate next"
- ever_circling_iterator<range2_iterator> nd_next2(
- begin_range_2, end_range_2, next2, true);
- advance_to_non_duplicate_next(nd_next2, it2, sec2, robust_policy);
+ unique_sub_range_from_section
+ <
+ areal2, Section2, point2_type, circular2_iterator,
+ IntersectionStrategy, RobustPolicy
+ > unique_sub_range2(sec2, index2,
+ circular2_iterator(begin_range_2, end_range_2, next2),
+ *prev2, *it2,
+ robust_policy);
typedef typename boost::range_value<Turns>::type turn_info;
@@ -295,13 +426,7 @@ public :
std::size_t const size_before = boost::size(turns);
- bool const is_1_first = sec1.is_non_duplicate_first && index1 == sec1.begin_index;
- bool const is_1_last = sec1.is_non_duplicate_last && index1+1 >= sec1.end_index;
- bool const is_2_first = sec2.is_non_duplicate_first && index2 == sec2.begin_index;
- bool const is_2_last = sec2.is_non_duplicate_last && index2+1 >= sec2.end_index;
-
- TurnPolicy::apply(*prev1, *it1, *nd_next1, *prev2, *it2, *nd_next2,
- is_1_first, is_1_last, is_2_first, is_2_last,
+ TurnPolicy::apply(unique_sub_range1, unique_sub_range2,
ti, intersection_strategy, robust_policy,
std::back_inserter(turns));
@@ -327,37 +452,6 @@ private :
typedef typename model::referring_segment<point1_type const> segment1_type;
typedef typename model::referring_segment<point2_type const> segment2_type;
- template <typename Iterator, typename RangeIterator, typename Section, typename RobustPolicy>
- static inline void advance_to_non_duplicate_next(Iterator& next,
- RangeIterator const& it, Section const& section, RobustPolicy const& robust_policy)
- {
- typedef typename robust_point_type<point1_type, RobustPolicy>::type robust_point_type;
- robust_point_type robust_point_from_it;
- robust_point_type robust_point_from_next;
- geometry::recalculate(robust_point_from_it, *it, robust_policy);
- geometry::recalculate(robust_point_from_next, *next, robust_policy);
-
- // To see where the next segments bend to, in case of touch/intersections
- // on end points, we need (in case of degenerate/duplicate points) an extra
- // iterator which moves to the REAL next point, so non duplicate.
- // This needs an extra comparison (disjoint).
- // (Note that within sections, non duplicate points are already asserted,
- // by the sectionalize process).
-
- // So advance to the "non duplicate next"
- // (the check is defensive, to avoid endless loops)
- std::size_t check = 0;
- while(! detail::disjoint::disjoint_point_point
- (
- robust_point_from_it, robust_point_from_next
- )
- && check++ < section.range_count)
- {
- next++;
- geometry::recalculate(robust_point_from_next, *next, robust_policy);
- }
- }
-
// It is NOT possible to have section-iterators here
// because of the logistics of "index" (the section-iterator automatically
// skips to the begin-point, we loose the index or have to recalculate it)
@@ -423,7 +517,9 @@ struct section_visitor
template <typename Section>
inline bool apply(Section const& sec1, Section const& sec2)
{
- if (! detail::disjoint::disjoint_box_box(sec1.bounding_box, sec2.bounding_box))
+ if (! detail::disjoint::disjoint_box_box(sec1.bounding_box,
+ sec2.bounding_box,
+ m_intersection_strategy.get_disjoint_box_box_strategy()))
{
// false if interrupted
return get_turns_in_sections
@@ -482,11 +578,13 @@ public:
typename IntersectionStrategy::envelope_strategy_type const
envelope_strategy = intersection_strategy.get_envelope_strategy();
+ typename IntersectionStrategy::expand_strategy_type const
+ expand_strategy = intersection_strategy.get_expand_strategy();
geometry::sectionalize<Reverse1, dimensions>(geometry1, robust_policy,
- sec1, envelope_strategy, 0);
+ sec1, envelope_strategy, expand_strategy, 0);
geometry::sectionalize<Reverse2, dimensions>(geometry2, robust_policy,
- sec2, envelope_strategy, 1);
+ sec2, envelope_strategy, expand_strategy, 1);
// ... and then partition them, intersecting overlapping sections in visitor method
section_visitor
@@ -500,12 +598,21 @@ public:
intersection_strategy, robust_policy,
turns, interrupt_policy);
+ typedef detail::section::get_section_box
+ <
+ typename IntersectionStrategy::expand_box_strategy_type
+ > get_section_box_type;
+ typedef detail::section::overlaps_section_box
+ <
+ typename IntersectionStrategy::disjoint_box_box_strategy_type
+ > overlaps_section_box_type;
+
geometry::partition
<
box_type
>::apply(sec1, sec2, visitor,
- detail::section::get_section_box(),
- detail::section::overlaps_section_box());
+ get_section_box_type(),
+ overlaps_section_box_type());
}
};
@@ -519,8 +626,9 @@ template
>
struct get_turns_cs
{
- typedef typename geometry::point_type<Range>::type point_type;
+ typedef typename geometry::point_type<Range>::type range_point_type;
typedef typename geometry::point_type<Box>::type box_point_type;
+ typedef boost::array<box_point_type, 4> box_array;
typedef typename closeable_view
<
@@ -539,6 +647,70 @@ struct get_turns_cs
view_type const
>::type iterator_type;
+ struct unique_sub_range_from_box_policy
+ {
+ typedef box_point_type point_type;
+
+ unique_sub_range_from_box_policy(box_array const& box)
+ : m_box(box)
+ , m_index(0)
+ {}
+
+ static inline bool is_first_segment() { return false; }
+ static inline bool is_last_segment() { return false; }
+ static inline std::size_t size() { return 4; }
+
+ inline box_point_type const& at(std::size_t index) const
+ {
+ BOOST_GEOMETRY_ASSERT(index < size());
+ return m_box[(m_index + index) % 4];
+ }
+
+ inline void next()
+ {
+ m_index++;
+ }
+
+ private :
+ box_array const& m_box;
+ std::size_t m_index;
+ };
+
+ struct unique_sub_range_from_view_policy
+ {
+ typedef range_point_type point_type;
+
+ unique_sub_range_from_view_policy(view_type const& view, point_type const& pi, point_type const& pj, iterator_type it)
+ : m_view(view)
+ , m_pi(pi)
+ , m_pj(pj)
+ , m_circular_iterator(boost::begin(view), boost::end(view), it, true)
+ {
+ ++m_circular_iterator;
+ }
+
+ static inline bool is_first_segment() { return false; }
+ static inline bool is_last_segment() { return false; }
+ static inline std::size_t size() { return 3; }
+
+ inline point_type const& at(std::size_t index) const
+ {
+ BOOST_GEOMETRY_ASSERT(index < size());
+ switch (index)
+ {
+ case 0 : return m_pi;
+ case 1 : return m_pj;
+ case 2 : return *m_circular_iterator;
+ default : return m_pi;
+ }
+ }
+
+ private :
+ view_type const& m_view;
+ point_type const& m_pi;
+ point_type const& m_pj;
+ ever_circling_iterator<iterator_type> m_circular_iterator;
+ };
template <typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline void apply(
@@ -556,22 +728,16 @@ struct get_turns_cs
return;
}
- boost::array<box_point_type,4> bp;
- assign_box_corners_oriented<ReverseBox>(box, bp);
+ box_array box_points;
+ assign_box_corners_oriented<ReverseBox>(box, box_points);
cview_type cview(range);
view_type view(cview);
- typedef typename boost::range_size<view_type>::type size_type;
- size_type segments_count1 = boost::size(view) - 1;
-
+ // TODO: in this code, possible duplicate points are not yet taken
+ // into account (not in the iterator, nor in the retrieve policy)
iterator_type it = boost::begin(view);
- ever_circling_iterator<iterator_type> next(
- boost::begin(view), boost::end(view), it, true);
- next++;
- next++;
-
//bool first = true;
//char previous_side[2] = {0, 0};
@@ -580,11 +746,13 @@ struct get_turns_cs
for (iterator_type prev = it++;
it != boost::end(view);
- prev = it++, next++, index++)
+ prev = it++, index++)
{
segment_identifier seg_id(source_id1,
multi_index, ring_index, index);
+ unique_sub_range_from_view_policy view_unique_sub_range(view, *prev, *it, it);
+
/*if (first)
{
previous_side[0] = get_side<0>(box, *prev);
@@ -611,11 +779,8 @@ struct get_turns_cs
if (true)
{
get_turns_with_box(seg_id, source_id2,
- *prev, *it, *next,
- bp[0], bp[1], bp[2], bp[3],
- // NOTE: some dummy values could be passed below since this would be called only for Polygons and Boxes
- index == 0,
- size_type(index) == segments_count1,
+ view_unique_sub_range,
+ box_points,
intersection_strategy,
robust_policy,
turns,
@@ -647,19 +812,16 @@ private:
else return 0;
}
- template <typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
+ template
+ <
+ typename IntersectionStrategy,
+ typename Turns,
+ typename InterruptPolicy,
+ typename RobustPolicy
+ >
static inline void get_turns_with_box(segment_identifier const& seg_id, int source_id2,
- // Points from a range:
- point_type const& rp0,
- point_type const& rp1,
- point_type const& rp2,
- // Points from the box
- box_point_type const& bp0,
- box_point_type const& bp1,
- box_point_type const& bp2,
- box_point_type const& bp3,
- bool const is_range_first,
- bool const is_range_last,
+ unique_sub_range_from_view_policy const& range_unique_sub_range,
+ box_array const& box,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
// Output
@@ -675,31 +837,27 @@ private:
turn_info ti;
ti.operations[0].seg_id = seg_id;
+ unique_sub_range_from_box_policy box_unique_sub_range(box);
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 0);
- TurnPolicy::apply(rp0, rp1, rp2, bp0, bp1, bp2,
- is_range_first, is_range_last,
- true, false,
+ TurnPolicy::apply(range_unique_sub_range, box_unique_sub_range,
ti, intersection_strategy, robust_policy,
std::back_inserter(turns));
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 1);
- TurnPolicy::apply(rp0, rp1, rp2, bp1, bp2, bp3,
- is_range_first, is_range_last,
- false, false,
+ box_unique_sub_range.next();
+ TurnPolicy::apply(range_unique_sub_range, box_unique_sub_range,
ti, intersection_strategy, robust_policy,
std::back_inserter(turns));
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 2);
- TurnPolicy::apply(rp0, rp1, rp2, bp2, bp3, bp0,
- is_range_first, is_range_last,
- false, false,
+ box_unique_sub_range.next();
+ TurnPolicy::apply(range_unique_sub_range, box_unique_sub_range,
ti, intersection_strategy, robust_policy,
std::back_inserter(turns));
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 3);
- TurnPolicy::apply(rp0, rp1, rp2, bp3, bp0, bp1,
- is_range_first, is_range_last,
- false, true,
+ box_unique_sub_range.next();
+ TurnPolicy::apply(range_unique_sub_range, box_unique_sub_range,
ti, intersection_strategy, robust_policy,
std::back_inserter(turns));
diff --git a/boost/geometry/algorithms/detail/overlay/linear_linear.hpp b/boost/geometry/algorithms/detail/overlay/linear_linear.hpp
index 21d079d95c..f0a7d6a7a8 100644
--- a/boost/geometry/algorithms/detail/overlay/linear_linear.hpp
+++ b/boost/geometry/algorithms/detail/overlay/linear_linear.hpp
@@ -139,18 +139,6 @@ protected:
static bool const include_no_turn = false;
static bool const include_degenerate = EnableDegenerateTurns;
static bool const include_opposite = false;
-
- template
- <
- typename Info,
- typename Point1,
- typename Point2,
- typename IntersectionInfo
- >
- static inline void apply(Info& , Point1 const& , Point2 const& ,
- IntersectionInfo const& )
- {
- }
};
diff --git a/boost/geometry/algorithms/detail/overlay/overlay.hpp b/boost/geometry/algorithms/detail/overlay/overlay.hpp
index 5094c6c96c..8a8561c136 100644
--- a/boost/geometry/algorithms/detail/overlay/overlay.hpp
+++ b/boost/geometry/algorithms/detail/overlay/overlay.hpp
@@ -125,6 +125,12 @@ inline void get_ring_turn_info(TurnInfoMap& turn_info_map, Turns const& turns, C
bool cluster_checked = false;
bool has_blocked = false;
+ if (is_self_turn<OverlayType>(turn) && turn.discarded)
+ {
+ // Discarded self-turns don't count as traversed
+ continue;
+ }
+
for (typename boost::range_iterator<container_type const>::type
op_it = boost::begin(turn.operations);
op_it != boost::end(turn.operations);
diff --git a/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp b/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp
index 88aedecf86..afe8f680be 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-2017, Oracle and/or its affiliates.
+// Copyright (c) 2014-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -148,13 +148,13 @@ struct point_point_point
Point2 const& point2,
RobustPolicy const& ,
OutputIterator oit,
- Strategy const&)
+ Strategy const& strategy)
{
action_selector_pl_pl
<
PointOut, OverlayType
>::apply(point1,
- detail::equals::equals_point_point(point1, point2),
+ detail::equals::equals_point_point(point1, point2, strategy),
oit);
return oit;
@@ -182,7 +182,7 @@ struct multipoint_point_point
Point const& point,
RobustPolicy const& ,
OutputIterator oit,
- Strategy const&)
+ Strategy const& strategy)
{
BOOST_GEOMETRY_ASSERT( OverlayType == overlay_difference );
@@ -194,7 +194,7 @@ struct multipoint_point_point
<
PointOut, OverlayType
>::apply(*it,
- detail::equals::equals_point_point(*it, point),
+ detail::equals::equals_point_point(*it, point, strategy),
oit);
}
@@ -218,7 +218,7 @@ struct point_multipoint_point
MultiPoint const& multipoint,
RobustPolicy const& ,
OutputIterator oit,
- Strategy const&)
+ Strategy const& strategy)
{
typedef action_selector_pl_pl<PointOut, OverlayType> action;
@@ -226,7 +226,7 @@ struct point_multipoint_point
it = boost::begin(multipoint);
it != boost::end(multipoint); ++it)
{
- if ( detail::equals::equals_point_point(*it, point) )
+ if ( detail::equals::equals_point_point(*it, point, strategy) )
{
action::apply(point, true, oit);
return oit;
diff --git a/boost/geometry/algorithms/detail/overlay/select_rings.hpp b/boost/geometry/algorithms/detail/overlay/select_rings.hpp
index 262ba748ab..9b88ddf8b4 100644
--- a/boost/geometry/algorithms/detail/overlay/select_rings.hpp
+++ b/boost/geometry/algorithms/detail/overlay/select_rings.hpp
@@ -21,7 +21,6 @@
#include <boost/geometry/core/tags.hpp>
-#include <boost/geometry/algorithms/area.hpp>
#include <boost/geometry/algorithms/covered_by.hpp>
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
diff --git a/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp b/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp
index 3cc98d3b7e..261d2c4b03 100644
--- a/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp
+++ b/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp
@@ -3,8 +3,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2017.
-// Modifications copyright (c) 2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2017, 2018.
+// Modifications copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -99,7 +99,9 @@ struct self_section_visitor
template <typename Section>
inline bool apply(Section const& sec1, Section const& sec2)
{
- if (! detail::disjoint::disjoint_box_box(sec1.bounding_box, sec2.bounding_box)
+ if (! detail::disjoint::disjoint_box_box(sec1.bounding_box,
+ sec2.bounding_box,
+ m_intersection_strategy.get_disjoint_box_box_strategy())
&& ! sec1.duplicate
&& ! sec2.duplicate)
{
@@ -154,7 +156,8 @@ struct get_turns
sections_type sec;
geometry::sectionalize<Reverse, dimensions>(geometry, robust_policy, sec,
- intersection_strategy.get_envelope_strategy());
+ intersection_strategy.get_envelope_strategy(),
+ intersection_strategy.get_expand_strategy());
self_section_visitor
<
@@ -162,13 +165,22 @@ struct get_turns
Turns, TurnPolicy, IntersectionStrategy, RobustPolicy, InterruptPolicy
> visitor(geometry, intersection_strategy, robust_policy, turns, interrupt_policy, source_index, skip_adjacent);
+ typedef detail::section::get_section_box
+ <
+ typename IntersectionStrategy::expand_box_strategy_type
+ > get_section_box_type;
+ typedef detail::section::overlaps_section_box
+ <
+ typename IntersectionStrategy::disjoint_box_box_strategy_type
+ > overlaps_section_box_type;
+
// false if interrupted
geometry::partition
<
box_type
>::apply(sec, visitor,
- detail::section::get_section_box(),
- detail::section::overlaps_section_box());
+ get_section_box_type(),
+ overlaps_section_box_type());
return ! interrupt_policy.has_intersections;
}
@@ -324,6 +336,8 @@ inline void self_turns(Geometry const& geometry,
\param turns container which will contain intersection points
\param interrupt_policy policy determining if process is stopped
when intersection is found
+ \param source_index source index for generated turns
+ \param skip_adjacent indicates if adjacent turns should be skipped
*/
template
<
diff --git a/boost/geometry/algorithms/detail/overlay/stream_info.hpp b/boost/geometry/algorithms/detail/overlay/stream_info.hpp
index 51fd1b3dca..307d9ff805 100644
--- a/boost/geometry/algorithms/detail/overlay/stream_info.hpp
+++ b/boost/geometry/algorithms/detail/overlay/stream_info.hpp
@@ -2,6 +2,11 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018 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)
@@ -12,7 +17,7 @@
#include <string>
-#include <boost/array.hpp>
+#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
namespace boost { namespace geometry
@@ -32,8 +37,8 @@ namespace detail { namespace overlay
return h == 0 ? "-" : (h == 1 ? "A" : "D");
}
- template <typename P>
- std::ostream& operator<<(std::ostream &os, turn_info<P> const& info)
+ template <typename P, typename SR, typename O, typename C>
+ std::ostream& operator<<(std::ostream &os, turn_info<P, SR, O, C> const& info)
{
os << "\t"
<< " src " << info.seg_id.source_index
@@ -46,10 +51,10 @@ namespace detail { namespace overlay
<< (info.opposite ? " o" : "")
<< "]"
<< " sd "
- << dir(info.sides.get<0,0>())
- << dir(info.sides.get<0,1>())
- << dir(info.sides.get<1,0>())
- << dir(info.sides.get<1,1>())
+ << dir(info.sides.template get<0,0>())
+ << dir(info.sides.template get<0,1>())
+ << dir(info.sides.template get<1,0>())
+ << dir(info.sides.template get<1,1>())
<< " nxt seg " << info.travels_to_vertex_index
<< " , ip " << info.travels_to_ip_index
<< " , or " << info.next_ip_index
diff --git a/boost/geometry/algorithms/detail/overlay/traversal.hpp b/boost/geometry/algorithms/detail/overlay/traversal.hpp
index 90ee240138..3a7d82ce0a 100644
--- a/boost/geometry/algorithms/detail/overlay/traversal.hpp
+++ b/boost/geometry/algorithms/detail/overlay/traversal.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2017.
-// Modifications copyright (c) 2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2017, 2018.
+// Modifications copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -15,9 +15,11 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TRAVERSAL_HPP
#include <cstddef>
+#include <set>
#include <boost/range.hpp>
+#include <boost/geometry/algorithms/detail/overlay/cluster_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/is_self_turn.hpp>
#include <boost/geometry/algorithms/detail/overlay/sort_by_side.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
@@ -103,6 +105,23 @@ template
>
struct traversal
{
+private :
+ struct linked_turn_op_info
+ {
+ explicit linked_turn_op_info(signed_size_type ti = -1, int oi = -1,
+ signed_size_type nti = -1)
+ : turn_index(ti)
+ , op_index(oi)
+ , next_turn_index(nti)
+ , rank_index(-1)
+ {}
+
+ signed_size_type turn_index;
+ int op_index;
+ signed_size_type next_turn_index;
+ signed_size_type rank_index;
+ };
+
static const operation_type target_operation = operation_from_overlay<OverlayType>::value;
typedef typename side_compare<target_operation>::type side_compare_type;
@@ -116,6 +135,7 @@ struct traversal
point_type, SideStrategy, side_compare_type
> sbs_type;
+public :
inline traversal(Geometry1 const& geometry1, Geometry2 const& geometry2,
Turns& turns, Clusters const& clusters,
RobustPolicy const& robust_policy, SideStrategy const& strategy,
@@ -352,35 +372,72 @@ struct traversal
// If both are valid candidates, take the one with minimal remaining
// distance (important for #mysql_23023665 in buffer).
- // Initialize with 0, automatically assigned on first result
+ signed_size_type next[2] = {0};
+ bool possible[2] = {0};
+ bool close[2] = {0};
+
+ for (int i = 0; i < 2; i++)
+ {
+ next[i] = turn.operations[i].enriched.get_next_turn_index();
+ possible[i] = traverse_possible(next[i]);
+ close[i] = possible[i] && next[i] == start_turn_index;
+ }
+
+ if (close[0] != close[1])
+ {
+ // One of the operations will finish the ring. Take that one.
+ selected_op_index = close[0] ? 0 : 1;
+ debug_traverse(turn, turn.operations[selected_op_index], "Candidate cc closing");
+ return true;
+ }
+
+ if (OverlayType == overlay_buffer && possible[0] && possible[1])
+ {
+ // Buffers sometimes have multiple overlapping pieces, where remaining
+ // distance could lead to the wrong choice. Take the matching operation.
+
+ bool is_target[2] = {0};
+ for (int i = 0; i < 2; i++)
+ {
+ turn_operation_type const& next_op = m_turns[next[i]].operations[i];
+ is_target[i] = next_op.operation == target_operation;
+ }
+
+ if (is_target[0] != is_target[1])
+ {
+ // Take the matching operation
+ selected_op_index = is_target[0] ? 0 : 1;
+ debug_traverse(turn, turn.operations[selected_op_index], "Candidate cc target");
+ return true;
+ }
+ }
+
+ static bool const is_union = target_operation == operation_union;
+
typename turn_operation_type::comparable_distance_type
- min_remaining_distance = 0;
+ best_remaining_distance = 0;
bool result = false;
for (int i = 0; i < 2; i++)
{
- turn_operation_type const& op = turn.operations[i];
-
- signed_size_type const next_turn_index = op.enriched.get_next_turn_index();
-
- if (! traverse_possible(next_turn_index))
+ if (!possible[i])
{
continue;
}
+ turn_operation_type const& op = turn.operations[i];
+
if (! result
- || next_turn_index == start_turn_index
- || op.remaining_distance < min_remaining_distance)
+ || (is_union && op.remaining_distance > best_remaining_distance)
+ || (!is_union && op.remaining_distance < best_remaining_distance))
{
debug_traverse(turn, op, "First candidate cc", ! result);
- debug_traverse(turn, op, "Candidate cc override (start)",
- result && next_turn_index == start_turn_index);
debug_traverse(turn, op, "Candidate cc override (remaining)",
- result && op.remaining_distance < min_remaining_distance);
+ result && op.remaining_distance < best_remaining_distance);
selected_op_index = i;
- min_remaining_distance = op.remaining_distance;
+ best_remaining_distance = op.remaining_distance;
result = true;
}
}
@@ -710,24 +767,163 @@ struct traversal
return false;
}
- inline bool select_turn_from_cluster(signed_size_type& turn_index,
+ inline signed_size_type get_rank(sbs_type const& sbs,
+ linked_turn_op_info const& info) const
+ {
+ for (std::size_t i = 0; i < sbs.m_ranked_points.size(); i++)
+ {
+ typename sbs_type::rp const& rp = sbs.m_ranked_points[i];
+ if (rp.turn_index == info.turn_index
+ && rp.operation_index == info.op_index
+ && rp.direction == sort_by_side::dir_to)
+ {
+ return rp.rank;
+ }
+ }
+ return -1;
+ }
+
+ // Function checks simple cases, such as a cluster with two turns,
+ // arriving at the first turn, first turn points to second turn,
+ // second turn points further.
+ inline bool select_turn_from_cluster_linked(signed_size_type& turn_index,
int& op_index,
- signed_size_type start_turn_index, int start_op_index,
+ std::set<signed_size_type> const& ids,
segment_identifier const& previous_seg_id) const
{
- bool const is_union = target_operation == operation_union;
+ typedef typename std::set<signed_size_type>::const_iterator sit_type;
- turn_type const& turn = m_turns[turn_index];
- BOOST_ASSERT(turn.is_clustered());
+ std::vector<linked_turn_op_info> possibilities;
+ std::vector<linked_turn_op_info> blocked;
+ for (sit_type it = ids.begin(); it != ids.end(); ++it)
+ {
+ signed_size_type cluster_turn_index = *it;
+ turn_type const& cluster_turn = m_turns[cluster_turn_index];
+ if (cluster_turn.discarded)
+ {
+ continue;
+ }
+ if (is_self_turn<OverlayType>(cluster_turn)
+ || cluster_turn.both(target_operation))
+ {
+ // Not (yet) supported, can be cluster of u/u turns
+ return false;
+ }
+ for (int i = 0; i < 2; i++)
+ {
+ turn_operation_type const& op = cluster_turn.operations[i];
+ turn_operation_type const& other_op = cluster_turn.operations[1 - i];
+ signed_size_type const ni = op.enriched.get_next_turn_index();
+ if (op.operation == target_operation
+ || op.operation == operation_continue)
+ {
+ if (ni == cluster_turn_index)
+ {
+ // Not (yet) supported, traveling to itself, can be
+ // hole
+ return false;
+ }
+ possibilities.push_back(
+ linked_turn_op_info(cluster_turn_index, i, ni));
+ }
+ else if (op.operation == operation_blocked
+ && ! (ni == other_op.enriched.get_next_turn_index())
+ && ids.count(ni) == 0)
+ {
+ // Points to turn, not part of this cluster,
+ // and that way is blocked. But if the other operation
+ // points at the same turn, it is still fine.
+ blocked.push_back(
+ linked_turn_op_info(cluster_turn_index, i, ni));
+ }
+ }
+ }
- typename Clusters::const_iterator mit = m_clusters.find(turn.cluster_id);
- BOOST_ASSERT(mit != m_clusters.end());
+ typedef typename std::vector<linked_turn_op_info>::const_iterator const_it_type;
- cluster_info const& cinfo = mit->second;
- std::set<signed_size_type> const& ids = cinfo.turn_indices;
+ if (! blocked.empty())
+ {
+ sbs_type sbs(m_strategy);
- sbs_type sbs(m_strategy);
+ if (! fill_sbs(sbs, turn_index, ids, previous_seg_id))
+ {
+ return false;
+ }
+
+ for (typename std::vector<linked_turn_op_info>::iterator it = possibilities.begin();
+ it != possibilities.end(); ++it)
+ {
+ linked_turn_op_info& info = *it;
+ info.rank_index = get_rank(sbs, info);
+ }
+ for (typename std::vector<linked_turn_op_info>::iterator it = blocked.begin();
+ it != blocked.end(); ++it)
+ {
+ linked_turn_op_info& info = *it;
+ info.rank_index = get_rank(sbs, info);
+ }
+
+
+ for (const_it_type it = possibilities.begin();
+ it != possibilities.end(); ++it)
+ {
+ linked_turn_op_info const& lti = *it;
+ for (const_it_type bit = blocked.begin();
+ bit != blocked.end(); ++bit)
+ {
+ linked_turn_op_info const& blti = *bit;
+ if (blti.next_turn_index == lti.next_turn_index
+ && blti.rank_index == lti.rank_index)
+ {
+ return false;
+ }
+ }
+ }
+ }
+
+ // Traversal can either enter the cluster in the first turn,
+ // or it can start halfway.
+ // If there is one (and only one) possibility pointing outside
+ // the cluster, take that one.
+ linked_turn_op_info target;
+ for (const_it_type it = possibilities.begin();
+ it != possibilities.end(); ++it)
+ {
+ linked_turn_op_info const& lti = *it;
+ if (ids.count(lti.next_turn_index) == 0)
+ {
+ if (target.turn_index >= 0
+ && target.next_turn_index != lti.next_turn_index)
+ {
+ // Points to different target
+ return false;
+ }
+ if (OverlayType == overlay_buffer && target.turn_index > 0)
+ {
+ // Target already assigned, so there are more targets
+ // or more ways to the same target
+ return false;
+ }
+
+ target = lti;
+ }
+ }
+ if (target.turn_index < 0)
+ {
+ return false;
+ }
+
+ turn_index = target.turn_index;
+ op_index = target.op_index;
+ return true;
+ }
+
+ inline bool fill_sbs(sbs_type& sbs,
+ signed_size_type turn_index,
+ std::set<signed_size_type> const& ids,
+ segment_identifier const& previous_seg_id) const
+ {
for (typename std::set<signed_size_type>::const_iterator sit = ids.begin();
sit != ids.end(); ++sit)
{
@@ -753,7 +949,39 @@ struct traversal
{
return false;
}
+ turn_type const& turn = m_turns[turn_index];
sbs.apply(turn.point);
+ return true;
+ }
+
+
+ inline bool select_turn_from_cluster(signed_size_type& turn_index,
+ int& op_index,
+ signed_size_type start_turn_index, int start_op_index,
+ segment_identifier const& previous_seg_id) const
+ {
+ bool const is_union = target_operation == operation_union;
+
+ turn_type const& turn = m_turns[turn_index];
+ BOOST_ASSERT(turn.is_clustered());
+
+ typename Clusters::const_iterator mit = m_clusters.find(turn.cluster_id);
+ BOOST_ASSERT(mit != m_clusters.end());
+
+ cluster_info const& cinfo = mit->second;
+ std::set<signed_size_type> const& ids = cinfo.turn_indices;
+
+ if (select_turn_from_cluster_linked(turn_index, op_index, ids, previous_seg_id))
+ {
+ return true;
+ }
+
+ sbs_type sbs(m_strategy);
+
+ if (! fill_sbs(sbs, turn_index, ids, previous_seg_id))
+ {
+ return false;
+ }
bool result = false;
diff --git a/boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp b/boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp
index 7f80c8313a..99b2834f15 100644
--- a/boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp
+++ b/boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2017.
-// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2017, 2018.
+// Modifications copyright (c) 2017-2018, 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,
@@ -17,6 +17,7 @@
#include <boost/range.hpp>
+#include <boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp>
#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/traversal.hpp>
@@ -208,10 +209,11 @@ struct traversal_ring_creator
if (start_turn.is_clustered())
{
- turn_type const& turn = m_turns[current_turn_index];
- if (turn.cluster_id == start_turn.cluster_id)
+ turn_type& turn = m_turns[current_turn_index];
+ turn_operation_type& op = turn.operations[current_op_index];
+ if (turn.cluster_id == start_turn.cluster_id
+ && op.enriched.get_next_turn_index() == start_turn_index)
{
- turn_operation_type& op = m_turns[start_turn_index].operations[current_op_index];
op.visited.set_finished();
m_visitor.visit_traverse(m_turns, m_turns[current_turn_index], start_op, "Early finish (cluster)");
return traverse_error_none;
@@ -306,6 +308,23 @@ struct traversal_ring_creator
}
}
+ int get_operation_index(turn_type const& turn) const
+ {
+ // When starting with a continue operation, the one
+ // with the smallest (for intersection) or largest (for union)
+ // remaining distance (#8310b)
+ // Also to avoid skipping a turn in between, which can happen
+ // in rare cases (e.g. #130)
+ static const bool is_union
+ = operation_from_overlay<OverlayType>::value == operation_union;
+
+ turn_operation_type const& op0 = turn.operations[0];
+ turn_operation_type const& op1 = turn.operations[1];
+ return op0.remaining_distance <= op1.remaining_distance
+ ? (is_union ? 1 : 0)
+ : (is_union ? 0 : 1);
+ }
+
template <typename Rings>
void iterate(Rings& rings, std::size_t& finalized_ring_size,
typename Backtrack::state_type& state)
@@ -322,15 +341,8 @@ struct traversal_ring_creator
if (turn.both(operation_continue))
{
- // Traverse only one turn, the one with the SMALLEST remaining distance
- // to avoid skipping a turn in between, which can happen in rare cases
- // (e.g. #130)
- turn_operation_type const& op0 = turn.operations[0];
- turn_operation_type const& op1 = turn.operations[1];
- int const op_index
- = op0.remaining_distance <= op1.remaining_distance ? 0 : 1;
-
- traverse_with_operation(turn, turn_index, op_index,
+ traverse_with_operation(turn, turn_index,
+ get_operation_index(turn),
rings, finalized_ring_size, state);
}
else
@@ -373,13 +385,8 @@ struct traversal_ring_creator
if (turn.both(operation_continue))
{
- // Traverse only one turn, the one with the SMALLEST remaining distance
- // to avoid skipping a turn in between, which can happen in rare cases
- // (e.g. #130)
- int const op_index
- = op0.remaining_distance <= op1.remaining_distance ? 0 : 1;
-
- traverse_with_operation(turn, turn_index, op_index,
+ traverse_with_operation(turn, turn_index,
+ get_operation_index(turn),
rings, finalized_ring_size, state);
}
else
diff --git a/boost/geometry/algorithms/detail/overlay/traversal_switch_detector.hpp b/boost/geometry/algorithms/detail/overlay/traversal_switch_detector.hpp
index 8bdb03df5d..2732531324 100644
--- a/boost/geometry/algorithms/detail/overlay/traversal_switch_detector.hpp
+++ b/boost/geometry/algorithms/detail/overlay/traversal_switch_detector.hpp
@@ -2,6 +2,11 @@
// Copyright (c) 2015-2016 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018 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)
@@ -10,6 +15,7 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TRAVERSAL_SWITCH_DETECTOR_HPP
#include <cstddef>
+#include <map>
#include <boost/range.hpp>
diff --git a/boost/geometry/algorithms/detail/point_on_border.hpp b/boost/geometry/algorithms/detail/point_on_border.hpp
index 831081aa69..b3e14fecbd 100644
--- a/boost/geometry/algorithms/detail/point_on_border.hpp
+++ b/boost/geometry/algorithms/detail/point_on_border.hpp
@@ -4,8 +4,8 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2017.
-// Modifications copyright (c) 2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2017, 2018.
+// Modifications copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@@ -56,117 +56,47 @@ struct get_point
}
};
-template<typename Point, std::size_t Dimension, std::size_t DimensionCount>
-struct midpoint_helper
-{
- template <typename InputPoint>
- static inline bool apply(Point& p, InputPoint const& p1, InputPoint const& p2)
- {
- typename coordinate_type<Point>::type const two = 2;
- set<Dimension>(p,
- (get<Dimension>(p1) + get<Dimension>(p2)) / two);
- return midpoint_helper<Point, Dimension + 1, DimensionCount>::apply(p, p1, p2);
- }
-};
-
-template <typename Point, std::size_t DimensionCount>
-struct midpoint_helper<Point, DimensionCount, DimensionCount>
-{
- template <typename InputPoint>
- static inline bool apply(Point& , InputPoint const& , InputPoint const& )
- {
- return true;
- }
-};
-
-
-template <bool Midpoint>
struct point_on_range
{
// Version with iterator
template<typename Point, typename Iterator>
static inline bool apply(Point& point, Iterator begin, Iterator end)
{
- Iterator it = begin;
- if (it == end)
+ if (begin == end)
{
return false;
}
- if (! Midpoint)
- {
- geometry::detail::conversion::convert_point_to_point(*it, point);
- return true;
- }
-
- Iterator prev = it++;
-
- // Go to next non-duplicate point
- while (it != end
- && detail::equals::equals_point_point(*it, *prev))
- {
- prev = it++;
- }
- if (it != end)
- {
- return midpoint_helper
- <
- Point,
- 0, dimension<Point>::value
- >::apply(point, *prev, *it);
- }
- return false;
+ geometry::detail::conversion::convert_point_to_point(*begin, point);
+ return true;
}
// Version with range
template<typename Point, typename Range>
static inline bool apply(Point& point, Range const& range)
{
- typedef typename geometry::cs_tag<Point>::type cs_tag;
- BOOST_STATIC_ASSERT((! Midpoint || boost::is_same<cs_tag, cartesian_tag>::value));
-
return apply(point, boost::begin(range), boost::end(range));
}
};
-template <bool Midpoint>
struct point_on_polygon
{
template<typename Point, typename Polygon>
static inline bool apply(Point& point, Polygon const& polygon)
{
- return point_on_range
- <
- Midpoint
- >::apply(point, exterior_ring(polygon));
+ return point_on_range::apply(point, exterior_ring(polygon));
}
};
-template <bool Midpoint>
struct point_on_box
{
template<typename Point, typename Box>
static inline bool apply(Point& point, Box const& box)
{
- if (BOOST_GEOMETRY_CONDITION(Midpoint))
- {
- Point p1, p2;
- detail::assign::assign_box_2d_corner<min_corner, min_corner>(box, p1);
- detail::assign::assign_box_2d_corner<max_corner, min_corner>(box, p2);
- midpoint_helper
- <
- Point,
- 0, dimension<Point>::value
- >::apply(point, p1, p2);
- }
- else
- {
- detail::assign::assign_box_2d_corner<min_corner, min_corner>(box, point);
- }
-
+ detail::assign::assign_box_2d_corner<min_corner, min_corner>(box, point);
return true;
}
};
@@ -206,60 +136,50 @@ namespace dispatch
{
-template
-<
- typename GeometryTag,
- bool Midpoint
-
->
+template <typename GeometryTag>
struct point_on_border
{};
-
-template <bool Midpoint>
-struct point_on_border<point_tag, Midpoint>
+template <>
+struct point_on_border<point_tag>
: detail::point_on_border::get_point
{};
-
-template <bool Midpoint>
-struct point_on_border<linestring_tag, Midpoint>
- : detail::point_on_border::point_on_range<Midpoint>
+template <>
+struct point_on_border<linestring_tag>
+ : detail::point_on_border::point_on_range
{};
-
-template <bool Midpoint>
-struct point_on_border<ring_tag, Midpoint>
- : detail::point_on_border::point_on_range<Midpoint>
+template <>
+struct point_on_border<ring_tag>
+ : detail::point_on_border::point_on_range
{};
-
-template <bool Midpoint>
-struct point_on_border<polygon_tag, Midpoint>
- : detail::point_on_border::point_on_polygon<Midpoint>
+template <>
+struct point_on_border<polygon_tag>
+ : detail::point_on_border::point_on_polygon
{};
-
-template <bool Midpoint>
-struct point_on_border<box_tag, Midpoint>
- : detail::point_on_border::point_on_box<Midpoint>
+template <>
+struct point_on_border<box_tag>
+ : detail::point_on_border::point_on_box
{};
-template <bool Midpoint>
-struct point_on_border<multi_polygon_tag, Midpoint>
+template <>
+struct point_on_border<multi_polygon_tag>
: detail::point_on_border::point_on_multi
<
- detail::point_on_border::point_on_polygon<Midpoint>
+ detail::point_on_border::point_on_polygon
>
{};
-template <bool Midpoint>
-struct point_on_border<multi_linestring_tag, Midpoint>
+template <>
+struct point_on_border<multi_linestring_tag>
: detail::point_on_border::point_on_multi
<
- detail::point_on_border::point_on_range<Midpoint>
+ detail::point_on_border::point_on_range
>
{};
@@ -286,33 +206,11 @@ inline bool point_on_border(Point& point, Geometry const& geometry)
return dispatch::point_on_border
<
- typename tag<Geometry>::type,
- false
+ typename tag<Geometry>::type
>::apply(point, geometry);
}
-/*!
-\tparam Midpoint boolean flag, true if the point should not be a vertex, but some point
- in between of two vertices
-\note for Midpoint, it is not taken from two consecutive duplicate vertices,
- (unless there are no other).
- */
-/*
-template <bool Midpoint, typename Point, typename Geometry>
-inline bool point_on_border(Point& point, Geometry const& geometry)
-{
- concepts::check<Point>();
- concepts::check<Geometry const>();
-
- return dispatch::point_on_border
- <
- typename tag<Geometry>::type,
- Midpoint
- >::apply(point, geometry);
-}
-*/
-
}} // namespace boost::geometry
diff --git a/boost/geometry/algorithms/detail/relate/areal_areal.hpp b/boost/geometry/algorithms/detail/relate/areal_areal.hpp
index 800fbb2e96..fa0ab1ea0f 100644
--- a/boost/geometry/algorithms/detail/relate/areal_areal.hpp
+++ b/boost/geometry/algorithms/detail/relate/areal_areal.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014, 2015, 2017.
-// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018.
+// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -277,7 +277,8 @@ struct areal_areal
{
// analyse sorted turns
turns_analyser<turn_type, 0> analyser;
- analyse_each_turn(result, analyser, turns.begin(), turns.end());
+ analyse_each_turn(result, analyser, turns.begin(), turns.end(),
+ point_in_areal_strategy12.get_equals_point_point_strategy());
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
@@ -317,7 +318,8 @@ struct areal_areal
{
// analyse sorted turns
turns_analyser<turn_type, 1> analyser;
- analyse_each_turn(result, analyser, turns.begin(), turns.end());
+ analyse_each_turn(result, analyser, turns.begin(), turns.end(),
+ point_in_areal_strategy21.get_equals_point_point_strategy());
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
@@ -441,9 +443,8 @@ struct areal_areal
, m_exit_detected(false)
{}
- template <typename Result,
- typename TurnIt>
- void apply(Result & result, TurnIt it)
+ template <typename Result, typename TurnIt, typename EqPPStrategy>
+ void apply(Result & result, TurnIt it, EqPPStrategy const& strategy)
{
//BOOST_GEOMETRY_ASSERT( it != last );
@@ -468,7 +469,7 @@ struct areal_areal
{
// real exit point - may be multiple
if ( first_in_range
- || ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it) )
+ || ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it, strategy) )
{
update_exit(result);
m_exit_detected = false;
@@ -484,7 +485,7 @@ struct areal_areal
{
// real entry point
if ( first_in_range
- || ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it) )
+ || ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it, strategy) )
{
update_enter(result);
m_enter_detected = false;
@@ -581,19 +582,24 @@ struct areal_areal
// call analyser.apply() for each turn in range
// IMPORTANT! The analyser is also called for the end iterator - last
- template <typename Result,
- typename Analyser,
- typename TurnIt>
+ template
+ <
+ typename Result,
+ typename Analyser,
+ typename TurnIt,
+ typename EqPPStrategy
+ >
static inline void analyse_each_turn(Result & res,
Analyser & analyser,
- TurnIt first, TurnIt last)
+ TurnIt first, TurnIt last,
+ EqPPStrategy const& strategy)
{
if ( first == last )
return;
for ( TurnIt it = first ; it != last ; ++it )
{
- analyser.apply(res, it);
+ analyser.apply(res, it, strategy);
if ( BOOST_GEOMETRY_CONDITION(res.interrupt) )
return;
diff --git a/boost/geometry/algorithms/detail/relate/boundary_checker.hpp b/boost/geometry/algorithms/detail/relate/boundary_checker.hpp
index 99385e06f9..dc927d9026 100644
--- a/boost/geometry/algorithms/detail/relate/boundary_checker.hpp
+++ b/boost/geometry/algorithms/detail/relate/boundary_checker.hpp
@@ -1,24 +1,26 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014 Oracle and/or its affiliates.
+// Copyright (c) 2014-2018 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_BOUNDARY_CHECKER_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_BOUNDARY_CHECKER_HPP
#include <boost/core/ignore_unused.hpp>
-#include <boost/geometry/util/range.hpp>
-#include <boost/geometry/algorithms/num_points.hpp>
-#include <boost/geometry/algorithms/detail/sub_range.hpp>
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
+#include <boost/geometry/algorithms/detail/sub_range.hpp>
+#include <boost/geometry/algorithms/num_points.hpp>
+
+#include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/util/has_nan_coordinate.hpp>
+#include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry
{
@@ -29,19 +31,26 @@ namespace detail { namespace relate {
enum boundary_query { boundary_front, boundary_back, boundary_any };
template <typename Geometry,
+ typename WithinStrategy, // Point/Point equals (within) strategy
typename Tag = typename geometry::tag<Geometry>::type>
class boundary_checker {};
-template <typename Geometry>
-class boundary_checker<Geometry, linestring_tag>
+template <typename Geometry, typename WithinStrategy>
+class boundary_checker<Geometry, WithinStrategy, linestring_tag>
{
typedef typename point_type<Geometry>::type point_type;
public:
+ typedef WithinStrategy equals_strategy_type;
+
boundary_checker(Geometry const& g)
: has_boundary( boost::size(g) >= 2
- && !detail::equals::equals_point_point(range::front(g), range::back(g)) )
+ && !detail::equals::equals_point_point(range::front(g),
+ range::back(g),
+ equals_strategy_type()) )
+#ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER
, geometry(g)
+#endif
{}
template <boundary_query BoundaryQuery>
@@ -51,24 +60,28 @@ public:
#ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER
// may give false positives for INT
BOOST_GEOMETRY_ASSERT( (BoundaryQuery == boundary_front || BoundaryQuery == boundary_any)
- && detail::equals::equals_point_point(pt, range::front(geometry))
+ && detail::equals::equals_point_point(pt, range::front(geometry), WithinStrategy())
|| (BoundaryQuery == boundary_back || BoundaryQuery == boundary_any)
- && detail::equals::equals_point_point(pt, range::back(geometry)) );
+ && detail::equals::equals_point_point(pt, range::back(geometry), WithinStrategy()) );
#endif
return has_boundary;
}
private:
bool has_boundary;
+#ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER
Geometry const& geometry;
+#endif
};
-template <typename Geometry>
-class boundary_checker<Geometry, multi_linestring_tag>
+template <typename Geometry, typename WithinStrategy>
+class boundary_checker<Geometry, WithinStrategy, multi_linestring_tag>
{
typedef typename point_type<Geometry>::type point_type;
public:
+ typedef WithinStrategy equals_strategy_type;
+
boundary_checker(Geometry const& g)
: is_filled(false), geometry(g)
{}
@@ -111,7 +124,7 @@ public:
point_reference back_pt = range::back(ls);
// linear ring or point - no boundary
- if (! equals::equals_point_point(front_pt, back_pt))
+ if (! equals::equals_point_point(front_pt, back_pt, equals_strategy_type()))
{
// do not add points containing NaN coordinates
// because they cannot be reasonably compared, e.g. with MSVC
diff --git a/boost/geometry/algorithms/detail/relate/follow_helpers.hpp b/boost/geometry/algorithms/detail/relate/follow_helpers.hpp
index 11e95a0b35..139664cc7c 100644
--- a/boost/geometry/algorithms/detail/relate/follow_helpers.hpp
+++ b/boost/geometry/algorithms/detail/relate/follow_helpers.hpp
@@ -2,25 +2,33 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014.
-// Modifications copyright (c) 2013-2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2018.
+// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_FOLLOW_HELPERS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_FOLLOW_HELPERS_HPP
+#include <vector>
+
#include <boost/core/ignore_unused.hpp>
+#include <boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp>
+#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
+#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
+#include <boost/geometry/algorithms/detail/relate/boundary_checker.hpp>
+#include <boost/geometry/algorithms/not_implemented.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>
namespace boost { namespace geometry
{
@@ -333,8 +341,9 @@ private:
std::vector<point_info> m_other_entry_points; // TODO: use map here or sorted vector?
};
-template <std::size_t OpId, typename Turn>
-inline bool turn_on_the_same_ip(Turn const& prev_turn, Turn const& curr_turn)
+template <std::size_t OpId, typename Turn, typename EqPPStrategy>
+inline bool turn_on_the_same_ip(Turn const& prev_turn, Turn const& curr_turn,
+ EqPPStrategy const& strategy)
{
segment_identifier const& prev_seg_id = prev_turn.operations[OpId].seg_id;
segment_identifier const& curr_seg_id = curr_turn.operations[OpId].seg_id;
@@ -354,7 +363,7 @@ inline bool turn_on_the_same_ip(Turn const& prev_turn, Turn const& curr_turn)
return false;
}
- return detail::equals::equals_point_point(prev_turn.point, curr_turn.point);
+ return detail::equals::equals_point_point(prev_turn.point, curr_turn.point, strategy);
}
template <boundary_query BoundaryQuery,
diff --git a/boost/geometry/algorithms/detail/relate/linear_areal.hpp b/boost/geometry/algorithms/detail/relate/linear_areal.hpp
index ddbd7d615a..81fc9e5b3b 100644
--- a/boost/geometry/algorithms/detail/relate/linear_areal.hpp
+++ b/boost/geometry/algorithms/detail/relate/linear_areal.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014, 2015, 2017.
-// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018.
+// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -262,13 +262,22 @@ struct linear_areal
typedef typename IntersectionStrategy::template point_in_geometry_strategy<Geometry1, Geometry2>::type within_strategy_type;
within_strategy_type const within_strategy = intersection_strategy.template get_point_in_geometry_strategy<Geometry1, Geometry2>();
- boundary_checker<Geometry1> boundary_checker1(geometry1);
+
+ typedef typename within_strategy_type::equals_point_point_strategy_type eq_pp_strategy_type;
+
+ typedef boundary_checker
+ <
+ Geometry1,
+ eq_pp_strategy_type
+ > boundary_checker1_type;
+ boundary_checker1_type boundary_checker1(geometry1);
+
no_turns_la_linestring_pred
<
Geometry2,
Result,
within_strategy_type,
- boundary_checker<Geometry1>,
+ boundary_checker1_type,
TransposeResult
> pred1(geometry2,
result,
@@ -393,12 +402,14 @@ struct linear_areal
typedef turns::less<1, turns::less_op_areal_linear<1> > less;
std::sort(it, next, less());
+ eq_pp_strategy_type const eq_pp_strategy = within_strategy.get_equals_point_point_strategy();
+
// analyse
areal_boundary_analyser<turn_type> analyser;
for ( turn_iterator rit = it ; rit != next ; ++rit )
{
// if the analyser requests, break the search
- if ( !analyser.apply(it, rit, next) )
+ if ( !analyser.apply(it, rit, next, eq_pp_strategy) )
break;
}
@@ -621,6 +632,37 @@ struct linear_areal
static const std::size_t op_id = 0;
static const std::size_t other_op_id = 1;
+ template <typename TurnPointCSTag, typename PointP, typename PointQ,
+ typename SideStrategy,
+ typename Pi = PointP, typename Pj = PointP, typename Pk = PointP,
+ typename Qi = PointQ, typename Qj = PointQ, typename Qk = PointQ
+ >
+ struct la_side_calculator
+ {
+ inline la_side_calculator(Pi const& pi, Pj const& pj, Pk const& pk,
+ Qi const& qi, Qj const& qj, Qk const& qk,
+ SideStrategy const& side_strategy)
+ : m_pi(pi), m_pj(pj), m_pk(pk)
+ , m_qi(qi), m_qj(qj), m_qk(qk)
+ , m_side_strategy(side_strategy)
+ {}
+
+ inline int pk_wrt_p1() const { return m_side_strategy.apply(m_pi, m_pj, m_pk); }
+ inline int qk_wrt_p1() const { return m_side_strategy.apply(m_pi, m_pj, m_qk); }
+ inline int pk_wrt_q2() const { return m_side_strategy.apply(m_qj, m_qk, m_pk); }
+
+ private :
+ Pi const& m_pi;
+ Pj const& m_pj;
+ Pk const& m_pk;
+ Qi const& m_qi;
+ Qj const& m_qj;
+ Qk const& m_qk;
+
+ SideStrategy m_side_strategy;
+ };
+
+
public:
turns_analyser()
: m_previous_turn_ptr(NULL)
@@ -670,7 +712,8 @@ struct linear_areal
{
// real exit point - may be multiple
// we know that we entered and now we exit
- if ( ! turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(), *it) )
+ if ( ! turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(), *it,
+ side_strategy.get_equals_point_point_strategy()) )
{
m_exit_watcher.reset_detected_exit();
@@ -712,7 +755,8 @@ struct linear_areal
if ( ( op == overlay::operation_intersection
|| op == overlay::operation_continue )
- && turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(), *it) )
+ && turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(), *it,
+ side_strategy.get_equals_point_point_strategy()) )
{
fake_enter_detected = true;
}
@@ -732,7 +776,8 @@ struct linear_areal
&& ( op != overlay::operation_blocked // operation different than block
|| seg_id.multi_index != m_previous_turn_ptr->operations[op_id].seg_id.multi_index ) ) // or the next single-geometry
|| ( m_previous_operation == overlay::operation_union
- && ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it) )
+ && ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it,
+ side_strategy.get_equals_point_point_strategy()) )
)
{
update<interior, exterior, '1', TransposeResult>(res);
@@ -764,7 +809,8 @@ struct linear_areal
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) )
+ if ( ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it,
+ side_strategy.get_equals_point_point_strategy()) )
{
update<interior, interior, '1', TransposeResult>(res);
m_interior_detected = false;
@@ -1203,7 +1249,7 @@ struct linear_areal
point2_type const& qj = range::at(range2, q_seg_ij + 1);
point1_type qi_conv;
geometry::convert(qi, qi_conv);
- bool const is_ip_qj = equals::equals_point_point(turn.point, qj);
+ bool const is_ip_qj = equals::equals_point_point(turn.point, qj, side_strategy.get_equals_point_point_strategy());
// TODO: test this!
// BOOST_GEOMETRY_ASSERT(!equals::equals_point_point(turn.point, pi));
// BOOST_GEOMETRY_ASSERT(!equals::equals_point_point(turn.point, qi));
@@ -1217,10 +1263,11 @@ struct linear_areal
// It would be good to replace it with some O(1) mechanism
range2_iterator qk_it = find_next_non_duplicated(boost::begin(range2),
range::pos(range2, q_seg_jk),
- boost::end(range2));
+ boost::end(range2),
+ side_strategy.get_equals_point_point_strategy());
// Will this sequence of points be always correct?
- overlay::side_calculator<cs_tag, point1_type, point2_type, SideStrategy>
+ la_side_calculator<cs_tag, point1_type, point2_type, SideStrategy>
side_calc(qi_conv, new_pj, pi, qi, qj, *qk_it, side_strategy);
return calculate_from_inside_sides(side_calc);
@@ -1230,15 +1277,16 @@ struct linear_areal
point2_type new_qj;
geometry::convert(turn.point, new_qj);
- overlay::side_calculator<cs_tag, point1_type, point2_type, SideStrategy>
+ la_side_calculator<cs_tag, point1_type, point2_type, SideStrategy>
side_calc(qi_conv, new_pj, pi, qi, new_qj, qj, side_strategy);
return calculate_from_inside_sides(side_calc);
}
}
- template <typename It>
- static inline It find_next_non_duplicated(It first, It current, It last)
+ template <typename It, typename EqPPStrategy>
+ static inline It find_next_non_duplicated(It first, It current, It last,
+ EqPPStrategy const& strategy)
{
BOOST_GEOMETRY_ASSERT( current != last );
@@ -1246,14 +1294,14 @@ struct linear_areal
for ( ++it ; it != last ; ++it )
{
- if ( !equals::equals_point_point(*current, *it) )
+ if ( !equals::equals_point_point(*current, *it, strategy) )
return it;
}
// if not found start from the beginning
for ( it = first ; it != current ; ++it )
{
- if ( !equals::equals_point_point(*current, *it) )
+ if ( !equals::equals_point_point(*current, *it, strategy) )
return it;
}
@@ -1396,8 +1444,9 @@ struct linear_areal
, m_previous_turn_ptr(NULL)
{}
- template <typename TurnIt>
- bool apply(TurnIt /*first*/, TurnIt it, TurnIt last)
+ template <typename TurnIt, typename EqPPStrategy>
+ bool apply(TurnIt /*first*/, TurnIt it, TurnIt last,
+ EqPPStrategy const& strategy)
{
overlay::operation_type op = it->operations[1].operation;
@@ -1412,7 +1461,7 @@ struct linear_areal
if ( is_union_detected )
{
BOOST_GEOMETRY_ASSERT(m_previous_turn_ptr != NULL);
- if ( !detail::equals::equals_point_point(it->point, m_previous_turn_ptr->point) )
+ if ( !detail::equals::equals_point_point(it->point, m_previous_turn_ptr->point, strategy) )
{
// break
return false;
diff --git a/boost/geometry/algorithms/detail/relate/linear_linear.hpp b/boost/geometry/algorithms/detail/relate/linear_linear.hpp
index 520f2bd775..6c5d82fdea 100644
--- a/boost/geometry/algorithms/detail/relate/linear_linear.hpp
+++ b/boost/geometry/algorithms/detail/relate/linear_linear.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014, 2015, 2017.
-// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018.
+// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -42,6 +42,8 @@ namespace detail { namespace relate {
template <typename Result, typename BoundaryChecker, bool TransposeResult>
class disjoint_linestring_pred
{
+ typedef typename BoundaryChecker::equals_strategy_type equals_strategy_type;
+
public:
disjoint_linestring_pred(Result & res,
BoundaryChecker const& boundary_checker)
@@ -80,7 +82,8 @@ public:
// point-like linestring
if ( count == 2
&& equals::equals_point_point(range::front(linestring),
- range::back(linestring)) )
+ range::back(linestring),
+ equals_strategy_type()) )
{
update<interior, exterior, '0', TransposeResult>(m_result);
}
@@ -145,14 +148,24 @@ struct linear_linear
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
- boundary_checker<Geometry1> boundary_checker1(geometry1);
- disjoint_linestring_pred<Result, boundary_checker<Geometry1>, false> pred1(result, boundary_checker1);
+ typedef boundary_checker
+ <
+ Geometry1,
+ typename IntersectionStrategy::point_in_point_strategy_type
+ > boundary_checker1_type;
+ boundary_checker1_type boundary_checker1(geometry1);
+ disjoint_linestring_pred<Result, boundary_checker1_type, false> pred1(result, boundary_checker1);
for_each_disjoint_geometry_if<0, Geometry1>::apply(turns.begin(), turns.end(), geometry1, pred1);
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
- boundary_checker<Geometry2> boundary_checker2(geometry2);
- disjoint_linestring_pred<Result, boundary_checker<Geometry2>, true> pred2(result, boundary_checker2);
+ typedef boundary_checker
+ <
+ Geometry2,
+ typename IntersectionStrategy::point_in_point_strategy_type
+ > boundary_checker2_type;
+ boundary_checker2_type boundary_checker2(geometry2);
+ disjoint_linestring_pred<Result, boundary_checker2_type, true> pred2(result, boundary_checker2);
for_each_disjoint_geometry_if<1, Geometry2>::apply(turns.begin(), turns.end(), geometry2, pred2);
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
@@ -274,6 +287,8 @@ struct linear_linear
BoundaryChecker const& boundary_checker,
OtherBoundaryChecker const& other_boundary_checker)
{
+ typedef typename BoundaryChecker::equals_strategy_type equals_strategy_type;
+
overlay::operation_type const op = it->operations[op_id].operation;
segment_identifier const& seg_id = it->operations[op_id].seg_id;
@@ -323,7 +338,9 @@ struct linear_linear
{
// real exit point - may be multiple
// we know that we entered and now we exit
- if ( ! turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(), *it) )
+ if ( ! turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(),
+ *it,
+ equals_strategy_type()) )
{
m_exit_watcher.reset_detected_exit();
@@ -344,7 +361,9 @@ struct linear_linear
return;
if ( op == overlay::operation_intersection
- && turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(), *it) )
+ && turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(),
+ *it,
+ equals_strategy_type()) )
{
fake_enter_detected = true;
}
@@ -647,6 +666,11 @@ struct linear_linear
OtherBoundaryChecker const& /*other_boundary_checker*/,
bool first_in_range)
{
+ typedef typename BoundaryChecker::equals_strategy_type
+ equals_strategy1_type;
+ typedef typename OtherBoundaryChecker::equals_strategy_type
+ equals_strategy2_type;
+
typename detail::single_geometry_return_type<Geometry const>::type
ls1_ref = detail::single_geometry(geometry, turn.operations[op_id].seg_id);
typename detail::single_geometry_return_type<OtherGeometry const>::type
@@ -714,9 +738,13 @@ struct linear_linear
// here we don't know which one is degenerated
bool const is_point1 = boost::size(ls1_ref) == 2
- && equals::equals_point_point(range::front(ls1_ref), range::back(ls1_ref));
+ && equals::equals_point_point(range::front(ls1_ref),
+ range::back(ls1_ref),
+ equals_strategy1_type());
bool const is_point2 = boost::size(ls2_ref) == 2
- && equals::equals_point_point(range::front(ls2_ref), range::back(ls2_ref));
+ && equals::equals_point_point(range::front(ls2_ref),
+ range::back(ls2_ref),
+ equals_strategy2_type());
// if the second one is degenerated
if ( !is_point1 && is_point2 )
diff --git a/boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp b/boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp
index 8d5f21555c..8dec5ccdaf 100644
--- a/boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp
+++ b/boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry
-// Copyright (c) 2017 Oracle and/or its affiliates.
+// Copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -17,6 +17,7 @@
#include <boost/geometry/algorithms/detail/disjoint/box_box.hpp>
#include <boost/geometry/algorithms/detail/disjoint/point_box.hpp>
#include <boost/geometry/algorithms/detail/expand_by_epsilon.hpp>
+#include <boost/geometry/algorithms/detail/partition.hpp>
#include <boost/geometry/algorithms/detail/relate/result.hpp>
#include <boost/geometry/algorithms/detail/relate/topology_check.hpp>
#include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
@@ -40,20 +41,21 @@ namespace detail { namespace relate
template
<
typename Geometry,
+ typename EqPPStrategy,
typename Tag = typename tag<Geometry>::type
>
struct multi_point_geometry_eb
{
template <typename MultiPoint>
static inline bool apply(MultiPoint const& ,
- detail::relate::topology_check<Geometry> const& )
+ detail::relate::topology_check<Geometry, EqPPStrategy> const& )
{
return true;
}
};
-template <typename Geometry>
-struct multi_point_geometry_eb<Geometry, linestring_tag>
+template <typename Geometry, typename EqPPStrategy>
+struct multi_point_geometry_eb<Geometry, EqPPStrategy, linestring_tag>
{
template <typename Points>
struct boundary_visitor
@@ -73,7 +75,7 @@ struct multi_point_geometry_eb<Geometry, linestring_tag>
template <typename Pt>
bool operator()(Pt const& pt) const
{
- return detail::equals::equals_point_point(pt, m_point);
+ return detail::equals::equals_point_point(pt, m_point, EqPPStrategy());
}
Point const& m_point;
@@ -99,7 +101,7 @@ struct multi_point_geometry_eb<Geometry, linestring_tag>
template <typename MultiPoint>
static inline bool apply(MultiPoint const& multi_point,
- detail::relate::topology_check<Geometry> const& tc)
+ detail::relate::topology_check<Geometry, EqPPStrategy> const& tc)
{
boundary_visitor<MultiPoint> visitor(multi_point);
tc.for_each_boundary_point(visitor);
@@ -107,9 +109,12 @@ struct multi_point_geometry_eb<Geometry, linestring_tag>
}
};
-template <typename Geometry>
-struct multi_point_geometry_eb<Geometry, multi_linestring_tag>
+template <typename Geometry, typename EqPPStrategy>
+struct multi_point_geometry_eb<Geometry, EqPPStrategy, multi_linestring_tag>
{
+ // TODO: CS-specific less compare strategy derived from EqPPStrategy
+ typedef geometry::less<> less_type;
+
template <typename Points>
struct boundary_visitor
{
@@ -121,7 +126,7 @@ struct multi_point_geometry_eb<Geometry, multi_linestring_tag>
template <typename Point>
bool apply(Point const& boundary_point)
{
- if (! std::binary_search(m_points.begin(), m_points.end(), boundary_point, geometry::less<>()))
+ if (! std::binary_search(m_points.begin(), m_points.end(), boundary_point, less_type()))
{
m_boundary_found = true;
return false;
@@ -138,12 +143,12 @@ struct multi_point_geometry_eb<Geometry, multi_linestring_tag>
template <typename MultiPoint>
static inline bool apply(MultiPoint const& multi_point,
- detail::relate::topology_check<Geometry> const& tc)
+ detail::relate::topology_check<Geometry, EqPPStrategy> const& tc)
{
typedef typename boost::range_value<MultiPoint>::type point_type;
typedef std::vector<point_type> points_type;
points_type points(boost::begin(multi_point), boost::end(multi_point));
- std::sort(points.begin(), points.end(), geometry::less<>());
+ std::sort(points.begin(), points.end(), less_type());
boundary_visitor<points_type> visitor(points);
tc.for_each_boundary_point(visitor);
@@ -165,6 +170,8 @@ struct multi_point_single_geometry
{
typedef typename point_type<SingleGeometry>::type point2_type;
typedef model::box<point2_type> box2_type;
+ typedef typename Strategy::equals_point_point_strategy_type eq_pp_strategy_type;
+ typedef typename Strategy::disjoint_point_box_strategy_type d_pb_strategy_type;
box2_type box2;
geometry::envelope(single_geometry, box2, strategy.get_envelope_strategy());
@@ -181,7 +188,7 @@ struct multi_point_single_geometry
}
// The default strategy is enough for Point/Box
- if (detail::disjoint::disjoint_point_box(*it, box2))
+ if (detail::disjoint::disjoint_point_box(*it, box2, d_pb_strategy_type()))
{
relate::set<interior, exterior, '0', Transpose>(result);
}
@@ -209,7 +216,10 @@ struct multi_point_single_geometry
}
}
- typedef detail::relate::topology_check<SingleGeometry> tc_t;
+ typedef detail::relate::topology_check
+ <
+ SingleGeometry, eq_pp_strategy_type
+ > tc_t;
if ( relate::may_update<exterior, interior, tc_t::interior, Transpose>(result)
|| relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result) )
{
@@ -226,8 +236,13 @@ struct multi_point_single_geometry
if ( relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result)
&& tc.has_boundary() )
{
- if (multi_point_geometry_eb<SingleGeometry>::apply(multi_point, tc))
+ if (multi_point_geometry_eb
+ <
+ SingleGeometry, eq_pp_strategy_type
+ >::apply(multi_point, tc))
+ {
relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
+ }
}
}
@@ -260,32 +275,40 @@ class multi_point_multi_geometry_ii_ib
}
};
+ template <typename DisjointPointBoxStrategy>
struct overlaps_box_point
{
template <typename Box, typename Point>
static inline bool apply(Box const& box, Point const& point)
{
// The default strategy is enough for Point/Box
- return ! detail::disjoint::disjoint_point_box(point, box);
+ return ! detail::disjoint::disjoint_point_box(point, box,
+ DisjointPointBoxStrategy());
}
};
+ template <typename DisjointBoxBoxStrategy>
struct overlaps_box_box_pair
{
template <typename Box, typename BoxPair>
static inline bool apply(Box const& box, BoxPair const& box_pair)
{
// The default strategy is enough for Box/Box
- return ! detail::disjoint::disjoint_box_box(box_pair.first, box);
+ return ! detail::disjoint::disjoint_box_box(box_pair.first, box,
+ DisjointBoxBoxStrategy());
}
};
template <typename Result, typename PtSegStrategy>
class item_visitor_type
{
+ typedef typename PtSegStrategy::equals_point_point_strategy_type pp_strategy_type;
+ typedef typename PtSegStrategy::disjoint_point_box_strategy_type d_pp_strategy_type;
+ typedef detail::relate::topology_check<MultiGeometry, pp_strategy_type> topology_check_type;
+
public:
item_visitor_type(MultiGeometry const& multi_geometry,
- detail::relate::topology_check<MultiGeometry> const& tc,
+ topology_check_type const& tc,
Result & result,
PtSegStrategy const& strategy)
: m_multi_geometry(multi_geometry)
@@ -298,7 +321,7 @@ class multi_point_multi_geometry_ii_ib
inline bool apply(Point const& point, BoxPair const& box_pair)
{
// The default strategy is enough for Point/Box
- if (! detail::disjoint::disjoint_point_box(point, box_pair.first))
+ if (! detail::disjoint::disjoint_point_box(point, box_pair.first, d_pp_strategy_type()))
{
typename boost::range_value<MultiGeometry>::type const&
single = range::at(m_multi_geometry, box_pair.second);
@@ -335,7 +358,7 @@ class multi_point_multi_geometry_ii_ib
private:
MultiGeometry const& m_multi_geometry;
- detail::relate::topology_check<MultiGeometry> const& m_tc;
+ topology_check_type const& m_tc;
Result & m_result;
PtSegStrategy const& m_strategy;
};
@@ -351,20 +374,33 @@ public:
static inline void apply(MultiPoint const& multi_point,
MultiGeometry const& multi_geometry,
std::vector<box_pair_type> const& boxes,
- detail::relate::topology_check<MultiGeometry> const& tc,
+ detail::relate::topology_check
+ <
+ MultiGeometry,
+ typename Strategy::equals_point_point_strategy_type
+ > const& tc,
Result & result,
Strategy const& strategy)
{
item_visitor_type<Result, Strategy> visitor(multi_geometry, tc, result, strategy);
+ typedef overlaps_box_point
+ <
+ typename Strategy::disjoint_point_box_strategy_type
+ > overlaps_box_point_type;
+ typedef overlaps_box_box_pair
+ <
+ typename Strategy::disjoint_box_box_strategy_type
+ > overlaps_box_box_pair_type;
+
geometry::partition
<
box1_type
>::apply(multi_point, boxes, visitor,
expand_box_point(),
- overlaps_box_point(),
+ overlaps_box_point_type(),
expand_box_box_pair(),
- overlaps_box_box_pair());
+ overlaps_box_box_pair_type());
}
};
@@ -387,7 +423,11 @@ struct multi_point_multi_geometry_ii_ib_ie
static inline void apply(MultiPoint const& multi_point,
MultiGeometry const& multi_geometry,
std::vector<box_pair_type> const& boxes,
- detail::relate::topology_check<MultiGeometry> const& tc,
+ detail::relate::topology_check
+ <
+ MultiGeometry,
+ typename Strategy::equals_point_point_strategy_type
+ > const& tc,
Result & result,
Strategy const& strategy)
{
@@ -461,6 +501,8 @@ struct multi_point_multi_geometry
typedef model::box<point2_type> box2_type;
typedef std::pair<box2_type, std::size_t> box_pair_type;
+ typedef typename Strategy::equals_point_point_strategy_type eq_pp_strategy_type;
+
typename Strategy::envelope_strategy_type const
envelope_strategy = strategy.get_envelope_strategy();
@@ -473,7 +515,7 @@ struct multi_point_multi_geometry
boxes[i].second = i;
}
- typedef detail::relate::topology_check<MultiGeometry> tc_t;
+ typedef detail::relate::topology_check<MultiGeometry, eq_pp_strategy_type> tc_t;
tc_t tc(multi_geometry);
if ( relate::may_update<interior, interior, '0', Transpose>(result)
@@ -512,8 +554,13 @@ struct multi_point_multi_geometry
if ( relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result)
&& tc.has_boundary() )
{
- if (multi_point_geometry_eb<MultiGeometry>::apply(multi_point, tc))
+ if (multi_point_geometry_eb
+ <
+ MultiGeometry, eq_pp_strategy_type
+ >::apply(multi_point, tc))
+ {
relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
+ }
}
}
diff --git a/boost/geometry/algorithms/detail/relate/point_geometry.hpp b/boost/geometry/algorithms/detail/relate/point_geometry.hpp
index e78a404b21..7b1726abeb 100644
--- a/boost/geometry/algorithms/detail/relate/point_geometry.hpp
+++ b/boost/geometry/algorithms/detail/relate/point_geometry.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014, 2015, 2017.
-// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018.
+// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -60,7 +60,11 @@ struct point_geometry
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
- typedef detail::relate::topology_check<Geometry> tc_t;
+ typedef detail::relate::topology_check
+ <
+ Geometry,
+ typename Strategy::equals_point_point_strategy_type
+ > tc_t;
if ( relate::may_update<exterior, interior, tc_t::interior, Transpose>(result)
|| relate::may_update<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 e0bed72ba3..d2a373f3c1 100644
--- a/boost/geometry/algorithms/detail/relate/point_point.hpp
+++ b/boost/geometry/algorithms/detail/relate/point_point.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014, 2017.
-// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2017, 2018.
+// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -39,9 +39,9 @@ struct point_point
template <typename Result, typename Strategy>
static inline void apply(Point1 const& point1, Point2 const& point2,
Result & result,
- Strategy const& /*strategy*/)
+ Strategy const& strategy)
{
- bool equal = detail::equals::equals_point_point(point1, point2);
+ bool equal = detail::equals::equals_point_point(point1, point2, strategy);
if ( equal )
{
relate::set<interior, interior, '0'>(result);
@@ -56,8 +56,10 @@ struct point_point
}
};
-template <typename Point, typename MultiPoint>
-std::pair<bool, bool> point_multipoint_check(Point const& point, MultiPoint const& multi_point)
+template <typename Point, typename MultiPoint, typename EqPPStrategy>
+std::pair<bool, bool> point_multipoint_check(Point const& point,
+ MultiPoint const& multi_point,
+ EqPPStrategy const& strategy)
{
bool found_inside = false;
bool found_outside = false;
@@ -70,7 +72,7 @@ std::pair<bool, bool> point_multipoint_check(Point const& point, MultiPoint cons
iterator last = boost::end(multi_point);
for ( ; it != last ; ++it )
{
- bool ii = detail::equals::equals_point_point(point, *it);
+ bool ii = detail::equals::equals_point_point(point, *it, strategy);
if ( ii )
found_inside = true;
@@ -92,7 +94,7 @@ struct point_multipoint
template <typename Result, typename Strategy>
static inline void apply(Point const& point, MultiPoint const& multi_point,
Result & result,
- Strategy const& /*strategy*/)
+ Strategy const& strategy)
{
if ( boost::empty(multi_point) )
{
@@ -101,7 +103,7 @@ struct point_multipoint
return;
}
- std::pair<bool, bool> rel = point_multipoint_check(point, multi_point);
+ std::pair<bool, bool> rel = point_multipoint_check(point, multi_point, strategy);
if ( rel.first ) // some point of MP is equal to P
{
diff --git a/boost/geometry/algorithms/detail/relate/result.hpp b/boost/geometry/algorithms/detail/relate/result.hpp
index 92bc160a6c..43592b9815 100644
--- a/boost/geometry/algorithms/detail/relate/result.hpp
+++ b/boost/geometry/algorithms/detail/relate/result.hpp
@@ -3,8 +3,8 @@
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013-2016.
-// Modifications copyright (c) 2013-2016 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013-2018.
+// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -25,6 +25,7 @@
#include <boost/mpl/end.hpp>
#include <boost/mpl/is_sequence.hpp>
#include <boost/mpl/next.hpp>
+#include <boost/mpl/size.hpp>
#include <boost/static_assert.hpp>
#include <boost/throw_exception.hpp>
#include <boost/tuple/tuple.hpp>
diff --git a/boost/geometry/algorithms/detail/relate/topology_check.hpp b/boost/geometry/algorithms/detail/relate/topology_check.hpp
index 810466ec05..a12acaf42b 100644
--- a/boost/geometry/algorithms/detail/relate/topology_check.hpp
+++ b/boost/geometry/algorithms/detail/relate/topology_check.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014-2017, Oracle and/or its affiliates.
+// Copyright (c) 2014-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -13,6 +13,7 @@
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/policies/compare.hpp>
@@ -28,6 +29,7 @@ namespace detail { namespace relate {
// TODO: change the name for e.g. something with the word "exterior"
template <typename Geometry,
+ typename EqPPStrategy,
typename Tag = typename geometry::tag<Geometry>::type>
struct topology_check
: not_implemented<Tag>
@@ -47,8 +49,8 @@ struct topology_check
// topology_check(Point const&, IgnoreBoundaryPoint const&) {}
//};
-template <typename Linestring>
-struct topology_check<Linestring, linestring_tag>
+template <typename Linestring, typename EqPPStrategy>
+struct topology_check<Linestring, EqPPStrategy, linestring_tag>
{
static const char interior = '1';
static const char boundary = '0';
@@ -100,7 +102,9 @@ private:
m_has_interior = count > 0;
// NOTE: Linestring with all points equal is treated as 1d linear ring
m_has_boundary = count > 1
- && ! detail::equals::equals_point_point(range::front(m_ls), range::back(m_ls));
+ && ! detail::equals::equals_point_point(range::front(m_ls),
+ range::back(m_ls),
+ EqPPStrategy());
m_is_initialized = true;
}
@@ -112,8 +116,8 @@ private:
mutable bool m_has_boundary;
};
-template <typename MultiLinestring>
-struct topology_check<MultiLinestring, multi_linestring_tag>
+template <typename MultiLinestring, typename EqPPStrategy>
+struct topology_check<MultiLinestring, EqPPStrategy, multi_linestring_tag>
{
static const char interior = '1';
static const char boundary = '0';
@@ -159,6 +163,9 @@ struct topology_check<MultiLinestring, multi_linestring_tag>
}
private:
+// TODO: CS-specific less derived from EqPPStrategy
+ typedef geometry::less<> less_type;
+
void init() const
{
if (m_is_initialized)
@@ -192,7 +199,7 @@ private:
point_reference back_pt = range::back(ls);
// don't store boundaries of linear rings, this doesn't change anything
- if (! equals::equals_point_point(front_pt, back_pt))
+ if (! equals::equals_point_point(front_pt, back_pt, EqPPStrategy()))
{
// do not add points containing NaN coordinates
// because they cannot be reasonably compared, e.g. with MSVC
@@ -215,7 +222,7 @@ private:
if (! m_endpoints.empty() )
{
- std::sort(m_endpoints.begin(), m_endpoints.end(), geometry::less<>());
+ std::sort(m_endpoints.begin(), m_endpoints.end(), less_type());
m_has_boundary = find_odd_count(m_endpoints.begin(), m_endpoints.end());
}
@@ -225,7 +232,7 @@ private:
template <typename It, typename Point>
static inline std::size_t count_equal(It first, It last, Point const& point)
{
- std::pair<It, It> rng = std::equal_range(first, last, point, geometry::less<>());
+ std::pair<It, It> rng = std::equal_range(first, last, point, less_type());
return (std::size_t)std::distance(rng.first, rng.second);
}
@@ -261,7 +268,7 @@ private:
for ( ; first != last ; ++first, ++prev )
{
// the end of the equal points subrange
- if ( ! equals::equals_point_point(*first, *prev) )
+ if ( ! equals::equals_point_point(*first, *prev, EqPPStrategy()) )
{
// odd count -> boundary
if ( count % 2 != 0 )
@@ -298,40 +305,35 @@ private:
mutable std::vector<point_type> m_endpoints;
};
-template <typename Ring>
-struct topology_check<Ring, ring_tag>
+struct topology_check_areal
{
static const char interior = '2';
static const char boundary = '1';
- topology_check(Ring const&) {}
-
static bool has_interior() { return true; }
static bool has_boundary() { return true; }
};
-template <typename Polygon>
-struct topology_check<Polygon, polygon_tag>
+template <typename Ring, typename EqPPStrategy>
+struct topology_check<Ring, EqPPStrategy, ring_tag>
+ : topology_check_areal
{
- static const char interior = '2';
- static const char boundary = '1';
-
- topology_check(Polygon const&) {}
+ topology_check(Ring const&) {}
+};
- static bool has_interior() { return true; }
- static bool has_boundary() { return true; }
+template <typename Polygon, typename EqPPStrategy>
+struct topology_check<Polygon, EqPPStrategy, polygon_tag>
+ : topology_check_areal
+{
+ topology_check(Polygon const&) {}
};
-template <typename MultiPolygon>
-struct topology_check<MultiPolygon, multi_polygon_tag>
+template <typename MultiPolygon, typename EqPPStrategy>
+struct topology_check<MultiPolygon, EqPPStrategy, multi_polygon_tag>
+ : topology_check_areal
{
- static const char interior = '2';
- static const char boundary = '1';
-
topology_check(MultiPolygon const&) {}
-
- static bool has_interior() { return true; }
- static bool has_boundary() { return true; }
+
template <typename Point>
static bool check_boundary_point(Point const& ) { return true; }
};
diff --git a/boost/geometry/algorithms/detail/relate/turns.hpp b/boost/geometry/algorithms/detail/relate/turns.hpp
index 6fa05eaf21..01c4304fa4 100644
--- a/boost/geometry/algorithms/detail/relate/turns.hpp
+++ b/boost/geometry/algorithms/detail/relate/turns.hpp
@@ -48,7 +48,11 @@ template
<
Geometry1, Geometry2, assign_policy<>
>,
- typename RobustPolicy = detail::no_rescale_policy
+ typename RobustPolicy = typename geometry::rescale_overlay_policy_type
+ <
+ Geometry1,
+ Geometry2
+ >::type
>
struct get_turns
{
diff --git a/boost/geometry/algorithms/detail/sections/section_box_policies.hpp b/boost/geometry/algorithms/detail/sections/section_box_policies.hpp
index cf06700306..e6342ff709 100644
--- a/boost/geometry/algorithms/detail/sections/section_box_policies.hpp
+++ b/boost/geometry/algorithms/detail/sections/section_box_policies.hpp
@@ -2,6 +2,10 @@
// Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018, 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)
@@ -21,21 +25,25 @@ namespace boost { namespace geometry
namespace detail { namespace section
{
+template <typename ExpandBoxStrategy>
struct get_section_box
{
template <typename Box, typename Section>
static inline void apply(Box& total, Section const& section)
{
- geometry::expand(total, section.bounding_box);
+ geometry::expand(total, section.bounding_box,
+ ExpandBoxStrategy());
}
};
+template <typename DisjointBoxBoxStrategy>
struct overlaps_section_box
{
template <typename Box, typename Section>
static inline bool apply(Box const& box, Section const& section)
{
- return ! detail::disjoint::disjoint_box_box(box, section.bounding_box);
+ return ! detail::disjoint::disjoint_box_box(box, section.bounding_box,
+ DisjointBoxBoxStrategy());
}
};
diff --git a/boost/geometry/algorithms/detail/sections/section_functions.hpp b/boost/geometry/algorithms/detail/sections/section_functions.hpp
index d283784e2c..bd72ff48a0 100644
--- a/boost/geometry/algorithms/detail/sections/section_functions.hpp
+++ b/boost/geometry/algorithms/detail/sections/section_functions.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2015, 2017.
-// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2017, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -22,6 +22,8 @@
// For spherical/geographic longitudes covered_by point/box
#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
+#include <boost/geometry/util/select_coordinate_type.hpp>
+
namespace boost { namespace geometry
{
@@ -30,6 +32,8 @@ namespace boost { namespace geometry
namespace detail { namespace section
{
+// TODO: This code is CS-specific, should be moved to strategies
+
template
<
std::size_t Dimension,
@@ -68,7 +72,7 @@ struct preceding_check<0, Geometry, spherical_tag>
calc_t const other_min = get<min_corner, 0>(other_box);
calc_t const other_max = get<max_corner, 0>(other_box);
- bool const pt_covered = strategy::within::covered_by_range
+ bool const pt_covered = strategy::within::detail::covered_by_range
<
Point, 0, spherical_tag
>::apply(value,
diff --git a/boost/geometry/algorithms/detail/sections/sectionalize.hpp b/boost/geometry/algorithms/detail/sections/sectionalize.hpp
index 7a8638f5c8..6ece756cd4 100644
--- a/boost/geometry/algorithms/detail/sections/sectionalize.hpp
+++ b/boost/geometry/algorithms/detail/sections/sectionalize.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013, 2014, 2015, 2017.
-// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018.
+// Modifications copyright (c) 2013-2018 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
@@ -58,6 +58,7 @@
#include <boost/geometry/algorithms/detail/expand_by_epsilon.hpp>
#include <boost/geometry/strategies/envelope.hpp>
+#include <boost/geometry/strategies/expand.hpp>
namespace boost { namespace geometry
{
@@ -330,9 +331,9 @@ struct assign_loop<T, Count, Count>
template <typename CSTag>
struct box_first_in_section
{
- template <typename Box, typename Point, typename Strategy>
+ template <typename Box, typename Point, typename EnvelopeStrategy>
static inline void apply(Box & box, Point const& prev, Point const& curr,
- Strategy const& strategy)
+ EnvelopeStrategy const& strategy)
{
geometry::model::referring_segment<Point const> seg(prev, curr);
geometry::envelope(seg, box, strategy);
@@ -342,9 +343,9 @@ struct box_first_in_section
template <>
struct box_first_in_section<cartesian_tag>
{
- template <typename Box, typename Point, typename Strategy>
+ template <typename Box, typename Point, typename ExpandStrategy>
static inline void apply(Box & box, Point const& prev, Point const& curr,
- Strategy const& )
+ ExpandStrategy const& )
{
geometry::envelope(prev, box);
geometry::expand(box, curr);
@@ -399,11 +400,20 @@ struct sectionalize_part
{
typedef typename strategy::envelope::services::default_strategy
<
+ segment_tag,
typename cs_tag<typename Sections::box_type>::type
>::type envelope_strategy_type;
+ typedef typename strategy::expand::services::default_strategy
+ <
+ segment_tag,
+ typename cs_tag<typename Sections::box_type>::type
+ >::type expand_strategy_type;
+
apply(sections, begin, end,
- robust_policy, envelope_strategy_type(),
+ robust_policy,
+ envelope_strategy_type(),
+ expand_strategy_type(),
ring_id, max_count);
}
@@ -412,12 +422,14 @@ struct sectionalize_part
typename Iterator,
typename RobustPolicy,
typename Sections,
- typename EnvelopeStrategy
+ typename EnvelopeStrategy,
+ typename ExpandStrategy
>
static inline void apply(Sections& sections,
Iterator begin, Iterator end,
RobustPolicy const& robust_policy,
- EnvelopeStrategy const& strategy,
+ EnvelopeStrategy const& envelope_strategy,
+ ExpandStrategy const& expand_strategy,
ring_identifier ring_id,
std::size_t max_count)
{
@@ -535,14 +547,14 @@ struct sectionalize_part
// In cartesian this is envelope of previous point expanded with current point
// in non-cartesian this is envelope of a segment
box_first_in_section<typename cs_tag<robust_point_type>::type>
- ::apply(section.bounding_box, previous_robust_point, current_robust_point, strategy);
+ ::apply(section.bounding_box, previous_robust_point, current_robust_point, envelope_strategy);
}
else
{
// In cartesian this is expand with current point
// in non-cartesian this is expand with a segment
box_next_in_section<typename cs_tag<robust_point_type>::type>
- ::apply(section.bounding_box, previous_robust_point, current_robust_point, strategy);
+ ::apply(section.bounding_box, previous_robust_point, current_robust_point, expand_strategy);
}
section.end_index = index + 1;
@@ -588,12 +600,14 @@ struct sectionalize_range
typename Range,
typename RobustPolicy,
typename Sections,
- typename EnvelopeStrategy
+ typename EnvelopeStrategy,
+ typename ExpandStrategy
>
static inline void apply(Range const& range,
RobustPolicy const& robust_policy,
Sections& sections,
- EnvelopeStrategy const& strategy,
+ EnvelopeStrategy const& envelope_strategy,
+ ExpandStrategy const& expand_strategy,
ring_identifier ring_id,
std::size_t max_count)
{
@@ -622,7 +636,8 @@ struct sectionalize_range
sectionalize_part<Point, DimensionVector>::apply(sections,
boost::begin(view), boost::end(view),
- robust_policy, strategy, ring_id, max_count);
+ robust_policy, envelope_strategy, expand_strategy,
+ ring_id, max_count);
}
};
@@ -638,12 +653,14 @@ struct sectionalize_polygon
typename Polygon,
typename RobustPolicy,
typename Sections,
- typename EnvelopeStrategy
+ typename EnvelopeStrategy,
+ typename ExpandStrategy
>
static inline void apply(Polygon const& poly,
RobustPolicy const& robust_policy,
Sections& sections,
- EnvelopeStrategy const& strategy,
+ EnvelopeStrategy const& envelope_strategy,
+ ExpandStrategy const& expand_strategy,
ring_identifier ring_id,
std::size_t max_count)
{
@@ -655,7 +672,8 @@ struct sectionalize_polygon
> per_range;
ring_id.ring_index = -1;
- per_range::apply(exterior_ring(poly), robust_policy, sections, strategy, ring_id, max_count);
+ per_range::apply(exterior_ring(poly), robust_policy, sections,
+ envelope_strategy, expand_strategy, ring_id, max_count);
ring_id.ring_index++;
typename interior_return_type<Polygon const>::type
@@ -663,7 +681,8 @@ struct sectionalize_polygon
for (typename detail::interior_iterator<Polygon const>::type
it = boost::begin(rings); it != boost::end(rings); ++it, ++ring_id.ring_index)
{
- per_range::apply(*it, robust_policy, sections, strategy, ring_id, max_count);
+ per_range::apply(*it, robust_policy, sections,
+ envelope_strategy, expand_strategy, ring_id, max_count);
}
}
};
@@ -676,12 +695,14 @@ struct sectionalize_box
typename Box,
typename RobustPolicy,
typename Sections,
- typename EnvelopeStrategy
+ typename EnvelopeStrategy,
+ typename ExpandStrategy
>
static inline void apply(Box const& box,
RobustPolicy const& robust_policy,
Sections& sections,
- EnvelopeStrategy const& ,
+ EnvelopeStrategy const& envelope_strategy,
+ ExpandStrategy const& expand_strategy,
ring_identifier const& ring_id, std::size_t max_count)
{
typedef typename point_type<Box>::type point_type;
@@ -714,7 +735,7 @@ struct sectionalize_box
point_type,
DimensionVector
>::apply(points, robust_policy, sections,
- strategy::envelope::cartesian_segment<>(),
+ envelope_strategy, expand_strategy,
ring_id, max_count);
}
};
@@ -727,12 +748,14 @@ struct sectionalize_multi
typename MultiGeometry,
typename RobustPolicy,
typename Sections,
- typename EnvelopeStrategy
+ typename EnvelopeStrategy,
+ typename ExpandStrategy
>
static inline void apply(MultiGeometry const& multi,
RobustPolicy const& robust_policy,
Sections& sections,
- EnvelopeStrategy const& strategy,
+ EnvelopeStrategy const& envelope_strategy,
+ ExpandStrategy const& expand_strategy,
ring_identifier ring_id,
std::size_t max_count)
{
@@ -742,7 +765,9 @@ struct sectionalize_multi
it != boost::end(multi);
++it, ++ring_id.multi_index)
{
- Policy::apply(*it, robust_policy, sections, strategy, ring_id, max_count);
+ Policy::apply(*it, robust_policy, sections,
+ envelope_strategy, expand_strategy,
+ ring_id, max_count);
}
}
};
@@ -903,6 +928,8 @@ struct sectionalize<multi_linestring_tag, MultiLinestring, Reverse, DimensionVec
\param geometry geometry to create sections from
\param robust_policy policy to handle robustness issues
\param sections structure with sections
+ \param envelope_strategy strategy for envelope calculation
+ \param expand_strategy strategy for partitions
\param source_index index to assign to the ring_identifiers
\param max_count maximal number of points per section
(defaults to 10, this seems to give the fastest results)
@@ -915,12 +942,14 @@ template
typename Geometry,
typename Sections,
typename RobustPolicy,
- typename EnvelopeStrategy
+ typename EnvelopeStrategy,
+ typename ExpandStrategy
>
inline void sectionalize(Geometry const& geometry,
RobustPolicy const& robust_policy,
Sections& sections,
- EnvelopeStrategy const& strategy,
+ EnvelopeStrategy const& envelope_strategy,
+ ExpandStrategy const& expand_strategy,
int source_index = 0,
std::size_t max_count = 10)
{
@@ -959,7 +988,9 @@ inline void sectionalize(Geometry const& geometry,
Geometry,
Reverse,
DimensionVector
- >::apply(geometry, robust_policy, sections, strategy, ring_id, max_count);
+ >::apply(geometry, robust_policy, sections,
+ envelope_strategy, expand_strategy,
+ ring_id, max_count);
detail::sectionalize::enlarge_sections(sections);
}
@@ -981,14 +1012,27 @@ inline void sectionalize(Geometry const& geometry,
{
typedef typename strategy::envelope::services::default_strategy
<
+ typename tag<Geometry>::type,
typename cs_tag<Geometry>::type
>::type envelope_strategy_type;
+ typedef typename strategy::expand::services::default_strategy
+ <
+ typename boost::mpl::if_c
+ <
+ boost::is_same<typename tag<Geometry>::type, box_tag>::value,
+ box_tag,
+ segment_tag
+ >::type,
+ typename cs_tag<Geometry>::type
+ >::type expand_strategy_type;
+
boost::geometry::sectionalize
<
Reverse, DimensionVector
>(geometry, robust_policy, sections,
envelope_strategy_type(),
+ expand_strategy_type(),
source_index, max_count);
}
diff --git a/boost/geometry/algorithms/detail/sub_range.hpp b/boost/geometry/algorithms/detail/sub_range.hpp
index 29edc94e6c..099de426ab 100644
--- a/boost/geometry/algorithms/detail/sub_range.hpp
+++ b/boost/geometry/algorithms/detail/sub_range.hpp
@@ -2,21 +2,29 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2013, 2014.
-// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2018.
+// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
-
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP
#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.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/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
#include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry {
diff --git a/boost/geometry/algorithms/detail/within/implementation.hpp b/boost/geometry/algorithms/detail/within/implementation.hpp
index a1fae421e5..163092b2cb 100644
--- a/boost/geometry/algorithms/detail/within/implementation.hpp
+++ b/boost/geometry/algorithms/detail/within/implementation.hpp
@@ -4,8 +4,8 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2013, 2014, 2017.
-// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2017, 2019.
+// Modifications copyright (c) 2013-2019 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -61,7 +61,7 @@ struct use_point_in_geometry
template <typename Geometry1, typename Geometry2, typename Strategy>
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
{
- return detail::within::point_in_geometry(geometry1, geometry2, strategy) == 1;
+ return detail::within::within_point_geometry(geometry1, geometry2, strategy);
}
};
diff --git a/boost/geometry/algorithms/detail/within/interface.hpp b/boost/geometry/algorithms/detail/within/interface.hpp
index 23263604c2..048cc01f7a 100644
--- a/boost/geometry/algorithms/detail/within/interface.hpp
+++ b/boost/geometry/algorithms/detail/within/interface.hpp
@@ -4,8 +4,8 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2013, 2014, 2017.
-// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2017, 2018.
+// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -70,13 +70,7 @@ struct within
Geometry2 const& geometry2,
Strategy const& strategy)
{
- concepts::within::check
- <
- typename tag<Geometry1>::type,
- typename tag<Geometry2>::type,
- typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
- Strategy
- >();
+ concepts::within::check<Geometry1, Geometry2, Strategy>();
return dispatch::within<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
}
diff --git a/boost/geometry/algorithms/detail/within/point_in_geometry.hpp b/boost/geometry/algorithms/detail/within/point_in_geometry.hpp
index a24f4d21e2..45449eb194 100644
--- a/boost/geometry/algorithms/detail/within/point_in_geometry.hpp
+++ b/boost/geometry/algorithms/detail/within/point_in_geometry.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013, 2014, 2015, 2017.
-// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018, 2019.
+// Modifications copyright (c) 2013-2019, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -45,6 +45,11 @@ namespace boost { namespace geometry {
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace within {
+template <typename Point1, typename Point2, typename Strategy>
+inline bool equals_point_point(Point1 const& p1, Point2 const& p2, Strategy const& strategy)
+{
+ return equals::equals_point_point(p1, p2, strategy.get_equals_point_point_strategy());
+}
// TODO: is this needed?
inline int check_result_type(int result)
@@ -139,8 +144,8 @@ struct point_in_geometry<Segment, segment_tag>
return -1; // exterior
// if the point is equal to the one of the terminal points
- if ( detail::equals::equals_point_point(point, p0)
- || detail::equals::equals_point_point(point, p1) )
+ if ( detail::within::equals_point_point(point, p0, strategy)
+ || detail::within::equals_point_point(point, p1, strategy) )
return 0; // boundary
else
return 1; // interior
@@ -161,11 +166,11 @@ struct point_in_geometry<Linestring, linestring_tag>
return -1; // exterior
// if the linestring doesn't have a boundary
- if (detail::equals::equals_point_point(range::front(linestring), range::back(linestring)))
+ if (detail::within::equals_point_point(range::front(linestring), range::back(linestring), strategy))
return 1; // interior
// else if the point is equal to the one of the terminal points
- else if (detail::equals::equals_point_point(point, range::front(linestring))
- || detail::equals::equals_point_point(point, range::back(linestring)))
+ else if (detail::within::equals_point_point(point, range::front(linestring), strategy)
+ || detail::within::equals_point_point(point, range::back(linestring), strategy))
return 0; // boundary
else
return 1; // interior
@@ -304,12 +309,12 @@ struct point_in_geometry<Geometry, multi_linestring_tag>
point_type const& back = range::back(*it);
// is closed_ring - no boundary
- if ( detail::equals::equals_point_point(front, back) )
+ if ( detail::within::equals_point_point(front, back, strategy) )
continue;
// is point on boundary
- if ( detail::equals::equals_point_point(point, front)
- || detail::equals::equals_point_point(point, back) )
+ if ( detail::within::equals_point_point(point, front, strategy)
+ || detail::within::equals_point_point(point, back, strategy) )
{
++boundaries;
}
@@ -361,13 +366,7 @@ namespace detail { namespace within {
template <typename Point, typename Geometry, typename Strategy>
inline int point_in_geometry(Point const& point, Geometry const& geometry, Strategy const& strategy)
{
- concepts::within::check
- <
- typename tag<Point>::type,
- typename tag<Geometry>::type,
- typename tag_cast<typename tag<Geometry>::type, areal_tag>::type,
- Strategy
- >();
+ concepts::within::check<Point, Geometry, Strategy>();
return detail_dispatch::within::point_in_geometry<Geometry>::apply(point, geometry, strategy);
}
@@ -383,6 +382,30 @@ inline int point_in_geometry(Point const& point, Geometry const& geometry)
return point_in_geometry(point, geometry, strategy_type());
}
+template <typename Point, typename Geometry, typename Strategy>
+inline bool within_point_geometry(Point const& point, Geometry const& geometry, Strategy const& strategy)
+{
+ return point_in_geometry(point, geometry, strategy) > 0;
+}
+
+template <typename Point, typename Geometry>
+inline bool within_point_geometry(Point const& point, Geometry const& geometry)
+{
+ return point_in_geometry(point, geometry) > 0;
+}
+
+template <typename Point, typename Geometry, typename Strategy>
+inline bool covered_by_point_geometry(Point const& point, Geometry const& geometry, Strategy const& strategy)
+{
+ return point_in_geometry(point, geometry, strategy) >= 0;
+}
+
+template <typename Point, typename Geometry>
+inline bool covered_by_point_geometry(Point const& point, Geometry const& geometry)
+{
+ return point_in_geometry(point, geometry) >= 0;
+}
+
}} // namespace detail::within
#endif // DOXYGEN_NO_DETAIL
diff --git a/boost/geometry/algorithms/discrete_frechet_distance.hpp b/boost/geometry/algorithms/discrete_frechet_distance.hpp
index de8a5286e0..70a0c1d11d 100644
--- a/boost/geometry/algorithms/discrete_frechet_distance.hpp
+++ b/boost/geometry/algorithms/discrete_frechet_distance.hpp
@@ -1,8 +1,12 @@
// Boost.Geometry
// Copyright (c) 2018 Yaghyavardhan Singh Khangarot, Hyderabad, India.
+// Contributed and/or modified by Yaghyavardhan Singh Khangarot,
+// as part of Google Summer of Code 2018 program.
-// Contributed and/or modified by Yaghyavardhan Singh Khangarot, as part of Google Summer of Code 2018 program.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018 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
@@ -22,13 +26,15 @@
#include <vector>
#include <limits>
-#include <boost/geometry/geometry.hpp>
-#include <boost/geometry/geometries/linestring.hpp>
-#include <boost/geometry/geometries/point_xy.hpp>
-#include <boost/geometry/geometries/polygon.hpp>
-#include <boost/range.hpp>
-#include <boost/mpl/assert.hpp>
+#include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/strategies/distance_result.hpp>
+#include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry
@@ -48,7 +54,7 @@ public:
result_type & operator()(size_type1 i, size_type2 j)
{
- BOOST_ASSERT(i < m_width && j < m_height);
+ BOOST_GEOMETRY_ASSERT(i < m_width && j < m_height);
return m_data[j * m_width + i];
}
@@ -86,28 +92,31 @@ struct linestring_linestring
//Coupling Matrix CoupMat(a,b,-1);
- coup_mat<size_type1,size_type2,result_type> coup_matrix(a,b);
+ coup_mat<size_type1,size_type2,result_type> coup_matrix(a,b);
result_type const not_feasible = -100;
//findin the Coupling Measure
- for(size_type1 i=0;i<a;i++)
+ for (size_type1 i = 0 ; i < a ; i++ )
{
for(size_type2 j=0;j<b;j++)
{
- result_type dis = geometry::distance(range::at(ls1,i),range::at(ls2,j),strategy);
+ result_type dis = strategy.apply(range::at(ls1,i), range::at(ls2,j));
if(i==0 && j==0)
- coup_matrix(i,j)= dis;
+ coup_matrix(i,j) = dis;
else if(i==0 && j>0)
- coup_matrix(i,j)=
- (std::max)(coup_matrix(i,j-1),dis);
+ coup_matrix(i,j) =
+ (std::max)(coup_matrix(i,j-1), dis);
else if(i>0 && j==0)
- coup_matrix(i,j)=
- (std::max)(coup_matrix(i-1,j),dis);
+ coup_matrix(i,j) =
+ (std::max)(coup_matrix(i-1,j), dis);
else if(i>0 && j>0)
- coup_matrix(i,j)=
- (std::max)((std::min)(coup_matrix(i,j-1),(std::min)(coup_matrix(i-1,j),coup_matrix(i-1,j-1))),dis);
+ coup_matrix(i,j) =
+ (std::max)((std::min)(coup_matrix(i,j-1),
+ (std::min)(coup_matrix(i-1,j),
+ coup_matrix(i-1,j-1))),
+ dis);
else
- coup_matrix(i,j)=not_feasible;
+ coup_matrix(i,j) = not_feasible;
}
}
@@ -140,8 +149,15 @@ template
>
struct discrete_frechet_distance : not_implemented<Tag1, Tag2>
{};
+
template <typename Linestring1, typename Linestring2>
-struct discrete_frechet_distance<Linestring1,Linestring2,linestring_tag,linestring_tag>
+struct discrete_frechet_distance
+ <
+ Linestring1,
+ Linestring2,
+ linestring_tag,
+ linestring_tag
+ >
: detail::discrete_frechet_distance::linestring_linestring
{};
@@ -151,7 +167,7 @@ struct discrete_frechet_distance<Linestring1,Linestring2,linestring_tag,linestri
/*!
\brief Calculate discrete Frechet distance between two geometries (currently
- works for LineString-LineString) using specified strategy.
+ works for LineString-LineString) using specified strategy.
\ingroup discrete_frechet_distance
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry
@@ -181,16 +197,21 @@ inline typename distance_result
typename point_type<Geometry2>::type,
Strategy
>::type
-discrete_frechet_distance(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
+discrete_frechet_distance(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
{
- return dispatch::discrete_frechet_distance<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
+ return dispatch::discrete_frechet_distance
+ <
+ Geometry1, Geometry2
+ >::apply(geometry1, geometry2, strategy);
}
// Algorithm overload using default Pt-Pt distance strategy
/*!
\brief Calculate discrete Frechet distance between two geometries (currently
- work for LineString-LineString).
+ work for LineString-LineString).
\ingroup discrete_frechet_distance
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry
diff --git a/boost/geometry/algorithms/discrete_hausdorff_distance.hpp b/boost/geometry/algorithms/discrete_hausdorff_distance.hpp
index f9daefe62b..6b954737bf 100644
--- a/boost/geometry/algorithms/discrete_hausdorff_distance.hpp
+++ b/boost/geometry/algorithms/discrete_hausdorff_distance.hpp
@@ -26,16 +26,18 @@
#include <vector>
#include <limits>
-#include <boost/geometry/geometry.hpp>
-#include <boost/geometry/geometries/linestring.hpp>
-#include <boost/geometry/geometries/point_xy.hpp>
-#include <boost/geometry/geometries/polygon.hpp>
-#include <boost/range.hpp>
-#include <boost/mpl/assert.hpp>
+#include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
+#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tag.hpp>
-#include <boost/geometry/index/rtree.hpp>
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/strategies/distance_result.hpp>
+#include <boost/geometry/util/range.hpp>
-namespace bgi = boost::geometry::index;
+#ifdef BOOST_GEOMETRY_ENABLE_SIMILARITY_RTREE
+#include <boost/geometry/index/rtree.hpp>
+#endif // BOOST_GEOMETRY_ENABLE_SIMILARITY_RTREE
namespace boost { namespace geometry
{
@@ -70,7 +72,7 @@ struct point_range
for (size_type i = 0 ; i < n ; i++)
{
- result_type dis_temp = geometry::distance(pnt, range::at(rng, i), strategy);
+ result_type dis_temp = strategy.apply(pnt, range::at(rng, i));
if (! is_dis_min_set || dis_temp < dis_min)
{
dis_min = dis_temp;
@@ -110,6 +112,7 @@ struct range_range
result_type dis_max = 0;
#ifdef BOOST_GEOMETRY_ENABLE_SIMILARITY_RTREE
+ namespace bgi = boost::geometry::index;
typedef typename point_type<Range1>::type point_t;
typedef bgi::rtree<point_t, bgi::linear<4> > rtree_type;
rtree_type rtree(boost::begin(r2), boost::end(r2));
@@ -120,7 +123,7 @@ struct range_range
{
#ifdef BOOST_GEOMETRY_ENABLE_SIMILARITY_RTREE
size_type found = rtree.query(bgi::nearest(range::at(r1, i), 1), &res);
- result_type dis_min = geometry::distance(range::at(r1,i), res);
+ result_type dis_min = strategy.apply(range::at(r1,i), res);
#else
result_type dis_min = point_range::apply(range::at(r1, i), r2, strategy);
#endif
@@ -246,15 +249,15 @@ struct discrete_hausdorff_distance<MultiPoint1, MultiPoint2, multi_point_tag, mu
: detail::discrete_hausdorff_distance::range_range
{};
-// Specialization for linestring and multi_linestring
-template <typename linestring, typename multi_linestring>
-struct discrete_hausdorff_distance<linestring, multi_linestring, linestring_tag, multi_linestring_tag>
+// Specialization for Linestring and MultiLinestring
+template <typename Linestring, typename MultiLinestring>
+struct discrete_hausdorff_distance<Linestring, MultiLinestring, linestring_tag, multi_linestring_tag>
: detail::discrete_hausdorff_distance::range_multi_range
{};
-// Specialization for multi_linestring and multi_linestring
-template <typename multi_linestring1, typename multi_linestring2>
-struct discrete_hausdorff_distance<multi_linestring1, multi_linestring2, multi_linestring_tag, multi_linestring_tag>
+// Specialization for MultiLinestring and MultiLinestring
+template <typename MultiLinestring1, typename MultiLinestring2>
+struct discrete_hausdorff_distance<MultiLinestring1, MultiLinestring2, multi_linestring_tag, multi_linestring_tag>
: detail::discrete_hausdorff_distance::multi_range_multi_range
{};
diff --git a/boost/geometry/algorithms/dispatch/disjoint.hpp b/boost/geometry/algorithms/dispatch/disjoint.hpp
index 78015f1a55..ef74991883 100644
--- a/boost/geometry/algorithms/dispatch/disjoint.hpp
+++ b/boost/geometry/algorithms/dispatch/disjoint.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013-2017.
-// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013-2018.
+// Modifications copyright (c) 2013-2018, 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,6 +23,7 @@
#include <cstddef>
+#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tag_cast.hpp>
#include <boost/geometry/core/tags.hpp>
diff --git a/boost/geometry/algorithms/dispatch/distance.hpp b/boost/geometry/algorithms/dispatch/distance.hpp
index cae3ebd0c9..b12fc0ce9d 100644
--- a/boost/geometry/algorithms/dispatch/distance.hpp
+++ b/boost/geometry/algorithms/dispatch/distance.hpp
@@ -5,10 +5,11 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2018.
+// Modifications copyright (c) 2014-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -25,8 +26,9 @@
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tag_cast.hpp>
#include <boost/geometry/core/tags.hpp>
-#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
+#include <boost/geometry/strategies/distance.hpp>
namespace boost { namespace geometry
diff --git a/boost/geometry/algorithms/dispatch/envelope.hpp b/boost/geometry/algorithms/dispatch/envelope.hpp
index bb8a99f5a8..bfe0f0d447 100644
--- a/boost/geometry/algorithms/dispatch/envelope.hpp
+++ b/boost/geometry/algorithms/dispatch/envelope.hpp
@@ -4,10 +4,11 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -35,8 +36,7 @@ namespace dispatch
template
<
typename Geometry,
- typename Tag = typename tag<Geometry>::type,
- typename CS_Tag = typename cs_tag<Geometry>::type
+ typename Tag = typename tag<Geometry>::type
>
struct envelope : not_implemented<Tag>
{};
diff --git a/boost/geometry/algorithms/dispatch/expand.hpp b/boost/geometry/algorithms/dispatch/expand.hpp
index c7a7696480..204bbc6ce3 100644
--- a/boost/geometry/algorithms/dispatch/expand.hpp
+++ b/boost/geometry/algorithms/dispatch/expand.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
-// This file was modified by Oracle on 2015, 2017.
-// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2017, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -41,9 +41,7 @@ template
<
typename GeometryOut, typename Geometry,
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
+ typename Tag = typename tag<Geometry>::type
>
struct expand : not_implemented<TagOut, Tag>
{};
diff --git a/boost/geometry/algorithms/is_convex.hpp b/boost/geometry/algorithms/is_convex.hpp
index 4a9251b270..1df778d1b5 100644
--- a/boost/geometry/algorithms/is_convex.hpp
+++ b/boost/geometry/algorithms/is_convex.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2017.
-// Modifications copyright (c) 2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2017, 2018.
+// Modifications copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -45,6 +45,9 @@ struct ring_is_convex
template <typename Ring, typename SideStrategy>
static inline bool apply(Ring const& ring, SideStrategy const& strategy)
{
+ typename SideStrategy::equals_point_point_strategy_type
+ eq_pp_strategy = strategy.get_equals_point_point_strategy();
+
std::size_t n = boost::size(ring);
if (boost::size(ring) < core_detail::closure::minimum_ring_size
<
@@ -67,7 +70,8 @@ struct ring_is_convex
current++;
std::size_t index = 1;
- while (equals::equals_point_point(*current, *previous) && index < n)
+ while (equals::equals_point_point(*current, *previous, eq_pp_strategy)
+ && index < n)
{
current++;
index++;
@@ -81,7 +85,7 @@ struct ring_is_convex
it_type next = current;
next++;
- while (equals::equals_point_point(*current, *next))
+ while (equals::equals_point_point(*current, *next, eq_pp_strategy))
{
next++;
}
@@ -105,7 +109,7 @@ struct ring_is_convex
// 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))
+ while (equals::equals_point_point(*current, *next, eq_pp_strategy))
{
next++;
}
diff --git a/boost/geometry/algorithms/line_interpolate.hpp b/boost/geometry/algorithms/line_interpolate.hpp
new file mode 100644
index 0000000000..1de92a0b62
--- /dev/null
+++ b/boost/geometry/algorithms/line_interpolate.hpp
@@ -0,0 +1,411 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2018, 2019 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// 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_LINE_INTERPOLATE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_LINE_INTERPOLATE_HPP
+
+#include <iterator>
+
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/range/value_type.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/length.hpp>
+#include <boost/geometry/strategies/default_strategy.hpp>
+#include <boost/geometry/strategies/line_interpolate.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace line_interpolate
+{
+
+struct convert_and_push_back
+{
+ template <typename Range, typename Point>
+ inline void apply(Point const& p, Range& range)
+ {
+ typename boost::range_value<Range>::type p2;
+ geometry::detail::conversion::convert_point_to_point(p, p2);
+ range::push_back(range, p2);
+ }
+};
+
+struct convert_and_assign
+{
+ template <typename Point1, typename Point2>
+ inline void apply(Point1 const& p1, Point2& p2)
+ {
+ geometry::detail::conversion::convert_point_to_point(p1, p2);
+ }
+
+};
+
+
+/*!
+\brief Internal, calculates interpolation point of a linestring using iterator pairs and
+ specified strategy
+*/
+template <typename Policy>
+struct interpolate_range
+{
+ template
+ <
+ typename Range,
+ typename Distance,
+ typename PointLike,
+ typename Strategy
+ >
+ static inline void apply(Range const& range,
+ Distance const& max_distance,
+ PointLike & pointlike,
+ Strategy const& strategy)
+ {
+ Policy policy;
+
+ typedef typename boost::range_iterator<Range const>::type iterator_t;
+ typedef typename boost::range_value<Range const>::type point_t;
+
+ iterator_t it = boost::begin(range);
+ iterator_t end = boost::end(range);
+
+ if (it == end) // empty(range)
+ {
+ BOOST_THROW_EXCEPTION(empty_input_exception());
+ return;
+ }
+ if (max_distance <= 0) //non positive distance
+ {
+ policy.apply(*it, pointlike);
+ return;
+ }
+
+ iterator_t prev = it++;
+ Distance repeated_distance = max_distance;
+ Distance prev_distance = 0;
+ Distance current_distance = 0;
+ point_t start_p = *prev;
+
+ for ( ; it != end ; ++it)
+ {
+ Distance dist = strategy.get_distance_pp_strategy().apply(*prev, *it);
+ current_distance = prev_distance + dist;
+
+ while (current_distance >= repeated_distance)
+ {
+ point_t p;
+ Distance diff_distance = current_distance - prev_distance;
+ BOOST_ASSERT(diff_distance != Distance(0));
+ strategy.apply(start_p, *it,
+ (repeated_distance - prev_distance)/diff_distance,
+ p,
+ diff_distance);
+ policy.apply(p, pointlike);
+ if (boost::is_same<PointLike, point_t>::value)
+ {
+ return;
+ }
+ start_p = p;
+ prev_distance = repeated_distance;
+ repeated_distance += max_distance;
+ }
+ prev_distance = current_distance;
+ prev = it;
+ start_p = *prev;
+ }
+
+ // case when max_distance is larger than linestring's length
+ // return the last point in range (range is not empty)
+ if (repeated_distance == max_distance)
+ {
+ policy.apply(*(end-1), pointlike);
+ }
+ }
+};
+
+template <typename Policy>
+struct interpolate_segment
+{
+ template <typename Segment, typename Distance, typename Pointlike, typename Strategy>
+ static inline void apply(Segment const& segment,
+ Distance const& max_distance,
+ Pointlike & point,
+ Strategy const& strategy)
+ {
+ interpolate_range<Policy>().apply(segment_view<Segment>(segment),
+ max_distance, point, strategy);
+ }
+};
+
+}} // namespace detail::line_interpolate
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename Geometry,
+ typename Pointlike,
+ typename Tag1 = typename tag<Geometry>::type,
+ typename Tag2 = typename tag<Pointlike>::type
+>
+struct line_interpolate
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+
+template <typename Geometry, typename Pointlike>
+struct line_interpolate<Geometry, Pointlike, linestring_tag, point_tag>
+ : detail::line_interpolate::interpolate_range
+ <
+ detail::line_interpolate::convert_and_assign
+ >
+{};
+
+template <typename Geometry, typename Pointlike>
+struct line_interpolate<Geometry, Pointlike, linestring_tag, multi_point_tag>
+ : detail::line_interpolate::interpolate_range
+ <
+ detail::line_interpolate::convert_and_push_back
+ >
+{};
+
+template <typename Geometry, typename Pointlike>
+struct line_interpolate<Geometry, Pointlike, segment_tag, point_tag>
+ : detail::line_interpolate::interpolate_segment
+ <
+ detail::line_interpolate::convert_and_assign
+ >
+{};
+
+template <typename Geometry, typename Pointlike>
+struct line_interpolate<Geometry, Pointlike, segment_tag, multi_point_tag>
+ : detail::line_interpolate::interpolate_segment
+ <
+ detail::line_interpolate::convert_and_push_back
+ >
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+namespace resolve_strategy {
+
+struct line_interpolate
+{
+ template
+ <
+ typename Geometry,
+ typename Distance,
+ typename Pointlike,
+ typename Strategy
+ >
+ static inline void apply(Geometry const& geometry,
+ Distance const& max_distance,
+ Pointlike & pointlike,
+ Strategy const& strategy)
+ {
+ dispatch::line_interpolate<Geometry, Pointlike>::apply(geometry,
+ max_distance,
+ pointlike,
+ strategy);
+ }
+
+ template <typename Geometry, typename Distance, typename Pointlike>
+ static inline void apply(Geometry const& geometry,
+ Distance const& max_distance,
+ Pointlike & pointlike,
+ default_strategy)
+ {
+ typedef typename strategy::line_interpolate::services::default_strategy
+ <
+ typename cs_tag<Geometry>::type
+ >::type strategy_type;
+
+ dispatch::line_interpolate<Geometry, Pointlike>::apply(geometry,
+ max_distance,
+ pointlike,
+ strategy_type());
+ }
+};
+
+} // namespace resolve_strategy
+
+
+namespace resolve_variant {
+
+template <typename Geometry>
+struct line_interpolate
+{
+ template <typename Distance, typename Pointlike, typename Strategy>
+ static inline void apply(Geometry const& geometry,
+ Distance const& max_distance,
+ Pointlike & pointlike,
+ Strategy const& strategy)
+ {
+ return resolve_strategy::line_interpolate::apply(geometry,
+ max_distance,
+ pointlike,
+ strategy);
+ }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct line_interpolate<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ template <typename Pointlike, typename Strategy>
+ struct visitor: boost::static_visitor<void>
+ {
+ Pointlike const& m_pointlike;
+ Strategy const& m_strategy;
+
+ visitor(Pointlike const& pointlike, Strategy const& strategy)
+ : m_pointlike(pointlike)
+ , m_strategy(strategy)
+ {}
+
+ template <typename Geometry, typename Distance>
+ void operator()(Geometry const& geometry, Distance const& max_distance) const
+ {
+ line_interpolate<Geometry>::apply(geometry, max_distance,
+ m_pointlike, m_strategy);
+ }
+ };
+
+ template <typename Distance, typename Pointlike, typename Strategy>
+ static inline void
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
+ double const& max_distance,
+ Pointlike & pointlike,
+ Strategy const& strategy)
+ {
+ boost::apply_visitor(
+ visitor<Pointlike, Strategy>(pointlike, strategy),
+ geometry,
+ max_distance
+ );
+ }
+};
+
+} // namespace resolve_variant
+
+/*!
+\brief Returns one or more points interpolated along a LineString \brief_strategy
+\ingroup line_interpolate
+\tparam Geometry Any type fulfilling a LineString concept
+\tparam Distance A numerical distance measure
+\tparam Pointlike Any type fulfilling Point or Multipoint concept
+\tparam Strategy A type fulfilling a LineInterpolatePointStrategy concept
+\param geometry Input geometry
+\param max_distance Distance threshold (in units depending on coordinate system)
+representing the spacing between the points
+\param pointlike Output: either a Point (exactly one point will be constructed) or
+a MultiPoint (depending on the max_distance one or more points will be constructed)
+\param strategy line_interpolate strategy to be used for interpolation of
+points
+
+\qbk{[include reference/algorithms/line_interpolate.qbk]}
+
+\qbk{distinguish,with strategy}
+
+\qbk{
+[heading Available Strategies]
+\* [link geometry.reference.strategies.strategy_line_interpolate_cartesian Cartesian]
+\* [link geometry.reference.strategies.strategy_line_interpolate_spherical Spherical]
+\* [link geometry.reference.strategies.strategy_line_interpolate_geographic Geographic]
+
+[heading Example]
+[line_interpolate_strategy]
+[line_interpolate_strategy_output]
+
+[heading See also]
+\* [link geometry.reference.algorithms.densify densify]
+}
+ */
+template
+<
+ typename Geometry,
+ typename Distance,
+ typename Pointlike,
+ typename Strategy
+>
+inline void line_interpolate(Geometry const& geometry,
+ Distance const& max_distance,
+ Pointlike & pointlike,
+ Strategy const& strategy)
+{
+ concepts::check<Geometry const>();
+
+ // detail::throw_on_empty_input(geometry);
+
+ return resolve_variant::line_interpolate<Geometry>
+ ::apply(geometry, max_distance, pointlike, strategy);
+}
+
+
+/*!
+\brief Returns one or more points interpolated along a LineString.
+\ingroup line_interpolate
+\tparam Geometry Any type fulfilling a LineString concept
+\tparam Distance A numerical distance measure
+\tparam Pointlike Any type fulfilling Point or Multipoint concept
+\param geometry Input geometry
+\param max_distance Distance threshold (in units depending on coordinate system)
+representing the spacing between the points
+\param pointlike Output: either a Point (exactly one point will be constructed) or
+a MultiPoint (depending on the max_distance one or more points will be constructed)
+
+\qbk{[include reference/algorithms/line_interpolate.qbk]
+
+[heading Example]
+[line_interpolate]
+[line_interpolate_output]
+
+[heading See also]
+\* [link geometry.reference.algorithms.densify densify]
+}
+ */
+template<typename Geometry, typename Distance, typename Pointlike>
+inline void line_interpolate(Geometry const& geometry,
+ Distance const& max_distance,
+ Pointlike & pointlike)
+{
+ concepts::check<Geometry const>();
+
+ // detail::throw_on_empty_input(geometry);
+
+ return resolve_variant::line_interpolate<Geometry>
+ ::apply(geometry, max_distance, pointlike, default_strategy());
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_LINE_INTERPOLATE_HPP
diff --git a/boost/geometry/algorithms/simplify.hpp b/boost/geometry/algorithms/simplify.hpp
index 298f9c640a..b5276878ef 100644
--- a/boost/geometry/algorithms/simplify.hpp
+++ b/boost/geometry/algorithms/simplify.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -15,6 +20,7 @@
#define BOOST_GEOMETRY_ALGORITHMS_SIMPLIFY_HPP
#include <cstddef>
+#include <set>
#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
@@ -53,12 +59,13 @@ namespace boost { namespace geometry
namespace detail { namespace simplify
{
-template <typename Range>
-inline bool is_degenerate(Range const& range)
+template <typename Range, typename EqualsStrategy>
+inline bool is_degenerate(Range const& range, EqualsStrategy const& strategy)
{
return boost::size(range) == 2
&& detail::equals::equals_point_point(geometry::range::front(range),
- geometry::range::back(range));
+ geometry::range::back(range),
+ strategy);
}
struct simplify_range_insert
@@ -67,9 +74,12 @@ struct simplify_range_insert
static inline void apply(Range const& range, OutputIterator out,
Distance const& max_distance, Strategy const& strategy)
{
+ typedef typename Strategy::distance_strategy_type::equals_point_point_strategy_type
+ equals_strategy_type;
+
boost::ignore_unused(strategy);
- if (is_degenerate(range))
+ if (is_degenerate(range, equals_strategy_type()))
{
std::copy(boost::begin(range), boost::begin(range) + 1, out);
}
@@ -107,6 +117,9 @@ struct simplify_range
static inline void apply(RangeIn const& range, RangeOut& out,
Distance const& max_distance, Strategy const& strategy)
{
+ typedef typename Strategy::distance_strategy_type::equals_point_point_strategy_type
+ equals_strategy_type;
+
// For a RING:
// Note that, especially if max_distance is too large,
// the output ring might be self intersecting while the input ring is
@@ -126,7 +139,7 @@ struct simplify_range
// Verify the two remaining points are equal. If so, remove one of them.
// This can cause the output being under the minimum size
- if (is_degenerate(out))
+ if (is_degenerate(out, equals_strategy_type()))
{
range::resize(out, 1);
}
diff --git a/boost/geometry/algorithms/union.hpp b/boost/geometry/algorithms/union.hpp
index d3a2daf66e..d1d04d4045 100644
--- a/boost/geometry/algorithms/union.hpp
+++ b/boost/geometry/algorithms/union.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2014, 2017.
-// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2017, 2018.
+// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -279,9 +279,10 @@ struct union_
{
typedef typename boost::range_value<Collection>::type geometry_out;
- typedef typename strategy::intersection::services::default_strategy
+ typedef typename strategy::relate::services::default_strategy
<
- typename cs_tag<geometry_out>::type
+ Geometry1,
+ Geometry2
>::type strategy_type;
dispatch::union_insert
diff --git a/boost/geometry/core/config.hpp b/boost/geometry/core/config.hpp
new file mode 100644
index 0000000000..c068e98cc7
--- /dev/null
+++ b/boost/geometry/core/config.hpp
@@ -0,0 +1,26 @@
+// Boost.Geometry
+
+// Copyright (c) 2018 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_CORE_CONFIG_HPP
+#define BOOST_GEOMETRY_CORE_CONFIG_HPP
+
+#include <boost/config.hpp>
+
+// NOTE: workaround for VC++ 12 (aka 2013): cannot specify explicit initializer for arrays
+#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && (!defined(_MSC_VER) || (_MSC_VER >= 1900))
+#define BOOST_GEOMETRY_CXX11_ARRAY_UNIFIED_INITIALIZATION
+#endif
+
+// Rescaling is turned on, unless NO_ROBUSTNESS is defined
+// In future versions of Boost.Geometry, it will be turned off by default
+#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
+#define BOOST_GEOMETRY_USE_RESCALING
+#endif
+
+#endif // BOOST_GEOMETRY_CORE_CONFIG_HPP
diff --git a/boost/geometry/core/cs.hpp b/boost/geometry/core/cs.hpp
index 301fb6b76f..c39eec3d4d 100644
--- a/boost/geometry/core/cs.hpp
+++ b/boost/geometry/core/cs.hpp
@@ -4,10 +4,11 @@
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2018.
+// Modifications copyright (c) 2014-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -22,7 +23,6 @@
#include <cstddef>
#include <boost/mpl/assert.hpp>
-#include <boost/type_traits/integral_constant.hpp>
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -56,7 +56,7 @@ namespace core_detail
{
template <typename DegreeOrRadian>
-struct coordinate_system_units
+struct define_angular_units
{
BOOST_MPL_ASSERT_MSG
((false),
@@ -65,13 +65,13 @@ struct coordinate_system_units
};
template <>
-struct coordinate_system_units<geometry::degree>
+struct define_angular_units<geometry::degree>
{
typedef geometry::degree units;
};
template <>
-struct coordinate_system_units<geometry::radian>
+struct define_angular_units<geometry::radian>
{
typedef geometry::radian units;
};
@@ -107,12 +107,8 @@ known as lat,long or lo,la or phi,lambda
*/
template<typename DegreeOrRadian>
struct geographic
-{
- typedef typename core_detail::coordinate_system_units
- <
- DegreeOrRadian
- >::units units;
-};
+ : core_detail::define_angular_units<DegreeOrRadian>
+{};
@@ -136,12 +132,8 @@ struct geographic
*/
template<typename DegreeOrRadian>
struct spherical
-{
- typedef typename core_detail::coordinate_system_units
- <
- DegreeOrRadian
- >::units units;
-};
+ : core_detail::define_angular_units<DegreeOrRadian>
+{};
/*!
@@ -156,12 +148,8 @@ struct spherical
*/
template<typename DegreeOrRadian>
struct spherical_equatorial
-{
- typedef typename core_detail::coordinate_system_units
- <
- DegreeOrRadian
- >::units units;
-};
+ : core_detail::define_angular_units<DegreeOrRadian>
+{};
@@ -174,12 +162,15 @@ struct spherical_equatorial
*/
template<typename DegreeOrRadian>
struct polar
-{
- typedef typename core_detail::coordinate_system_units
- <
- DegreeOrRadian
- >::units units;
-};
+ : core_detail::define_angular_units<DegreeOrRadian>
+{};
+
+
+/*!
+\brief Undefined coordinate system
+\ingroup cs
+*/
+struct undefined {};
} // namespace cs
@@ -227,9 +218,18 @@ struct cs_tag<cs::cartesian>
};
+template <>
+struct cs_tag<cs::undefined>
+{
+ typedef cs_undefined_tag type;
+};
+
#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+
} // namespace traits
+
/*!
\brief Meta-function returning coordinate system tag (cs family) of any geometry
\tparam Geometry \tparam_geometry
@@ -245,24 +245,97 @@ struct cs_tag
};
-/*!
-\brief Meta-function to verify if a coordinate system is radian
-\tparam CoordinateSystem Any coordinate system.
-\ingroup core
-*/
+namespace traits
+{
+
+// cartesian or undefined
template <typename CoordinateSystem>
-struct is_radian : boost::true_type {};
+struct cs_angular_units
+{
+ typedef geometry::radian type;
+};
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+template<typename DegreeOrRadian>
+struct cs_angular_units<cs::geographic<DegreeOrRadian> >
+{
+ typedef DegreeOrRadian type;
+};
+
+template<typename DegreeOrRadian>
+struct cs_angular_units<cs::spherical<DegreeOrRadian> >
+{
+ typedef DegreeOrRadian type;
+};
+
+template<typename DegreeOrRadian>
+struct cs_angular_units<cs::spherical_equatorial<DegreeOrRadian> >
+{
+ typedef DegreeOrRadian type;
+};
+
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace traits
-#ifndef DOXYGEN_NO_SPECIALIZATIONS
-// Specialization for any degree coordinate systems
-template <template<typename> class CoordinateSystem>
-struct is_radian< CoordinateSystem<degree> > : boost::false_type
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename Geometry>
+struct cs_angular_units
{
+ typedef typename traits::cs_angular_units
+ <
+ typename geometry::coordinate_system<Geometry>::type
+ >::type type;
};
-#endif // DOXYGEN_NO_SPECIALIZATIONS
+
+template <typename Units, typename CsTag>
+struct cs_tag_to_coordinate_system
+{
+ BOOST_MPL_ASSERT_MSG((false),
+ NOT_IMPLEMENTED_FOR_THIS_COORDINATE_SYSTEM,
+ (types<CsTag>));
+};
+
+template <typename Units>
+struct cs_tag_to_coordinate_system<Units, cs_undefined_tag>
+{
+ typedef cs::undefined type;
+};
+
+template <typename Units>
+struct cs_tag_to_coordinate_system<Units, cartesian_tag>
+{
+ typedef cs::cartesian type;
+};
+
+template <typename Units>
+struct cs_tag_to_coordinate_system<Units, spherical_equatorial_tag>
+{
+ typedef cs::spherical_equatorial<Units> type;
+};
+
+template <typename Units>
+struct cs_tag_to_coordinate_system<Units, spherical_polar_tag>
+{
+ typedef cs::spherical<Units> type;
+};
+
+template <typename Units>
+struct cs_tag_to_coordinate_system<Units, geographic_tag>
+{
+ typedef cs::geographic<Units> type;
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
}} // namespace boost::geometry
diff --git a/boost/geometry/core/tags.hpp b/boost/geometry/core/tags.hpp
index 5d6acb1878..f5bebbacb1 100644
--- a/boost/geometry/core/tags.hpp
+++ b/boost/geometry/core/tags.hpp
@@ -4,8 +4,8 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// 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, 2018.
+// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -25,6 +25,9 @@ namespace boost { namespace geometry
// Tags defining strategies linked to coordinate systems
+/// Tag used for undefined coordinate system
+struct cs_undefined_tag {};
+
/// Tag used for casting spherical/geographic coordinate systems
struct spherical_tag {};
diff --git a/boost/geometry/formulas/area_formulas.hpp b/boost/geometry/formulas/area_formulas.hpp
index 66d90a7256..c670f831a6 100644
--- a/boost/geometry/formulas/area_formulas.hpp
+++ b/boost/geometry/formulas/area_formulas.hpp
@@ -12,6 +12,7 @@
#ifndef BOOST_GEOMETRY_FORMULAS_AREA_FORMULAS_HPP
#define BOOST_GEOMETRY_FORMULAS_AREA_FORMULAS_HPP
+#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/formulas/flattening.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/math/special_functions/hypot.hpp>
diff --git a/boost/geometry/formulas/differential_quantities.hpp b/boost/geometry/formulas/differential_quantities.hpp
index ff2ec539db..6d4c223286 100644
--- a/boost/geometry/formulas/differential_quantities.hpp
+++ b/boost/geometry/formulas/differential_quantities.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry
-// Copyright (c) 2016-2017 Oracle and/or its affiliates.
+// Copyright (c) 2016-2019 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -70,10 +70,11 @@ public:
// equator
if (math::equals(sin_bet1, c0) && math::equals(sin_bet2, c0))
{
- CT const sig_12 = math::abs(dlon) / one_minus_f;
+ CT const sig_12 = dlon / one_minus_f;
if (BOOST_GEOMETRY_CONDITION(EnableReducedLength))
{
- CT m12 = sin(sig_12) * b;
+ int azi_sign = math::sign(azimuth) >= 0 ? 1 : -1; // for antipodal
+ CT m12 = azi_sign * sin(sig_12) * b;
reduced_length = m12;
}
diff --git a/boost/geometry/formulas/eccentricity_sqr.hpp b/boost/geometry/formulas/eccentricity_sqr.hpp
index 01a9beacb9..1608a85707 100644
--- a/boost/geometry/formulas/eccentricity_sqr.hpp
+++ b/boost/geometry/formulas/eccentricity_sqr.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry
-// Copyright (c) 2016 Oracle and/or its affiliates.
+// Copyright (c) 2016, 2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -11,11 +11,13 @@
#ifndef BOOST_GEOMETRY_FORMULAS_ECCENCRICITY_SQR_HPP
#define BOOST_GEOMETRY_FORMULAS_ECCENCRICITY_SQR_HPP
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
#include <boost/geometry/core/radius.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
-#include <boost/geometry/algorithms/not_implemented.hpp>
+#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/formulas/interpolate_point_spherical.hpp b/boost/geometry/formulas/interpolate_point_spherical.hpp
new file mode 100644
index 0000000000..7141a5a9f6
--- /dev/null
+++ b/boost/geometry/formulas/interpolate_point_spherical.hpp
@@ -0,0 +1,107 @@
+// Boost.Geometry
+
+// Copyright (c) 2019 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_FORMULAS_INTERPOLATE_POINT_SPHERICAL_HPP
+#define BOOST_GEOMETRY_FORMULAS_INTERPOLATE_POINT_SPHERICAL_HPP
+
+namespace boost { namespace geometry { namespace formula
+{
+
+template <typename CalculationType>
+class interpolate_point_spherical
+{
+ typedef model::point<CalculationType, 3, cs::cartesian> point3d_t;
+
+public :
+
+ template <typename Point>
+ void compute_angle(Point const& p0,
+ Point const& p1,
+ CalculationType& angle01)
+ {
+ m_xyz0 = formula::sph_to_cart3d<point3d_t>(p0);
+ m_xyz1 = formula::sph_to_cart3d<point3d_t>(p1);
+ CalculationType const dot01 = geometry::dot_product(m_xyz0, m_xyz1);
+ angle01 = acos(dot01);
+ }
+
+ template <typename Point>
+ void compute_axis(Point const& p0,
+ CalculationType const& angle01)
+ {
+ CalculationType const c0 = 0, c1 = 1;
+ CalculationType const pi = math::pi<CalculationType>();
+
+ if (! math::equals(angle01, pi))
+ {
+ m_axis = geometry::cross_product(m_xyz0, m_xyz1);
+ geometry::detail::vec_normalize(m_axis);
+ }
+ else // antipodal
+ {
+ CalculationType const half_pi = math::half_pi<CalculationType>();
+ CalculationType const lat = geometry::get_as_radian<1>(p0);
+
+ if (math::equals(lat, half_pi))
+ {
+ // pointing east, segment lies on prime meridian, going south
+ m_axis = point3d_t(c0, c1, c0);
+ }
+ else if (math::equals(lat, -half_pi))
+ {
+ // pointing west, segment lies on prime meridian, going north
+ m_axis = point3d_t(c0, -c1, c0);
+ }
+ else
+ {
+ // lon rotated west by pi/2 at equator
+ CalculationType const lon = geometry::get_as_radian<0>(p0);
+ m_axis = point3d_t(sin(lon), -cos(lon), c0);
+ }
+ }
+ }
+
+ template <typename Point>
+ void compute_point(CalculationType const& a, Point& p)
+ {
+ CalculationType const c1 = 1;
+
+ // Axis-Angle rotation
+ // see: https://en.wikipedia.org/wiki/Axis-angle_representation
+ CalculationType const cos_a = cos(a);
+ CalculationType const sin_a = sin(a);
+ // cos_a * v
+ point3d_t s1 = m_xyz0;
+ geometry::multiply_value(s1, cos_a);
+ // sin_a * (n x v)
+ point3d_t s2 = geometry::cross_product(m_axis, m_xyz0);
+ geometry::multiply_value(s2, sin_a);
+ // (1 - cos_a)(n.v) * n
+ point3d_t s3 = m_axis;
+ geometry::multiply_value(s3, (c1 - cos_a) *
+ geometry::dot_product(m_axis, m_xyz0));
+ // v_rot = cos_a * v + sin_a * (n x v) + (1 - cos_a)(n.v) * e
+ point3d_t v_rot = s1;
+ geometry::add_point(v_rot, s2);
+ geometry::add_point(v_rot, s3);
+
+ p = formula::cart3d_to_sph<Point>(v_rot);
+ }
+
+private :
+ point3d_t m_xyz0;
+ point3d_t m_xyz1;
+ point3d_t m_axis;
+};
+
+}}} // namespace boost::geometry::formula
+
+#endif // BOOST_GEOMETRY_FORMULAS_INTERPOLATE_POINT_SPHERICAL_HPP
diff --git a/boost/geometry/formulas/karney_direct.hpp b/boost/geometry/formulas/karney_direct.hpp
index 1e6add7d49..7a89061fd6 100644
--- a/boost/geometry/formulas/karney_direct.hpp
+++ b/boost/geometry/formulas/karney_direct.hpp
@@ -2,7 +2,12 @@
// Copyright (c) 2018 Adeel Ahmad, Islamabad, Pakistan.
-// Contributed and/or modified by Adeel Ahmad, as part of Google Summer of Code 2018 program.
+// Contributed and/or modified by Adeel Ahmad,
+// as part of Google Summer of Code 2018 program.
+
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018 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
@@ -30,13 +35,14 @@
#include <boost/math/constants/constants.hpp>
#include <boost/math/special_functions/hypot.hpp>
-#include <boost/geometry/util/math.hpp>
-#include <boost/geometry/util/series_expansion.hpp>
-#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
-
#include <boost/geometry/formulas/flattening.hpp>
#include <boost/geometry/formulas/result_direct.hpp>
+#include <boost/geometry/util/condition.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
+#include <boost/geometry/util/series_expansion.hpp>
+
namespace boost { namespace geometry { namespace formula
{
@@ -82,15 +88,6 @@ public:
Azi azi12 = azimuth12;
math::normalize_azimuth<degree, Azi>(azi12);
- Dist const dist_c0 = 0;
-
- if (math::equals(distance, dist_c0) || distance < dist_c0)
- {
- result.lon2 = lon1;
- result.lat2 = lat1;
- return result;
- }
-
CT const c0 = 0;
CT const c1 = 1;
CT const c2 = 2;
diff --git a/boost/geometry/formulas/meridian_direct.hpp b/boost/geometry/formulas/meridian_direct.hpp
index e55b35e88f..f8e73f57c6 100644
--- a/boost/geometry/formulas/meridian_direct.hpp
+++ b/boost/geometry/formulas/meridian_direct.hpp
@@ -3,6 +3,7 @@
// Copyright (c) 2018 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -15,14 +16,15 @@
#include <boost/geometry/core/radius.hpp>
-#include <boost/geometry/util/condition.hpp>
-#include <boost/geometry/util/math.hpp>
-
-#include <boost/geometry/formulas/meridian_inverse.hpp>
+#include <boost/geometry/formulas/differential_quantities.hpp>
#include <boost/geometry/formulas/flattening.hpp>
+#include <boost/geometry/formulas/meridian_inverse.hpp>
#include <boost/geometry/formulas/quarter_meridian.hpp>
#include <boost/geometry/formulas/result_direct.hpp>
+#include <boost/geometry/util/condition.hpp>
+#include <boost/geometry/util/math.hpp>
+
namespace boost { namespace geometry { namespace formula
{
diff --git a/boost/geometry/formulas/meridian_segment.hpp b/boost/geometry/formulas/meridian_segment.hpp
index 535e31e3db..0aa7542f91 100644
--- a/boost/geometry/formulas/meridian_segment.hpp
+++ b/boost/geometry/formulas/meridian_segment.hpp
@@ -1,8 +1,9 @@
// Boost.Geometry
-// Copyright (c) 2017 Oracle and/or its affiliates.
+// Copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -14,7 +15,6 @@
#include <boost/math/constants/constants.hpp>
#include <boost/geometry/core/radius.hpp>
-#include <boost/geometry/srs/srs.hpp>
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/math.hpp>
diff --git a/boost/geometry/formulas/quarter_meridian.hpp b/boost/geometry/formulas/quarter_meridian.hpp
index 2f93f53cf6..5aa10cc870 100644
--- a/boost/geometry/formulas/quarter_meridian.hpp
+++ b/boost/geometry/formulas/quarter_meridian.hpp
@@ -3,6 +3,7 @@
// Copyright (c) 2018 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -11,11 +12,15 @@
#ifndef BOOST_GEOMETRY_FORMULAS_QUARTER_MERIDIAN_HPP
#define BOOST_GEOMETRY_FORMULAS_QUARTER_MERIDIAN_HPP
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
#include <boost/geometry/core/radius.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
-#include <boost/geometry/algorithms/not_implemented.hpp>
+#include <boost/geometry/formulas/flattening.hpp>
+
+#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/formulas/spherical.hpp b/boost/geometry/formulas/spherical.hpp
index 5599cd6e81..964e2de302 100644
--- a/boost/geometry/formulas/spherical.hpp
+++ b/boost/geometry/formulas/spherical.hpp
@@ -13,6 +13,7 @@
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/radius.hpp>
@@ -98,7 +99,7 @@ static inline PointSph cart3d_to_sph(Point3d const& point_3d)
math::normalize_spheroidal_coordinates
<
- typename coordinate_system<PointSph>::type::units,
+ typename detail::cs_angular_units<PointSph>::type,
coord_t
>(lon, lat);
@@ -183,6 +184,7 @@ inline T spherical_azimuth(T const& lon1, T const& lat1, T const& lon2, T const&
template <typename T>
inline int azimuth_side_value(T const& azi_a1_p, T const& azi_a1_a2)
{
+ T const c0 = 0;
T const pi = math::pi<T>();
T const two_pi = math::two_pi<T>();
@@ -213,7 +215,7 @@ inline int azimuth_side_value(T const& azi_a1_p, T const& azi_a1_a2)
// the difference to 0 as well
// positive azimuth is on the right side
- return math::equals(a_diff, 0)
+ return math::equals(a_diff, c0)
|| math::equals(a_diff, pi)
|| math::equals(a_diff, -pi) ? 0
: a_diff > 0 ? -1 // right
diff --git a/boost/geometry/formulas/thomas_direct.hpp b/boost/geometry/formulas/thomas_direct.hpp
index 830f256a6e..7b61616af6 100644
--- a/boost/geometry/formulas/thomas_direct.hpp
+++ b/boost/geometry/formulas/thomas_direct.hpp
@@ -67,13 +67,6 @@ public:
CT const lon1 = lo1;
CT const lat1 = la1;
- if ( math::equals(distance, Dist(0)) || distance < Dist(0) )
- {
- result.lon2 = lon1;
- result.lat2 = lat1;
- return result;
- }
-
CT const c0 = 0;
CT const c1 = 1;
CT const c2 = 2;
diff --git a/boost/geometry/formulas/vincenty_direct.hpp b/boost/geometry/formulas/vincenty_direct.hpp
index b72379defe..2806de04cd 100644
--- a/boost/geometry/formulas/vincenty_direct.hpp
+++ b/boost/geometry/formulas/vincenty_direct.hpp
@@ -74,13 +74,6 @@ public:
CT const lon1 = lo1;
CT const lat1 = la1;
- if ( math::equals(distance, Dist(0)) || distance < Dist(0) )
- {
- result.lon2 = lon1;
- result.lat2 = lat1;
- return result;
- }
-
CT const radius_a = CT(get_radius<0>(spheroid));
CT const radius_b = CT(get_radius<2>(spheroid));
CT const flattening = formula::flattening<CT>(spheroid);
diff --git a/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp b/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp
index 84f72aadcb..ca54ec6afe 100644
--- a/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp
+++ b/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp
@@ -2,6 +2,11 @@
// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018, 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)
@@ -14,9 +19,11 @@
// pair{begin_points, end_points} -> ring_proxy
#include <boost/polygon/polygon.hpp>
-#include <boost/range.hpp>
-
+#include <boost/range/const_iterator.hpp>
+#include <boost/range/mutable_iterator.hpp>
+#include <boost/geometry/core/mutable_range.hpp>
+#include <boost/geometry/core/tag.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/geometries/adapted/boost_tuple.hpp b/boost/geometry/geometries/adapted/boost_tuple.hpp
index 58065fe9af..88d1af37b8 100644
--- a/boost/geometry/geometries/adapted/boost_tuple.hpp
+++ b/boost/geometry/geometries/adapted/boost_tuple.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -19,6 +24,7 @@
#include <boost/tuple/tuple.hpp>
+#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/point_type.hpp>
diff --git a/boost/geometry/geometries/adapted/std_array.hpp b/boost/geometry/geometries/adapted/std_array.hpp
index 4f5cbe0d32..ede9fe9974 100644
--- a/boost/geometry/geometries/adapted/std_array.hpp
+++ b/boost/geometry/geometries/adapted/std_array.hpp
@@ -12,6 +12,12 @@
#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_STD_ARRAY_HPP
+#include <boost/config.hpp>
+
+
+#ifndef BOOST_NO_CXX11_HDR_ARRAY
+
+
#define BOOST_GEOMETRY_ADAPTED_STD_ARRAY_TAG_DEFINED
@@ -111,5 +117,14 @@ struct access<std::array<CoordinateType, DimensionCount>, Dimension>
}}}
+#else
+
+
+#warning "This file requires compiler and library support for the ISO C++ 2011 standard."
+
+
+#endif // BOOST_NO_CXX11_HDR_ARRAY
+
+
#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_STD_ARRAY_HPP
diff --git a/boost/geometry/geometries/concepts/multi_point_concept.hpp b/boost/geometry/geometries/concepts/multi_point_concept.hpp
index 9e205f1635..9dffdb1c41 100644
--- a/boost/geometry/geometries/concepts/multi_point_concept.hpp
+++ b/boost/geometry/geometries/concepts/multi_point_concept.hpp
@@ -20,6 +20,7 @@
#include <boost/range/concepts.hpp>
#include <boost/range/metafunctions.hpp>
+#include <boost/geometry/core/mutable_range.hpp>
#include <boost/geometry/geometries/concepts/point_concept.hpp>
diff --git a/boost/geometry/geometries/helper_geometry.hpp b/boost/geometry/geometries/helper_geometry.hpp
index f3102fee93..e110dd2b1b 100644
--- a/boost/geometry/geometries/helper_geometry.hpp
+++ b/boost/geometry/geometries/helper_geometry.hpp
@@ -32,60 +32,6 @@ namespace boost { namespace geometry
namespace detail { namespace helper_geometries
{
-template <typename Geometry, typename CS_Tag = typename cs_tag<Geometry>::type>
-struct default_units
-{
- typedef typename coordinate_system<Geometry>::type::units type;
-};
-
-// The Cartesian coordinate system does not define the type units.
-// For that reason the generic implementation for default_units cannot be used
-// and specialization needs to be defined.
-// Moreover, it makes sense to define the units for the Cartesian
-// coordinate system to be radians, as this way a Cartesian point can
-// potentially be used in algorithms taking non-Cartesian strategies
-// and work as if it was as point in the non-Cartesian coordinate
-// system with radian units.
-template <typename Geometry>
-struct default_units<Geometry, cartesian_tag>
-{
- typedef radian type;
-};
-
-
-template <typename Units, typename CS_Tag>
-struct cs_tag_to_coordinate_system
-{
- BOOST_MPL_ASSERT_MSG((false),
- NOT_IMPLEMENTED_FOR_THIS_COORDINATE_SYSTEM,
- (types<CS_Tag>));
-};
-
-template <typename Units>
-struct cs_tag_to_coordinate_system<Units, cartesian_tag>
-{
- typedef cs::cartesian type;
-};
-
-template <typename Units>
-struct cs_tag_to_coordinate_system<Units, spherical_equatorial_tag>
-{
- typedef cs::spherical_equatorial<Units> type;
-};
-
-template <typename Units>
-struct cs_tag_to_coordinate_system<Units, spherical_polar_tag>
-{
- typedef cs::spherical<Units> type;
-};
-
-template <typename Units>
-struct cs_tag_to_coordinate_system<Units, geographic_tag>
-{
- typedef cs::geographic<Units> type;
-};
-
-
template
<
typename Point,
@@ -154,10 +100,7 @@ template
<
typename Geometry,
typename NewCoordinateType = typename coordinate_type<Geometry>::type,
- typename NewUnits = typename detail::helper_geometries::default_units
- <
- Geometry
- >::type
+ typename NewUnits = typename detail::cs_angular_units<Geometry>::type
>
struct helper_geometry
{
diff --git a/boost/geometry/geometries/variant.hpp b/boost/geometry/geometries/variant.hpp
index 881eab9c8b..6b19c113d2 100644
--- a/boost/geometry/geometries/variant.hpp
+++ b/boost/geometry/geometries/variant.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -15,8 +20,10 @@
#define BOOST_GEOMETRY_GEOMETRIES_VARIANT_GEOMETRY_HPP
-#include <boost/variant/variant_fwd.hpp>
#include <boost/mpl/front.hpp>
+#include <boost/variant/variant_fwd.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
namespace boost { namespace geometry {
diff --git a/boost/geometry/geometry.hpp b/boost/geometry/geometry.hpp
index 0957d48a29..5c2c58e4cb 100644
--- a/boost/geometry/geometry.hpp
+++ b/boost/geometry/geometry.hpp
@@ -76,6 +76,7 @@
#include <boost/geometry/algorithms/is_simple.hpp>
#include <boost/geometry/algorithms/is_valid.hpp>
#include <boost/geometry/algorithms/length.hpp>
+#include <boost/geometry/algorithms/line_interpolate.hpp>
#include <boost/geometry/algorithms/make.hpp>
#include <boost/geometry/algorithms/num_geometries.hpp>
#include <boost/geometry/algorithms/num_interior_rings.hpp>
diff --git a/boost/geometry/index/detail/algorithms/intersection_content.hpp b/boost/geometry/index/detail/algorithms/intersection_content.hpp
index 437f90b46c..b8ef9e7163 100644
--- a/boost/geometry/index/detail/algorithms/intersection_content.hpp
+++ b/boost/geometry/index/detail/algorithms/intersection_content.hpp
@@ -2,7 +2,7 @@
//
// boxes union/intersection area/volume
//
-// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -24,7 +24,12 @@ namespace boost { namespace geometry { namespace index { namespace detail {
template <typename Box>
inline typename default_content_result<Box>::type intersection_content(Box const& box1, Box const& box2)
{
- bool const intersects = ! geometry::detail::disjoint::box_box<Box, Box>::apply(box1, box2);
+ typedef typename strategy::disjoint::services::default_strategy
+ <
+ Box, Box
+ >::type strategy_type;
+
+ bool const intersects = ! geometry::detail::disjoint::disjoint_box_box(box1, box2, strategy_type());
if ( intersects )
{
diff --git a/boost/geometry/index/detail/meta.hpp b/boost/geometry/index/detail/meta.hpp
index bec1380b06..10118ade7c 100644
--- a/boost/geometry/index/detail/meta.hpp
+++ b/boost/geometry/index/detail/meta.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry Index
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2019 Adam Wulkiewicz, Lodz, Poland.
//
// 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,7 +10,8 @@
#include <boost/mpl/aux_/has_type.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
-//#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/is_same.hpp>
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_META_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_META_HPP
@@ -37,6 +38,68 @@ struct is_range
// : is_range_of_convertible_values_impl<T, V, is_range<T>::value>
//{};
+// Implemented this way in order to prevent instantiation of all type traits at
+// once because some of them are causing problems with gcc 4.6 namely
+// is_convertible<bg::model::segment<>, std::pair<bg::model::segment<>, T> >
+// because segment<> is derived from pair<> and pair<> has copy ctor taking
+// other pair<> of any types the compiler tries to instantiate ctor of
+// pair<segment, T> taking pair<point, point> which results in instantiation of
+// segment's ctor taking a point which results in compilation error.
+// This is probably compiler's bug.
+template <typename T, typename Value, typename Indexable, typename ResultType, int Ver>
+struct convertible_type_impl
+{
+ typedef ResultType type;
+};
+
+template <typename T, typename Value, typename Indexable>
+struct convertible_type_impl<T, Value, Indexable, void, 0>
+{
+ typedef typename boost::mpl::if_c
+ <
+ boost::is_convertible<T, Indexable>::value,
+ Indexable,
+ void
+ >::type result_type;
+
+ typedef typename convertible_type_impl
+ <
+ T, Value, Indexable, result_type, 1
+ >::type type;
+};
+
+template <typename T, typename Value, typename Indexable>
+struct convertible_type_impl<T, Value, Indexable, void, 1>
+{
+ typedef typename boost::mpl::if_c
+ <
+ boost::is_convertible<T, Value>::value,
+ Value,
+ void
+ >::type type;
+};
+
+template <typename T, typename Value, typename Indexable>
+struct convertible_type
+{
+ typedef typename boost::mpl::if_c
+ <
+ boost::is_same<T, Value>::value,
+ Value,
+ typename boost::mpl::if_c
+ <
+ boost::is_same<T, Indexable>::value,
+ Indexable,
+ void
+ >::type
+ >::type result_type;
+
+ typedef typename convertible_type_impl
+ <
+ T, Value, Indexable, result_type, 0
+ >::type type;
+};
+
}}}} // namespace boost::geometry::index::detail
#endif // BOOST_GEOMETRY_INDEX_DETAIL_META_HPP
diff --git a/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp b/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp
index e07926ffed..2ac6eb27c9 100644
--- a/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp
+++ b/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp
@@ -2,7 +2,7 @@
//
// R-tree R*-tree next node choosing algorithm implementation
//
-// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2019 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -65,6 +65,20 @@ public:
}
private:
+ struct child_contents
+ {
+ content_type content_diff;
+ content_type content;
+ size_t i;
+
+ void set(size_t i_, content_type const& content_, content_type const& content_diff_)
+ {
+ i = i_;
+ content = content_;
+ content_diff = content_diff_;
+ }
+ };
+
template <typename Indexable>
static inline size_t choose_by_minimum_overlap_cost(children_type const& children,
Indexable const& indexable,
@@ -77,10 +91,8 @@ private:
size_t choosen_index = 0;
// create container of children sorted by content enlargement needed to include the new value
- typedef boost::tuple<size_t, content_type, content_type> child_contents;
-
- typename rtree::container_from_elements_type<children_type, child_contents>::type children_contents;
- children_contents.resize(children_count);
+ typename rtree::container_from_elements_type<children_type, child_contents>::type
+ children_contents(children_count);
for ( size_t i = 0 ; i < children_count ; ++i )
{
@@ -94,7 +106,7 @@ private:
content_type content = index::detail::content(box_exp);
content_type content_diff = content - index::detail::content(ch_i.first);
- children_contents[i] = boost::make_tuple(i, content_diff, content);
+ children_contents[i].set(i, content, content_diff);
if ( content_diff < min_content_diff ||
(content_diff == min_content_diff && content < min_content) )
@@ -125,10 +137,10 @@ private:
return choosen_index;
}
- static inline bool content_diff_less(boost::tuple<size_t, content_type, content_type> const& p1, boost::tuple<size_t, content_type, content_type> const& p2)
+ static inline bool content_diff_less(child_contents const& p1, child_contents const& p2)
{
- return boost::get<1>(p1) < boost::get<1>(p2) ||
- (boost::get<1>(p1) == boost::get<1>(p2) && boost::get<2>(p1) < boost::get<2>(p2));
+ return p1.content_diff < p2.content_diff
+ || (p1.content_diff == p2.content_diff && (p1.content) < (p2.content));
}
template <typename Indexable, typename ChildrenContents>
@@ -148,8 +160,12 @@ private:
content_type smallest_content = (std::numeric_limits<content_type>::max)();
// for each child node
- for (size_t i = 0 ; i < first_n_children_count ; ++i )
+ for (size_t first_i = 0 ; first_i < first_n_children_count ; ++first_i)
{
+ size_t i = children_contents[first_i].i;
+ content_type const& content = children_contents[first_i].content;
+ content_type const& content_diff = children_contents[first_i].content_diff;
+
child_type const& ch_i = children[i];
Box box_exp(ch_i.first);
@@ -173,9 +189,6 @@ private:
}
}
- content_type content = boost::get<2>(children_contents[i]);
- content_type content_diff = boost::get<1>(children_contents[i]);
-
// update result
if ( overlap_diff < smallest_overlap_diff ||
( overlap_diff == smallest_overlap_diff && ( content_diff < smallest_content_diff ||
diff --git a/boost/geometry/index/indexable.hpp b/boost/geometry/index/indexable.hpp
index 831e17f6dd..eee4e1d211 100644
--- a/boost/geometry/index/indexable.hpp
+++ b/boost/geometry/index/indexable.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry Index
//
-// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2019 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -11,11 +11,43 @@
#include <boost/mpl/assert.hpp>
#include <boost/tuple/tuple.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
#include <boost/geometry/index/detail/is_indexable.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
+template <typename T>
+struct remove_cr
+ : boost::remove_const
+ <
+ typename boost::remove_reference<T>::type
+ >
+{};
+
+template <typename From, typename To>
+struct is_referencable
+ : boost::is_same
+ <
+ typename remove_cr<From>::type,
+ typename remove_cr<To>::type
+ >
+{};
+
+template <typename Indexable, typename V>
+inline Indexable const& indexable_prevent_any_type(V const& )
+{
+ BOOST_MPL_ASSERT_MSG(
+ (false),
+ UNEXPECTED_TYPE,
+ (V)
+ );
+ return Indexable();
+}
+
/*!
\brief The function object extracting Indexable from Value.
@@ -48,6 +80,15 @@ struct indexable
{
return v;
}
+
+ /*!
+ \brief Prevent reference to temporary for types convertible to Value.
+ */
+ template <typename V>
+ inline result_type operator()(V const& v) const
+ {
+ return indexable_prevent_any_type<Value>(v);
+ }
};
/*!
@@ -56,11 +97,13 @@ struct indexable
This specialization translates from std::pair<Indexable, T2>.
\tparam Indexable The Indexable type.
-\tparam T2 The second type.
+\tparam Second The second type.
*/
-template <typename Indexable, typename T2>
-struct indexable<std::pair<Indexable, T2>, false>
+template <typename Indexable, typename Second>
+struct indexable<std::pair<Indexable, Second>, false>
{
+ typedef std::pair<Indexable, Second> value_type;
+
BOOST_MPL_ASSERT_MSG(
(detail::is_indexable<Indexable>::value),
NOT_VALID_INDEXABLE_TYPE,
@@ -76,24 +119,51 @@ struct indexable<std::pair<Indexable, T2>, false>
\param v The value.
\return The indexable.
*/
- inline result_type operator()(std::pair<Indexable, T2> const& v) const
+ inline result_type operator()(value_type const& v) const
{
return v.first;
}
+
+ /*!
+ \brief Return indexable extracted from compatible type different than value_type.
+
+ \param v The value.
+ \return The indexable.
+ */
+ template <typename I, typename S>
+ inline result_type operator()(std::pair<I, S> const& v) const
+ {
+ BOOST_MPL_ASSERT_MSG(
+ (is_referencable<I, result_type>::value),
+ UNEXPECTED_TYPE,
+ (std::pair<I, S>)
+ );
+ return v.first;
+ }
+
+ /*!
+ \brief Prevent reference to temporary for types convertible to Value.
+ */
+ template <typename V>
+ inline result_type operator()(V const& v) const
+ {
+ return indexable_prevent_any_type<Indexable>(v);
+ }
};
/*!
\brief The function object extracting Indexable from Value.
-This specialization translates from boost::tuple<Indexable, ...>.
+This specialization translates from boost::tuple<Indexable, ...>
+ or boost::tuples::cons<Indexable, ...>.
+\tparam Value The Value type.
\tparam Indexable The Indexable type.
*/
-template <typename Indexable, typename T1, typename T2, typename T3, typename T4,
- typename T5, typename T6, typename T7, typename T8, typename T9>
-struct indexable<boost::tuple<Indexable, T1, T2, T3, T4, T5, T6, T7, T8, T9>, false>
+template <typename Value, typename Indexable>
+struct indexable_boost_tuple
{
- typedef boost::tuple<Indexable, T1, T2, T3, T4, T5, T6, T7, T8, T9> value_type;
+ typedef Value value_type;
BOOST_MPL_ASSERT_MSG(
(detail::is_indexable<Indexable>::value),
@@ -114,8 +184,85 @@ struct indexable<boost::tuple<Indexable, T1, T2, T3, T4, T5, T6, T7, T8, T9>, fa
{
return boost::get<0>(v);
}
+
+ /*!
+ \brief Return indexable extracted from compatible type different than value_type.
+
+ \param v The value.
+ \return The indexable.
+ */
+ template <typename I, typename U1, typename U2, typename U3, typename U4,
+ typename U5, typename U6, typename U7, typename U8, typename U9>
+ inline result_type operator()(boost::tuple<I, U1, U2, U3, U4, U5, U6, U7, U8, U9> const& v) const
+ {
+ BOOST_MPL_ASSERT_MSG(
+ (is_referencable<I, result_type>::value),
+ UNEXPECTED_TYPE,
+ (boost::tuple<I, U1, U2, U3, U4, U5, U6, U7, U8, U9>)
+ );
+ return boost::get<0>(v);
+ }
+
+ /*!
+ \brief Return indexable extracted from compatible type different than value_type.
+
+ \param v The value.
+ \return The indexable.
+ */
+ template <typename I, typename T>
+ inline result_type operator()(boost::tuples::cons<I, T> const& v) const
+ {
+ BOOST_MPL_ASSERT_MSG(
+ (is_referencable<I, result_type>::value),
+ UNEXPECTED_TYPE,
+ (boost::tuples::cons<I, T>)
+ );
+ return boost::get<0>(v);
+ }
+
+ /*!
+ \brief Prevent reference to temporary for types convertible to Value.
+ */
+ template <typename V>
+ inline result_type operator()(V const& v) const
+ {
+ return indexable_prevent_any_type<Indexable>(v);
+ }
};
+/*!
+\brief The function object extracting Indexable from Value.
+
+This specialization translates from boost::tuple<Indexable, ...>.
+
+\tparam Indexable The Indexable type.
+*/
+template <typename Indexable, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6, typename T7, typename T8, typename T9>
+struct indexable<boost::tuple<Indexable, T1, T2, T3, T4, T5, T6, T7, T8, T9>, false>
+ : indexable_boost_tuple
+ <
+ boost::tuple<Indexable, T1, T2, T3, T4, T5, T6, T7, T8, T9>,
+ Indexable
+ >
+{};
+
+/*!
+\brief The function object extracting Indexable from Value.
+
+This specialization translates from boost::tuples::cons<Indexable, ...>.
+
+\tparam Indexable The Indexable type.
+*/
+template <typename Indexable, typename Tail>
+struct indexable<boost::tuples::cons<Indexable, Tail>, false>
+ : indexable_boost_tuple
+ <
+ boost::tuples::cons<Indexable, Tail>,
+ Indexable
+ >
+{};
+
}}}} // namespace boost::geometry::index::detail
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
@@ -156,6 +303,32 @@ struct indexable<std::tuple<Indexable, Args...>, false>
{
return std::get<0>(v);
}
+
+ /*!
+ \brief Return indexable extracted from compatible type different than value_type.
+
+ \param v The value.
+ \return The indexable.
+ */
+ template <typename I, typename ...A>
+ inline result_type operator()(std::tuple<I, A...> const& v) const
+ {
+ BOOST_MPL_ASSERT_MSG(
+ (is_referencable<I, result_type>::value),
+ UNEXPECTED_TYPE,
+ (std::tuple<I, A...>)
+ );
+ return std::get<0>(v);
+ }
+
+ /*!
+ \brief Prevent reference to temporary for types convertible to Value.
+ */
+ template <typename V>
+ inline result_type operator()(V const& v) const
+ {
+ return indexable_prevent_any_type<Indexable>(v);
+ }
};
}}}} // namespace boost::geometry::index::detail
@@ -190,6 +363,20 @@ struct indexable
{
return detail::indexable<Value>::operator()(v);
}
+
+ /*!
+ \brief Return indexable extracted from the value. Overload for types
+ compatible with Value but different yet holding referencable
+ Indexable, e.g. tuple containing a reference.
+
+ \param v The value.
+ \return The indexable.
+ */
+ template <typename V>
+ inline result_type operator()(V const& v) const
+ {
+ return detail::indexable<Value>::operator()(v);
+ }
};
}}} // namespace boost::geometry::index
diff --git a/boost/geometry/index/rtree.hpp b/boost/geometry/index/rtree.hpp
index 53c2661669..1a8be031dc 100644
--- a/boost/geometry/index/rtree.hpp
+++ b/boost/geometry/index/rtree.hpp
@@ -3,7 +3,7 @@
// R-tree implementation
//
// Copyright (c) 2008 Federico J. Fernandez.
-// Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2019 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -1296,32 +1296,18 @@ public:
return 0;
// the input should be convertible to Value or Indexable type
-
- enum { as_val = 0, as_ind, dont_know };
- typedef boost::mpl::int_
- <
- boost::is_same<ValueOrIndexable, value_type>::value ?
- as_val :
- boost::is_same<ValueOrIndexable, indexable_type>::value ?
- as_ind :
- boost::is_convertible<ValueOrIndexable, indexable_type>::value ?
- as_ind :
- boost::is_convertible<ValueOrIndexable, value_type>::value ?
- as_val :
- dont_know
- > variant;
-
- BOOST_MPL_ASSERT_MSG((variant::value != dont_know),
- PASSED_OBJECT_NOT_CONVERTIBLE_TO_VALUE_NOR_INDEXABLE_TYPE,
- (ValueOrIndexable));
-
- typedef typename boost::mpl::if_c
+ typedef typename index::detail::convertible_type
<
- variant::value == as_val,
+ ValueOrIndexable,
value_type,
indexable_type
>::type value_or_indexable;
+ static const bool is_void = boost::is_same<value_or_indexable, void>::value;
+ BOOST_MPL_ASSERT_MSG((! is_void),
+ PASSED_OBJECT_NOT_CONVERTIBLE_TO_VALUE_NOR_INDEXABLE_TYPE,
+ (ValueOrIndexable));
+
// NOTE: If an object of convertible but not the same type is passed
// into the function, here a temporary will be created.
return this->template raw_count<value_or_indexable>(vori);
diff --git a/boost/geometry/io/wkt/read.hpp b/boost/geometry/io/wkt/read.hpp
index 9caa36cb47..414024b461 100644
--- a/boost/geometry/io/wkt/read.hpp
+++ b/boost/geometry/io/wkt/read.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2014, 2015.
-// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2015, 2018.
+// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -39,7 +39,7 @@
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/append.hpp>
#include <boost/geometry/algorithms/clear.hpp>
-#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
+#include <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
@@ -295,7 +295,7 @@ struct stateful_range_appender<Geometry, open>
should_append
= is_next_expected
|| pt_index < core_detail::closure::minimum_ring_size<open>::value
- || !detail::equals::equals_point_point(point, first_point);
+ || disjoint(point, first_point);
}
++pt_index;
@@ -306,6 +306,17 @@ struct stateful_range_appender<Geometry, open>
}
private:
+ static inline bool disjoint(point_type const& p1, point_type const& p2)
+ {
+ // TODO: pass strategy
+ typedef typename strategy::disjoint::services::default_strategy
+ <
+ point_type, point_type
+ >::type strategy_type;
+
+ return detail::disjoint::disjoint_point_point(p1, p2, strategy_type());
+ }
+
size_type pt_index;
point_type first_point;
};
diff --git a/boost/geometry/io/wkt/write.hpp b/boost/geometry/io/wkt/write.hpp
index 34af432fc6..62d1d6cb44 100644
--- a/boost/geometry/io/wkt/write.hpp
+++ b/boost/geometry/io/wkt/write.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2017 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -162,7 +162,7 @@ struct wkt_range
if (ForceClosurePossible
&& force_closure
&& boost::size(range) > 1
- && detail::disjoint::disjoint_point_point(*begin, *(end - 1)))
+ && wkt_range::disjoint(*begin, *(end - 1)))
{
os << ",";
stream_type::apply(os, *begin);
@@ -174,6 +174,17 @@ struct wkt_range
private:
typedef typename boost::range_value<Range>::type point_type;
+
+ static inline bool disjoint(point_type const& p1, point_type const& p2)
+ {
+ // TODO: pass strategy
+ typedef typename strategy::disjoint::services::default_strategy
+ <
+ point_type, point_type
+ >::type strategy_type;
+
+ return detail::disjoint::disjoint_point_point(p1, p2, strategy_type());
+ }
};
/*!
diff --git a/boost/geometry/iterators/detail/point_iterator/iterator_type.hpp b/boost/geometry/iterators/detail/point_iterator/iterator_type.hpp
index a7805b127b..92c0c093c9 100644
--- a/boost/geometry/iterators/detail/point_iterator/iterator_type.hpp
+++ b/boost/geometry/iterators/detail/point_iterator/iterator_type.hpp
@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014, Oracle and/or its affiliates.
+// Copyright (c) 2014, 2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -12,6 +13,7 @@
#include <boost/range.hpp>
+#include <boost/geometry/core/interior_type.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
diff --git a/boost/geometry/policies/robustness/get_rescale_policy.hpp b/boost/geometry/policies/robustness/get_rescale_policy.hpp
index daf32d3057..9bb3f885a7 100644
--- a/boost/geometry/policies/robustness/get_rescale_policy.hpp
+++ b/boost/geometry/policies/robustness/get_rescale_policy.hpp
@@ -25,6 +25,7 @@
#include <boost/type_traits/is_same.hpp>
#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/config.hpp>
#include <boost/geometry/core/tag_cast.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
@@ -249,9 +250,7 @@ struct rescale_policy_type
: public detail::get_rescale_policy::rescale_policy_type
<
Point,
-#if defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
- false
-#else
+#if defined(BOOST_GEOMETRY_USE_RESCALING)
boost::is_floating_point
<
typename geometry::coordinate_type<Point>::type
@@ -262,6 +261,8 @@ struct rescale_policy_type
typename geometry::coordinate_system<Point>::type,
geometry::cs::cartesian
>::value
+#else
+ false
#endif
>
{
diff --git a/boost/geometry/policies/robustness/rescale_policy.hpp b/boost/geometry/policies/robustness/rescale_policy.hpp
index b92f6e1ec7..e4a9090567 100644
--- a/boost/geometry/policies/robustness/rescale_policy.hpp
+++ b/boost/geometry/policies/robustness/rescale_policy.hpp
@@ -5,7 +5,8 @@
// Copyright (c) 2014-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
-// Copyright (c) 2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -18,6 +19,8 @@
#include <cstddef>
+#include <boost/geometry/core/coordinate_type.hpp>
+
#include <boost/geometry/policies/robustness/segment_ratio.hpp>
#include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
#include <boost/geometry/policies/robustness/robust_point_type.hpp>
diff --git a/boost/geometry/srs/projections/dpar.hpp b/boost/geometry/srs/projections/dpar.hpp
index 641a4fc6e9..0cfb2e2103 100644
--- a/boost/geometry/srs/projections/dpar.hpp
+++ b/boost/geometry/srs/projections/dpar.hpp
@@ -22,11 +22,16 @@
#include <boost/mpl/assert.hpp>
#include <boost/mpl/if.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/size.hpp>
+#include <boost/range/value_type.hpp>
#include <boost/tuple/tuple.hpp>
-#include <boost/variant/variant.hpp>
#include <boost/type_traits/integral_constant.hpp>
+#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_void.hpp>
+#include <boost/variant/variant.hpp>
#include <string>
#include <vector>
diff --git a/boost/geometry/srs/projections/impl/aasincos.hpp b/boost/geometry/srs/projections/impl/aasincos.hpp
index de064f6a01..b12b5f65ba 100644
--- a/boost/geometry/srs/projections/impl/aasincos.hpp
+++ b/boost/geometry/srs/projections/impl/aasincos.hpp
@@ -42,6 +42,8 @@
#include <cmath>
+#include <boost/geometry/srs/projections/exception.hpp>
+#include <boost/geometry/srs/projections/impl/pj_strerrno.hpp>
#include <boost/geometry/util/math.hpp>
diff --git a/boost/geometry/srs/projections/impl/dms_parser.hpp b/boost/geometry/srs/projections/impl/dms_parser.hpp
index fabc558f61..ee9c8db3d1 100644
--- a/boost/geometry/srs/projections/impl/dms_parser.hpp
+++ b/boost/geometry/srs/projections/impl/dms_parser.hpp
@@ -42,9 +42,9 @@
#include <string>
#include <boost/algorithm/string.hpp>
-#include <boost/config.hpp>
#include <boost/static_assert.hpp>
+#include <boost/geometry/core/config.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/srs/projections/str_cast.hpp>
#include <boost/geometry/util/math.hpp>
@@ -123,7 +123,7 @@ struct dms_parser
bool has_dms[3];
dms_value()
-#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && (!defined(_MSC_VER) || (_MSC_VER >= 1900)) // workaround for VC++ 12 (aka 2013)
+#ifdef BOOST_GEOMETRY_CXX11_ARRAY_UNIFIED_INITIALIZATION
: dms{0, 0, 0}
, has_dms{false, false, false}
{}
diff --git a/boost/geometry/srs/projections/impl/pj_apply_gridshift.hpp b/boost/geometry/srs/projections/impl/pj_apply_gridshift.hpp
index ee3aa6ed23..e56fecc8b2 100644
--- a/boost/geometry/srs/projections/impl/pj_apply_gridshift.hpp
+++ b/boost/geometry/srs/projections/impl/pj_apply_gridshift.hpp
@@ -1,8 +1,8 @@
// Boost.Geometry
// This file is manually converted from PROJ4
-// This file was modified by Oracle on 2018.
-// Modifications copyright (c) 2018, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2018, 2019.
+// Modifications copyright (c) 2018-2019, 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,
@@ -44,8 +44,12 @@
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/srs/projections/impl/adjlon.hpp>
+#include <boost/geometry/srs/projections/impl/function_overloads.hpp>
#include <boost/geometry/srs/projections/impl/pj_gridlist.hpp>
+#include <boost/geometry/util/range.hpp>
+
namespace boost { namespace geometry { namespace projections
{
@@ -388,7 +392,7 @@ inline bool pj_apply_gridshift_3(StreamPolicy const& stream_policy,
/************************************************************************/
template <bool Inverse, typename Par, typename Range, typename ProjGrids>
-inline bool pj_apply_gridshift_2(Par const& defn, Range & range, ProjGrids const& grids)
+inline bool pj_apply_gridshift_2(Par const& /*defn*/, Range & range, ProjGrids const& grids)
{
/*if( defn->catalog_name != NULL )
return pj_gc_apply_gridshift( defn, inverse, point_count, point_offset,
diff --git a/boost/geometry/srs/projections/impl/pj_apply_gridshift_shared.hpp b/boost/geometry/srs/projections/impl/pj_apply_gridshift_shared.hpp
index 2f0d63169e..c83c1bc515 100644
--- a/boost/geometry/srs/projections/impl/pj_apply_gridshift_shared.hpp
+++ b/boost/geometry/srs/projections/impl/pj_apply_gridshift_shared.hpp
@@ -1,8 +1,8 @@
// Boost.Geometry
// This file is manually converted from PROJ4
-// This file was modified by Oracle on 2018.
-// Modifications copyright (c) 2018, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2018, 2019.
+// Modifications copyright (c) 2018-2019, 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,
@@ -57,7 +57,7 @@ namespace detail
template <bool Inverse, typename CalcT, typename StreamPolicy, typename Range>
inline bool pj_apply_gridshift_3(StreamPolicy const& stream_policy,
Range & range,
- srs::shared_grids & grids,
+ shared_grids & grids,
std::vector<std::size_t> const& gridindexes)
{
typedef typename boost::range_size<Range>::type size_type;
diff --git a/boost/geometry/srs/projections/impl/pj_datum_set.hpp b/boost/geometry/srs/projections/impl/pj_datum_set.hpp
index fee5eca906..1b651d0826 100644
--- a/boost/geometry/srs/projections/impl/pj_datum_set.hpp
+++ b/boost/geometry/srs/projections/impl/pj_datum_set.hpp
@@ -3,8 +3,8 @@
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2017, 2018.
-// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2017, 2018, 2019.
+// Modifications copyright (c) 2017-2019, 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,
@@ -135,7 +135,7 @@ template
struct pj_datum_find_datum_static
{
template <typename T>
- static const pj_datums_type<T>* apply(Params const& params)
+ static const pj_datums_type<T>* apply(Params const& )
{
const pj_datums_type<T>* pj_datums = pj_get_datums<T>().first;
const int n = pj_get_datums<T>().second;
@@ -225,7 +225,7 @@ struct pj_datum_find_nadgrids_static
{
static void apply(Params const& params, srs::detail::nadgrids & out)
{
- out = boost::tuples::get<I>();
+ out = boost::tuples::get<I>(params);
}
};
template <typename Params, int N>
@@ -322,7 +322,7 @@ struct pj_datum_find_towgs84_static
static void apply(Params const& params, srs::detail::towgs84<T> & out)
{
typename boost::tuples::element<I, Params>::type const&
- towgs84 = boost::tuples::get<I>();
+ towgs84 = boost::tuples::get<I>(params);
std::size_t n = (std::min<std::size_t>)(towgs84.size(), 7u);
std::size_t z = n <= 3 ? 3 : 7;
diff --git a/boost/geometry/srs/projections/impl/pj_ellps.hpp b/boost/geometry/srs/projections/impl/pj_ellps.hpp
index ae6c55457d..1a6f824eec 100644
--- a/boost/geometry/srs/projections/impl/pj_ellps.hpp
+++ b/boost/geometry/srs/projections/impl/pj_ellps.hpp
@@ -39,8 +39,6 @@
#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_ELLPS_HPP
#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_ELLPS_HPP
-#include <boost/geometry/srs/projections/impl/projects.hpp>
-
#include <string>
namespace boost { namespace geometry { namespace projections {
diff --git a/boost/geometry/srs/projections/impl/pj_gauss.hpp b/boost/geometry/srs/projections/impl/pj_gauss.hpp
index 94b8f89862..54d1778226 100644
--- a/boost/geometry/srs/projections/impl/pj_gauss.hpp
+++ b/boost/geometry/srs/projections/impl/pj_gauss.hpp
@@ -40,7 +40,8 @@
#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_GAUSS_HPP
-#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/srs/projections/constants.hpp>
+#include <boost/geometry/srs/projections/exception.hpp>
namespace boost { namespace geometry { namespace projections {
diff --git a/boost/geometry/srs/projections/impl/pj_gridinfo.hpp b/boost/geometry/srs/projections/impl/pj_gridinfo.hpp
index 8f244dc3c6..0d297b1cb8 100644
--- a/boost/geometry/srs/projections/impl/pj_gridinfo.hpp
+++ b/boost/geometry/srs/projections/impl/pj_gridinfo.hpp
@@ -1,8 +1,8 @@
// Boost.Geometry
// This file is manually converted from PROJ4
-// This file was modified by Oracle on 2018.
-// Modifications copyright (c) 2018, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2018, 2019.
+// Modifications copyright (c) 2018-2019, 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,
@@ -44,6 +44,7 @@
#include <boost/algorithm/string.hpp>
#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/util/math.hpp>
#include <boost/cstdint.hpp>
@@ -204,7 +205,7 @@ bool pj_gridinfo_load_ctable(IStream & is, pj_gi_load & gi)
std::size_t ch_size = sizeof(pj_ctable::flp_t) * a_size;
is.read(reinterpret_cast<char*>(&ct.cvs[0]), ch_size);
- if (is.fail() || is.gcount() != ch_size)
+ if (is.fail() || std::size_t(is.gcount()) != ch_size)
{
ct.cvs.clear();
//ctable loading failed on fread() - binary incompatible?
@@ -235,7 +236,7 @@ bool pj_gridinfo_load_ctable2(IStream & is, pj_gi_load & gi)
std::size_t ch_size = sizeof(pj_ctable::flp_t) * a_size;
is.read(reinterpret_cast<char*>(&ct.cvs[0]), ch_size);
- if (is.fail() || is.gcount() != ch_size)
+ if (is.fail() || std::size_t(is.gcount()) != ch_size)
{
//ctable2 loading failed on fread() - binary incompatible?
ct.cvs.clear();
@@ -278,7 +279,7 @@ inline bool pj_gridinfo_load_ntv1(IStream & is, pj_gi_load & gi)
{
is.read(reinterpret_cast<char*>(&row_buf[0]), ch_size);
- if (is.fail() || is.gcount() != ch_size)
+ if (is.fail() || std::size_t(is.gcount()) != ch_size)
{
gi.ct.cvs.clear();
return false;
@@ -328,7 +329,7 @@ inline bool pj_gridinfo_load_ntv2(IStream & is, pj_gi_load & gi)
{
is.read(reinterpret_cast<char*>(&row_buf[0]), ch_size);
- if (is.fail() || is.gcount() != ch_size)
+ if (is.fail() || std::size_t(is.gcount()) != ch_size)
{
gi.ct.cvs.clear();
return false;
@@ -375,7 +376,7 @@ inline bool pj_gridinfo_load_gtx(IStream & is, pj_gi_load & gi)
is.read(reinterpret_cast<char*>(&gi.ct.cvs[0]), ch_size);
- if (is.fail() || is.gcount() != ch_size)
+ if (is.fail() || std::size_t(is.gcount()) != ch_size)
{
gi.ct.cvs.clear();
return false;
diff --git a/boost/geometry/srs/projections/impl/pj_gridlist.hpp b/boost/geometry/srs/projections/impl/pj_gridlist.hpp
index 18a215b507..deccdd39fb 100644
--- a/boost/geometry/srs/projections/impl/pj_gridlist.hpp
+++ b/boost/geometry/srs/projections/impl/pj_gridlist.hpp
@@ -41,8 +41,11 @@
#define BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_GRIDLIST_HPP
+#include <boost/geometry/srs/projections/exception.hpp>
#include <boost/geometry/srs/projections/grids.hpp>
#include <boost/geometry/srs/projections/impl/pj_gridinfo.hpp>
+#include <boost/geometry/srs/projections/impl/pj_strerrno.hpp>
+#include <boost/geometry/srs/projections/par_data.hpp>
namespace boost { namespace geometry { namespace projections
diff --git a/boost/geometry/srs/projections/impl/pj_gridlist_shared.hpp b/boost/geometry/srs/projections/impl/pj_gridlist_shared.hpp
index 88753d034d..de8640a01f 100644
--- a/boost/geometry/srs/projections/impl/pj_gridlist_shared.hpp
+++ b/boost/geometry/srs/projections/impl/pj_gridlist_shared.hpp
@@ -1,8 +1,8 @@
// Boost.Geometry
// This file is manually converted from PROJ4
-// This file was modified by Oracle on 2018.
-// Modifications copyright (c) 2018, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2018, 2019.
+// Modifications copyright (c) 2018-2019, 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,
@@ -43,6 +43,7 @@
#include <boost/geometry/srs/projections/shared_grids.hpp>
#include <boost/geometry/srs/projections/impl/pj_gridinfo.hpp>
+#include <boost/geometry/srs/projections/impl/pj_gridlist.hpp>
namespace boost { namespace geometry { namespace projections
@@ -63,7 +64,7 @@ namespace detail
template <typename StreamPolicy>
inline bool pj_gridlist_merge_gridfile(std::string const& gridname,
StreamPolicy const& stream_policy,
- srs::shared_grids & grids,
+ shared_grids & grids,
std::vector<std::size_t> & gridindexes)
{
// Try to find in the existing list of loaded grids. Add all
diff --git a/boost/geometry/srs/projections/impl/pj_mlfn.hpp b/boost/geometry/srs/projections/impl/pj_mlfn.hpp
index 04f0d19442..92621875bb 100644
--- a/boost/geometry/srs/projections/impl/pj_mlfn.hpp
+++ b/boost/geometry/srs/projections/impl/pj_mlfn.hpp
@@ -48,6 +48,8 @@
#include <cstdlib>
+#include <boost/geometry/srs/projections/exception.hpp>
+#include <boost/geometry/srs/projections/impl/pj_strerrno.hpp>
#include <boost/geometry/util/math.hpp>
diff --git a/boost/geometry/srs/projections/impl/pj_phi2.hpp b/boost/geometry/srs/projections/impl/pj_phi2.hpp
index 868a8c659b..dacd4e16d0 100644
--- a/boost/geometry/srs/projections/impl/pj_phi2.hpp
+++ b/boost/geometry/srs/projections/impl/pj_phi2.hpp
@@ -39,6 +39,8 @@
#ifndef BOOST_GEOMETRY_PROJECTIONS_PHI2_HPP
#define BOOST_GEOMETRY_PROJECTIONS_PHI2_HPP
+#include <boost/geometry/srs/projections/exception.hpp>
+#include <boost/geometry/srs/projections/impl/pj_strerrno.hpp>
#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry { namespace projections {
diff --git a/boost/geometry/srs/projections/impl/pj_transform.hpp b/boost/geometry/srs/projections/impl/pj_transform.hpp
index 1be984556b..02291649e0 100644
--- a/boost/geometry/srs/projections/impl/pj_transform.hpp
+++ b/boost/geometry/srs/projections/impl/pj_transform.hpp
@@ -41,6 +41,7 @@
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/srs/projections/impl/geocent.hpp>
diff --git a/boost/geometry/srs/projections/impl/proj_mdist.hpp b/boost/geometry/srs/projections/impl/proj_mdist.hpp
index 5f67546f54..65fc41a4cc 100644
--- a/boost/geometry/srs/projections/impl/proj_mdist.hpp
+++ b/boost/geometry/srs/projections/impl/proj_mdist.hpp
@@ -40,6 +40,8 @@
#define BOOST_GEOMETRY_PROJECTIONS_PROJ_MDIST_HPP
+#include <boost/geometry/srs/projections/exception.hpp>
+#include <boost/geometry/srs/projections/impl/pj_strerrno.hpp>
#include <boost/geometry/util/math.hpp>
diff --git a/boost/geometry/srs/projections/par_data.hpp b/boost/geometry/srs/projections/par_data.hpp
index 17644e2157..c867676128 100644
--- a/boost/geometry/srs/projections/par_data.hpp
+++ b/boost/geometry/srs/projections/par_data.hpp
@@ -10,10 +10,12 @@
#ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_PAR_DATA_HPP
#define BOOST_GEOMETRY_SRS_PROJECTIONS_PAR_DATA_HPP
-#include <boost/config.hpp>
#include <string>
#include <vector>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/config.hpp>
+
namespace boost { namespace geometry { namespace srs
{
@@ -86,14 +88,14 @@ struct towgs84
towgs84()
: m_size(0)
-#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
+#ifdef BOOST_GEOMETRY_CXX11_ARRAY_UNIFIED_INITIALIZATION
, m_data{0, 0, 0, 0, 0, 0, 0}
-#endif
+ {}
+#else
{
-#ifdef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
std::fill(m_data, m_data + 7, T(0));
-#endif
}
+#endif
template <typename It>
towgs84(It first, It last)
diff --git a/boost/geometry/srs/projections/proj/aeqd.hpp b/boost/geometry/srs/projections/proj/aeqd.hpp
index b45146eac4..73ce9aac47 100644
--- a/boost/geometry/srs/projections/proj/aeqd.hpp
+++ b/boost/geometry/srs/projections/proj/aeqd.hpp
@@ -45,17 +45,21 @@
#define BOOST_GEOMETRY_PROJECTIONS_AEQD_HPP
#include <boost/config.hpp>
+
#include <boost/geometry/formulas/vincenty_direct.hpp>
#include <boost/geometry/formulas/vincenty_inverse.hpp>
-#include <boost/geometry/util/math.hpp>
-#include <boost/math/special_functions/hypot.hpp>
+#include <boost/geometry/srs/projections/impl/aasincos.hpp>
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
-#include <boost/geometry/srs/projections/impl/aasincos.hpp>
#include <boost/geometry/srs/projections/impl/pj_mlfn.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/math/special_functions/hypot.hpp>
#include <boost/type_traits/is_same.hpp>
diff --git a/boost/geometry/srs/projections/proj/airy.hpp b/boost/geometry/srs/projections/proj/airy.hpp
index 235a120d0e..fc2ea57de1 100644
--- a/boost/geometry/srs/projections/proj/airy.hpp
+++ b/boost/geometry/srs/projections/proj/airy.hpp
@@ -45,12 +45,13 @@
#ifndef BOOST_GEOMETRY_PROJECTIONS_AIRY_HPP
#define BOOST_GEOMETRY_PROJECTIONS_AIRY_HPP
-#include <boost/geometry/util/math.hpp>
-
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+
+#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/aitoff.hpp b/boost/geometry/srs/projections/proj/aitoff.hpp
index 6d64ea3588..a7ad3b086d 100644
--- a/boost/geometry/srs/projections/proj/aitoff.hpp
+++ b/boost/geometry/srs/projections/proj/aitoff.hpp
@@ -47,14 +47,15 @@
#ifndef BOOST_GEOMETRY_PROJECTIONS_AITOFF_HPP
#define BOOST_GEOMETRY_PROJECTIONS_AITOFF_HPP
-
#include <boost/core/ignore_unused.hpp>
-#include <boost/geometry/util/math.hpp>
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+
+#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/bipc.hpp b/boost/geometry/srs/projections/proj/bipc.hpp
index 647a07ad3f..9d531f87a8 100644
--- a/boost/geometry/srs/projections/proj/bipc.hpp
+++ b/boost/geometry/srs/projections/proj/bipc.hpp
@@ -40,13 +40,15 @@
#ifndef BOOST_GEOMETRY_PROJECTIONS_BIPC_HPP
#define BOOST_GEOMETRY_PROJECTIONS_BIPC_HPP
-#include <boost/geometry/util/math.hpp>
-#include <boost/math/special_functions/hypot.hpp>
-
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/math/special_functions/hypot.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/bonne.hpp b/boost/geometry/srs/projections/proj/bonne.hpp
index 4016d03229..70bdc87fd2 100644
--- a/boost/geometry/srs/projections/proj/bonne.hpp
+++ b/boost/geometry/srs/projections/proj/bonne.hpp
@@ -40,14 +40,16 @@
#ifndef BOOST_GEOMETRY_PROJECTIONS_BONNE_HPP
#define BOOST_GEOMETRY_PROJECTIONS_BONNE_HPP
-#include <boost/geometry/util/math.hpp>
-#include <boost/math/special_functions/hypot.hpp>
-
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
#include <boost/geometry/srs/projections/impl/pj_mlfn.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/math/special_functions/hypot.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/cea.hpp b/boost/geometry/srs/projections/proj/cea.hpp
index a440ec3f8a..467330e568 100644
--- a/boost/geometry/srs/projections/proj/cea.hpp
+++ b/boost/geometry/srs/projections/proj/cea.hpp
@@ -40,14 +40,15 @@
#ifndef BOOST_GEOMETRY_PROJECTIONS_CEA_HPP
#define BOOST_GEOMETRY_PROJECTIONS_CEA_HPP
-#include <boost/geometry/util/math.hpp>
-
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
#include <boost/geometry/srs/projections/impl/pj_auth.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
#include <boost/geometry/srs/projections/impl/pj_qsfn.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+
+#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/chamb.hpp b/boost/geometry/srs/projections/proj/chamb.hpp
index 1f397b33c4..0200a565cf 100644
--- a/boost/geometry/srs/projections/proj/chamb.hpp
+++ b/boost/geometry/srs/projections/proj/chamb.hpp
@@ -40,14 +40,16 @@
#ifndef BOOST_GEOMETRY_PROJECTIONS_CHAMB_HPP
#define BOOST_GEOMETRY_PROJECTIONS_CHAMB_HPP
-#include <boost/geometry/util/math.hpp>
#include <cstdio>
+#include <boost/geometry/srs/projections/impl/aasincos.hpp>
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
-#include <boost/geometry/srs/projections/impl/aasincos.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+
+#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/eqc.hpp b/boost/geometry/srs/projections/proj/eqc.hpp
index 21b655d2db..5a19f39ec7 100644
--- a/boost/geometry/srs/projections/proj/eqc.hpp
+++ b/boost/geometry/srs/projections/proj/eqc.hpp
@@ -42,8 +42,9 @@
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/eqdc.hpp b/boost/geometry/srs/projections/proj/eqdc.hpp
index d5aa8f2e11..986e258e2b 100644
--- a/boost/geometry/srs/projections/proj/eqdc.hpp
+++ b/boost/geometry/srs/projections/proj/eqdc.hpp
@@ -40,15 +40,17 @@
#ifndef BOOST_GEOMETRY_PROJECTIONS_EQDC_HPP
#define BOOST_GEOMETRY_PROJECTIONS_EQDC_HPP
-#include <boost/geometry/util/math.hpp>
-#include <boost/math/special_functions/hypot.hpp>
-
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
#include <boost/geometry/srs/projections/impl/pj_mlfn.hpp>
#include <boost/geometry/srs/projections/impl/pj_msfn.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/math/special_functions/hypot.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/etmerc.hpp b/boost/geometry/srs/projections/proj/etmerc.hpp
index 0bedbf247d..86e2a506fb 100644
--- a/boost/geometry/srs/projections/proj/etmerc.hpp
+++ b/boost/geometry/srs/projections/proj/etmerc.hpp
@@ -54,13 +54,14 @@
#ifndef BOOST_GEOMETRY_PROJECTIONS_ETMERC_HPP
#define BOOST_GEOMETRY_PROJECTIONS_ETMERC_HPP
-#include <boost/math/special_functions/hypot.hpp>
-
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
#include <boost/geometry/srs/projections/impl/function_overloads.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+
+#include <boost/math/special_functions/hypot.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/fouc_s.hpp b/boost/geometry/srs/projections/proj/fouc_s.hpp
index 10a252ec27..f6a8c5ed4b 100644
--- a/boost/geometry/srs/projections/proj/fouc_s.hpp
+++ b/boost/geometry/srs/projections/proj/fouc_s.hpp
@@ -40,13 +40,14 @@
#ifndef BOOST_GEOMETRY_PROJECTIONS_FOUC_S_HPP
#define BOOST_GEOMETRY_PROJECTIONS_FOUC_S_HPP
-#include <boost/geometry/util/math.hpp>
-
+#include <boost/geometry/srs/projections/impl/aasincos.hpp>
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
-#include <boost/geometry/srs/projections/impl/aasincos.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+
+#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/gn_sinu.hpp b/boost/geometry/srs/projections/proj/gn_sinu.hpp
index b4218cc839..2ef7df5099 100644
--- a/boost/geometry/srs/projections/proj/gn_sinu.hpp
+++ b/boost/geometry/srs/projections/proj/gn_sinu.hpp
@@ -40,14 +40,15 @@
#ifndef BOOST_GEOMETRY_PROJECTIONS_GN_SINU_HPP
#define BOOST_GEOMETRY_PROJECTIONS_GN_SINU_HPP
-#include <boost/geometry/util/math.hpp>
-
+#include <boost/geometry/srs/projections/impl/aasincos.hpp>
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
-#include <boost/geometry/srs/projections/impl/aasincos.hpp>
#include <boost/geometry/srs/projections/impl/pj_mlfn.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+
+#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/hammer.hpp b/boost/geometry/srs/projections/proj/hammer.hpp
index 6518fd8245..f9e1ae4e72 100644
--- a/boost/geometry/srs/projections/proj/hammer.hpp
+++ b/boost/geometry/srs/projections/proj/hammer.hpp
@@ -42,8 +42,9 @@
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/healpix.hpp b/boost/geometry/srs/projections/proj/healpix.hpp
index 414935c040..2084ae82f8 100644
--- a/boost/geometry/srs/projections/proj/healpix.hpp
+++ b/boost/geometry/srs/projections/proj/healpix.hpp
@@ -49,14 +49,15 @@
#ifndef BOOST_GEOMETRY_PROJECTIONS_HEALPIX_HPP
#define BOOST_GEOMETRY_PROJECTIONS_HEALPIX_HPP
-#include <boost/geometry/util/math.hpp>
-
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
#include <boost/geometry/srs/projections/impl/pj_auth.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
#include <boost/geometry/srs/projections/impl/pj_qsfn.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+
+#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/imw_p.hpp b/boost/geometry/srs/projections/proj/imw_p.hpp
index f5f662406f..d86c3c8f74 100644
--- a/boost/geometry/srs/projections/proj/imw_p.hpp
+++ b/boost/geometry/srs/projections/proj/imw_p.hpp
@@ -40,13 +40,14 @@
#ifndef BOOST_GEOMETRY_PROJECTIONS_IMW_P_HPP
#define BOOST_GEOMETRY_PROJECTIONS_IMW_P_HPP
-#include <boost/geometry/util/math.hpp>
-
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
#include <boost/geometry/srs/projections/impl/pj_mlfn.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+
+#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/isea.hpp b/boost/geometry/srs/projections/proj/isea.hpp
index d3f53a7754..d8a48041d2 100644
--- a/boost/geometry/srs/projections/proj/isea.hpp
+++ b/boost/geometry/srs/projections/proj/isea.hpp
@@ -48,12 +48,14 @@
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/core/assert.hpp>
-#include <boost/geometry/util/math.hpp>
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+
+#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/krovak.hpp b/boost/geometry/srs/projections/proj/krovak.hpp
index 5e4d08a844..75771b49e1 100644
--- a/boost/geometry/srs/projections/proj/krovak.hpp
+++ b/boost/geometry/srs/projections/proj/krovak.hpp
@@ -47,8 +47,9 @@
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/labrd.hpp b/boost/geometry/srs/projections/proj/labrd.hpp
index a66d0c63a2..1b86fe74ec 100644
--- a/boost/geometry/srs/projections/proj/labrd.hpp
+++ b/boost/geometry/srs/projections/proj/labrd.hpp
@@ -42,8 +42,9 @@
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/lagrng.hpp b/boost/geometry/srs/projections/proj/lagrng.hpp
index 6f40bb2804..6df4459624 100644
--- a/boost/geometry/srs/projections/proj/lagrng.hpp
+++ b/boost/geometry/srs/projections/proj/lagrng.hpp
@@ -40,12 +40,13 @@
#ifndef BOOST_GEOMETRY_PROJECTIONS_LAGRNG_HPP
#define BOOST_GEOMETRY_PROJECTIONS_LAGRNG_HPP
-#include <boost/geometry/util/math.hpp>
-
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+
+#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/lcc.hpp b/boost/geometry/srs/projections/proj/lcc.hpp
index 1b261cb70b..ebd9c3bb6e 100644
--- a/boost/geometry/srs/projections/proj/lcc.hpp
+++ b/boost/geometry/srs/projections/proj/lcc.hpp
@@ -40,17 +40,18 @@
#ifndef BOOST_GEOMETRY_PROJECTIONS_LCC_HPP
#define BOOST_GEOMETRY_PROJECTIONS_LCC_HPP
-#include <boost/geometry/util/math.hpp>
-#include <boost/math/special_functions/hypot.hpp>
-
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
#include <boost/geometry/srs/projections/impl/pj_msfn.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
#include <boost/geometry/srs/projections/impl/pj_phi2.hpp>
#include <boost/geometry/srs/projections/impl/pj_tsfn.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/math/special_functions/hypot.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/loxim.hpp b/boost/geometry/srs/projections/proj/loxim.hpp
index 3736a11cf2..927cab1574 100644
--- a/boost/geometry/srs/projections/proj/loxim.hpp
+++ b/boost/geometry/srs/projections/proj/loxim.hpp
@@ -40,12 +40,13 @@
#ifndef BOOST_GEOMETRY_PROJECTIONS_LOXIM_HPP
#define BOOST_GEOMETRY_PROJECTIONS_LOXIM_HPP
-#include <boost/geometry/util/math.hpp>
-
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+
+#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/lsat.hpp b/boost/geometry/srs/projections/proj/lsat.hpp
index 65dbe97f6d..3a20d96cb7 100644
--- a/boost/geometry/srs/projections/proj/lsat.hpp
+++ b/boost/geometry/srs/projections/proj/lsat.hpp
@@ -40,13 +40,14 @@
#ifndef BOOST_GEOMETRY_PROJECTIONS_LSAT_HPP
#define BOOST_GEOMETRY_PROJECTIONS_LSAT_HPP
-#include <boost/geometry/util/math.hpp>
-
+#include <boost/geometry/srs/projections/impl/aasincos.hpp>
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
-#include <boost/geometry/srs/projections/impl/aasincos.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+
+#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/merc.hpp b/boost/geometry/srs/projections/proj/merc.hpp
index e2fba50720..5ec1e1f84c 100644
--- a/boost/geometry/srs/projections/proj/merc.hpp
+++ b/boost/geometry/srs/projections/proj/merc.hpp
@@ -40,15 +40,16 @@
#ifndef BOOST_GEOMETRY_PROJECTIONS_MERC_HPP
#define BOOST_GEOMETRY_PROJECTIONS_MERC_HPP
-#include <boost/geometry/util/math.hpp>
-
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
#include <boost/geometry/srs/projections/impl/pj_msfn.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
#include <boost/geometry/srs/projections/impl/pj_phi2.hpp>
#include <boost/geometry/srs/projections/impl/pj_tsfn.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+
+#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/nsper.hpp b/boost/geometry/srs/projections/proj/nsper.hpp
index 89dc6a8a15..6366e100dd 100644
--- a/boost/geometry/srs/projections/proj/nsper.hpp
+++ b/boost/geometry/srs/projections/proj/nsper.hpp
@@ -41,13 +41,16 @@
#define BOOST_GEOMETRY_PROJECTIONS_NSPER_HPP
#include <boost/config.hpp>
-#include <boost/geometry/util/math.hpp>
-#include <boost/math/special_functions/hypot.hpp>
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/math/special_functions/hypot.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/ob_tran.hpp b/boost/geometry/srs/projections/proj/ob_tran.hpp
index f5709228f5..99a7b82b1a 100644
--- a/boost/geometry/srs/projections/proj/ob_tran.hpp
+++ b/boost/geometry/srs/projections/proj/ob_tran.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2017, 2018.
-// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2017, 2018, 2019.
+// Modifications copyright (c) 2017-2019, 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,
@@ -128,7 +128,7 @@ namespace projections
}
template <BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX, typename Parameters>
- inline Parameters o_proj_parameters(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& params,
+ inline Parameters o_proj_parameters(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& /*params*/,
Parameters const& par)
{
/* copy existing header into new */
@@ -292,7 +292,7 @@ namespace projections
// General Oblique Transformation
template <typename T, typename Params, typename Parameters, typename ProjParameters>
- inline T setup_ob_tran(Params const& params, Parameters & par, ProjParameters& proj_parm)
+ inline T setup_ob_tran(Params const& params, Parameters & /*par*/, ProjParameters& proj_parm)
{
static const T half_pi = detail::half_pi<T>();
diff --git a/boost/geometry/srs/projections/proj/ocea.hpp b/boost/geometry/srs/projections/proj/ocea.hpp
index af8be1ca08..c7f531745c 100644
--- a/boost/geometry/srs/projections/proj/ocea.hpp
+++ b/boost/geometry/srs/projections/proj/ocea.hpp
@@ -44,8 +44,9 @@
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/oea.hpp b/boost/geometry/srs/projections/proj/oea.hpp
index f78037d2cb..10399ec1a8 100644
--- a/boost/geometry/srs/projections/proj/oea.hpp
+++ b/boost/geometry/srs/projections/proj/oea.hpp
@@ -42,11 +42,12 @@
#include <boost/math/special_functions/hypot.hpp>
+#include <boost/geometry/srs/projections/impl/aasincos.hpp>
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
-#include <boost/geometry/srs/projections/impl/aasincos.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/omerc.hpp b/boost/geometry/srs/projections/proj/omerc.hpp
index 1e041e2ac0..0bec0cacca 100644
--- a/boost/geometry/srs/projections/proj/omerc.hpp
+++ b/boost/geometry/srs/projections/proj/omerc.hpp
@@ -46,10 +46,11 @@
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
#include <boost/geometry/srs/projections/impl/pj_phi2.hpp>
#include <boost/geometry/srs/projections/impl/pj_tsfn.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/rpoly.hpp b/boost/geometry/srs/projections/proj/rpoly.hpp
index 87a5d482ba..fc59a0397b 100644
--- a/boost/geometry/srs/projections/proj/rpoly.hpp
+++ b/boost/geometry/srs/projections/proj/rpoly.hpp
@@ -42,8 +42,9 @@
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/sconics.hpp b/boost/geometry/srs/projections/proj/sconics.hpp
index 5499f1a7c0..44d606cab4 100644
--- a/boost/geometry/srs/projections/proj/sconics.hpp
+++ b/boost/geometry/srs/projections/proj/sconics.hpp
@@ -46,8 +46,9 @@
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/stere.hpp b/boost/geometry/srs/projections/proj/stere.hpp
index 7b287383f1..7c2de3fcc7 100644
--- a/boost/geometry/srs/projections/proj/stere.hpp
+++ b/boost/geometry/srs/projections/proj/stere.hpp
@@ -46,9 +46,10 @@
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
#include <boost/geometry/srs/projections/impl/pj_tsfn.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/tpeqd.hpp b/boost/geometry/srs/projections/proj/tpeqd.hpp
index 9b9687fae3..06f9cc0a03 100644
--- a/boost/geometry/srs/projections/proj/tpeqd.hpp
+++ b/boost/geometry/srs/projections/proj/tpeqd.hpp
@@ -43,11 +43,12 @@
#include <boost/geometry/util/math.hpp>
#include <boost/math/special_functions/hypot.hpp>
+#include <boost/geometry/srs/projections/impl/aasincos.hpp>
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
-#include <boost/geometry/srs/projections/impl/aasincos.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/urm5.hpp b/boost/geometry/srs/projections/proj/urm5.hpp
index 4cec4cdd1e..b1682332aa 100644
--- a/boost/geometry/srs/projections/proj/urm5.hpp
+++ b/boost/geometry/srs/projections/proj/urm5.hpp
@@ -40,11 +40,12 @@
#ifndef BOOST_GEOMETRY_PROJECTIONS_URM5_HPP
#define BOOST_GEOMETRY_PROJECTIONS_URM5_HPP
+#include <boost/geometry/srs/projections/impl/aasincos.hpp>
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
-#include <boost/geometry/srs/projections/impl/aasincos.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/urmfps.hpp b/boost/geometry/srs/projections/proj/urmfps.hpp
index aa7982758a..8f608619a5 100644
--- a/boost/geometry/srs/projections/proj/urmfps.hpp
+++ b/boost/geometry/srs/projections/proj/urmfps.hpp
@@ -40,11 +40,12 @@
#ifndef BOOST_GEOMETRY_PROJECTIONS_URMFPS_HPP
#define BOOST_GEOMETRY_PROJECTIONS_URMFPS_HPP
+#include <boost/geometry/srs/projections/impl/aasincos.hpp>
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
-#include <boost/geometry/srs/projections/impl/aasincos.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/wag3.hpp b/boost/geometry/srs/projections/proj/wag3.hpp
index 825ead3533..c69eca7b75 100644
--- a/boost/geometry/srs/projections/proj/wag3.hpp
+++ b/boost/geometry/srs/projections/proj/wag3.hpp
@@ -42,8 +42,9 @@
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/wink1.hpp b/boost/geometry/srs/projections/proj/wink1.hpp
index b920daa97f..d05f9458f8 100644
--- a/boost/geometry/srs/projections/proj/wink1.hpp
+++ b/boost/geometry/srs/projections/proj/wink1.hpp
@@ -42,8 +42,9 @@
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/proj/wink2.hpp b/boost/geometry/srs/projections/proj/wink2.hpp
index 06f0770365..71bc147abc 100644
--- a/boost/geometry/srs/projections/proj/wink2.hpp
+++ b/boost/geometry/srs/projections/proj/wink2.hpp
@@ -44,8 +44,9 @@
#include <boost/geometry/srs/projections/impl/base_static.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
-#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_param.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/srs/projections/shared_grids.hpp b/boost/geometry/srs/projections/shared_grids.hpp
index 54191808cb..d4a27e4b10 100644
--- a/boost/geometry/srs/projections/shared_grids.hpp
+++ b/boost/geometry/srs/projections/shared_grids.hpp
@@ -23,35 +23,24 @@ namespace boost { namespace geometry
{
-// Forward declarations
-namespace srs
+namespace projections { namespace detail
{
// Forward declaration for functions declarations below
class shared_grids;
-} // namespace srs
-namespace projections { namespace detail
-{
-
// Forward declaratios of shared_grids friends
template <typename StreamPolicy>
inline bool pj_gridlist_merge_gridfile(std::string const& gridname,
StreamPolicy const& stream_policy,
- srs::shared_grids & grids,
+ shared_grids & grids,
std::vector<std::size_t> & gridindexes);
template <bool Inverse, typename CalcT, typename StreamPolicy, typename Range>
inline bool pj_apply_gridshift_3(StreamPolicy const& stream_policy,
Range & range,
- srs::shared_grids & grids,
+ shared_grids & grids,
std::vector<std::size_t> const& gridindexes);
-}} // namespace projections::detail
-
-
-namespace srs
-{
-
class shared_grids
{
@@ -73,21 +62,21 @@ private:
friend inline bool projections::detail::pj_gridlist_merge_gridfile(
std::string const& gridname,
StreamPolicy const& stream_policy,
- srs::shared_grids & grids,
+ shared_grids & grids,
std::vector<std::size_t> & gridindexes);
template <bool Inverse, typename CalcT, typename StreamPolicy, typename Range>
friend inline bool projections::detail::pj_apply_gridshift_3(
StreamPolicy const& stream_policy,
Range & range,
- srs::shared_grids & grids,
+ shared_grids & grids,
std::vector<std::size_t> const& gridindexes);
projections::detail::pj_gridinfo gridinfo;
mutable boost::shared_mutex mutex;
};
+}} // namespace projections::detail
-} // namespace srs
}} // namespace boost::geometry
diff --git a/boost/geometry/srs/shared_grids.hpp b/boost/geometry/srs/shared_grids.hpp
index 9eb61717ba..bc9528bd27 100644
--- a/boost/geometry/srs/shared_grids.hpp
+++ b/boost/geometry/srs/shared_grids.hpp
@@ -16,5 +16,11 @@
#include <boost/geometry/srs/projections/impl/pj_gridlist_shared.hpp>
#include <boost/geometry/srs/projections/shared_grids.hpp>
+namespace boost { namespace geometry { namespace srs
+{
+
+using geometry::projections::detail::shared_grids;
+
+}}} // namespace boost::geometry::srs
#endif // BOOST_GEOMETRY_SRS_SHARED_GRIDS_HPP
diff --git a/boost/geometry/srs/transformation.hpp b/boost/geometry/srs/transformation.hpp
index 38e6ce04c6..b8ab4e0775 100644
--- a/boost/geometry/srs/transformation.hpp
+++ b/boost/geometry/srs/transformation.hpp
@@ -59,15 +59,11 @@ template
<
typename PtIn,
typename PtOut,
- bool SameUnits = geometry::is_radian
+ bool SameUnits = boost::is_same
<
- typename geometry::coordinate_system<PtIn>::type
- >::type::value
- ==
- geometry::is_radian
- <
- typename geometry::coordinate_system<PtOut>::type
- >::type::value
+ typename geometry::detail::cs_angular_units<PtIn>::type,
+ typename geometry::detail::cs_angular_units<PtOut>::type
+ >::value
>
struct transform_geometry_point_coordinates
{
diff --git a/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp b/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp
index 0cd0cdc4db..f86dcbdd91 100644
--- a/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp
+++ b/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2018.
+// Modifications copyright (c) 2014, 2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -22,18 +22,17 @@
#include <algorithm>
#include <vector>
-#include <boost/range.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/geometry/algorithms/detail/for_each_range.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/strategies/convex_hull.hpp>
-
+#include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/views/detail/range_type.hpp>
-
-#include <boost/geometry/policies/compare.hpp>
-
-#include <boost/geometry/algorithms/detail/for_each_range.hpp>
#include <boost/geometry/views/reversible_view.hpp>
@@ -193,9 +192,6 @@ static inline void sort(Range& range)
/*!
\brief Graham scan strategy to calculate convex hull
\ingroup strategies
-\note Completely reworked version inspired on the sources listed below
-\see http://www.ddj.com/architect/201806315
-\see http://marknelson.us/2007/08/22/convex
*/
template <typename InputGeometry, typename OutputPoint>
class graham_andrew
diff --git a/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp b/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp
index 8493b57c35..f87656dbce 100644
--- a/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp
+++ b/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp
@@ -4,6 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018 Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -20,6 +24,7 @@
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/strategies/covered_by.hpp>
+#include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/strategies/within.hpp>
@@ -60,16 +65,17 @@ struct decide_covered_by
// This strategy is not suitable for boxes in non-cartesian CSes having edges
// longer than 180deg because e.g. the SSF formula picks the side of the closer
// longitude, so for long edges the side is the opposite.
-template <typename Point, typename Box, typename Decide = decide_within>
+template <typename Decide = decide_within>
struct point_in_box_by_side
{
- typedef typename strategy::side::services::default_strategy
- <
- typename cs_tag<Box>::type
- >::type side_strategy_type;
-
+ template <typename Point, typename Box>
static inline bool apply(Point const& point, Box const& box)
{
+ typedef typename strategy::side::services::default_strategy
+ <
+ typename cs_tag<Box>::type
+ >::type side_strategy_type;
+
// Create (counterclockwise) array of points, the fifth one closes it
// Every point should be on the LEFT side (=1), or ON the border (=0),
// So >= 1 or >= 0
diff --git a/boost/geometry/strategies/agnostic/point_in_point.hpp b/boost/geometry/strategies/agnostic/point_in_point.hpp
index d4692766c5..051b87f401 100644
--- a/boost/geometry/strategies/agnostic/point_in_point.hpp
+++ b/boost/geometry/strategies/agnostic/point_in_point.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2014-2017 Oracle and/or its affiliates.
+// Copyright (c) 2014-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -12,10 +12,12 @@
#ifndef BOOST_GEOMETRY_STRATEGY_AGNOSTIC_POINT_IN_POINT_HPP
#define BOOST_GEOMETRY_STRATEGY_AGNOSTIC_POINT_IN_POINT_HPP
-#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
-#include <boost/geometry/strategies/covered_by.hpp>
-#include <boost/geometry/strategies/within.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
+#include <boost/geometry/strategies/spherical/point_in_point.hpp>
namespace boost { namespace geometry
@@ -26,59 +28,32 @@ namespace strategy { namespace within
template
<
- typename Point1, typename Point2
+ typename Point1, typename Point2,
+ typename CSTag = typename cs_tag<Point1>::type
>
struct point_in_point
-{
- static inline bool apply(Point1 const& point1, Point2 const& point2)
- {
- return geometry::detail::equals::equals_point_point(point1, point2);
- }
-};
-
-
-#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+ : strategy::within::cartesian_point_point
+{};
-namespace services
-{
-
-template <typename PointLike1, typename PointLike2, typename Tag1, typename Tag2, typename AnyCS1, typename AnyCS2>
-struct default_strategy<PointLike1, PointLike2, Tag1, Tag2, pointlike_tag, pointlike_tag, AnyCS1, AnyCS2>
-{
- typedef strategy::within::point_in_point
- <
- typename point_type<PointLike1>::type,
- typename point_type<PointLike2>::type
- > type;
-};
+template <typename Point1, typename Point2>
+struct point_in_point<Point1, Point2, spherical_equatorial_tag>
+ : strategy::within::spherical_point_point
+{};
+template <typename Point1, typename Point2>
+struct point_in_point<Point1, Point2, spherical_polar_tag>
+ : strategy::within::spherical_point_point
+{};
-} // namespace services
-
-#endif
+template <typename Point1, typename Point2>
+struct point_in_point<Point1, Point2, geographic_tag>
+ : strategy::within::spherical_point_point
+{};
}} // namespace strategy::within
-#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-namespace strategy { namespace covered_by { namespace services
-{
-
-template <typename PointLike1, typename PointLike2, typename Tag1, typename Tag2, typename AnyCS1, typename AnyCS2>
-struct default_strategy<PointLike1, PointLike2, Tag1, Tag2, pointlike_tag, pointlike_tag, AnyCS1, AnyCS2>
-{
- typedef strategy::within::point_in_point
- <
- typename point_type<PointLike1>::type,
- typename point_type<PointLike2>::type
- > type;
-};
-
-}}} // namespace strategy::covered_by::services
-#endif
-
-
}} // namespace boost::geometry
diff --git a/boost/geometry/strategies/agnostic/point_in_poly_oriented_winding.hpp b/boost/geometry/strategies/agnostic/point_in_poly_oriented_winding.hpp
index 423948fff3..35aae192a3 100644
--- a/boost/geometry/strategies/agnostic/point_in_poly_oriented_winding.hpp
+++ b/boost/geometry/strategies/agnostic/point_in_poly_oriented_winding.hpp
@@ -36,8 +36,6 @@ namespace strategy { namespace within
\tparam PointOfSegment \tparam_segment_point
\tparam CalculationType \tparam_calculation
\author Barend Gehrels
-\note The implementation is inspired by terralib http://www.terralib.org (LGPL)
-\note but totally revised afterwards, especially for cases on segments
\note Only dependant on "side", -> agnostic, suitable for spherical/latlong
\qbk{
diff --git a/boost/geometry/strategies/cartesian/area.hpp b/boost/geometry/strategies/cartesian/area.hpp
index 27708424c2..070e8f56b0 100644
--- a/boost/geometry/strategies/cartesian/area.hpp
+++ b/boost/geometry/strategies/cartesian/area.hpp
@@ -5,8 +5,8 @@
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2016, 2017.
-// Modifications copyright (c) 2016-2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2016, 2017, 2018.
+// Modifications copyright (c) 2016-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -24,6 +24,7 @@
#include <boost/mpl/if.hpp>
//#include <boost/geometry/arithmetic/determinant.hpp>
+#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/strategies/area.hpp>
diff --git a/boost/geometry/strategies/cartesian/azimuth.hpp b/boost/geometry/strategies/cartesian/azimuth.hpp
index 62f804e8f5..2ff16e9458 100644
--- a/boost/geometry/strategies/cartesian/azimuth.hpp
+++ b/boost/geometry/strategies/cartesian/azimuth.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2016-2017 Oracle and/or its affiliates.
+// Copyright (c) 2016-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -13,6 +13,8 @@
#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/strategies/azimuth.hpp>
+
namespace boost { namespace geometry
{
diff --git a/boost/geometry/strategies/cartesian/buffer_end_flat.hpp b/boost/geometry/strategies/cartesian/buffer_end_flat.hpp
index c01cf4df85..dfbc19e98d 100644
--- a/boost/geometry/strategies/cartesian/buffer_end_flat.hpp
+++ b/boost/geometry/strategies/cartesian/buffer_end_flat.hpp
@@ -2,6 +2,11 @@
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -9,16 +14,13 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_END_FLAT_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_END_FLAT_HPP
-#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/strategies/buffer.hpp>
#include <boost/geometry/strategies/tags.hpp>
#include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
-#include <boost/geometry/strategies/buffer.hpp>
-
-
-
namespace boost { namespace geometry
{
diff --git a/boost/geometry/strategies/cartesian/buffer_point_circle.hpp b/boost/geometry/strategies/cartesian/buffer_point_circle.hpp
index f289857177..c341e3ca3b 100644
--- a/boost/geometry/strategies/cartesian/buffer_point_circle.hpp
+++ b/boost/geometry/strategies/cartesian/buffer_point_circle.hpp
@@ -2,10 +2,11 @@
// Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2018.
+// Modifications copyright (c) 2015, 2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -16,12 +17,15 @@
#include <cstddef>
-#include <boost/range.hpp>
+#include <boost/range/value_type.hpp>
-#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/strategies/buffer.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
namespace boost { namespace geometry
{
@@ -46,6 +50,7 @@ namespace strategy { namespace buffer
[heading See also]
\* [link geometry.reference.algorithms.buffer.buffer_7_with_strategies buffer (with strategies)]
\* [link geometry.reference.strategies.strategy_buffer_point_square point_square]
+\* [link geometry.reference.strategies.strategy_buffer_geographic_point_circle geographic_point_circle]
}
*/
class point_circle
diff --git a/boost/geometry/strategies/cartesian/buffer_point_square.hpp b/boost/geometry/strategies/cartesian/buffer_point_square.hpp
index 37a90c013f..12b4bd8eb4 100644
--- a/boost/geometry/strategies/cartesian/buffer_point_square.hpp
+++ b/boost/geometry/strategies/cartesian/buffer_point_square.hpp
@@ -1,5 +1,12 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
+
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -9,12 +16,11 @@
#include <cstddef>
-#include <boost/range.hpp>
-
-#include <boost/geometry/util/math.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/geometry/core/access.hpp>
#include <boost/geometry/strategies/buffer.hpp>
-
+#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry
{
@@ -39,6 +45,7 @@ namespace strategy { namespace buffer
[heading See also]
\* [link geometry.reference.algorithms.buffer.buffer_7_with_strategies buffer (with strategies)]
\* [link geometry.reference.strategies.strategy_buffer_point_circle point_circle]
+\* [link geometry.reference.strategies.strategy_buffer_geographic_point_circle geographic_point_circle]
}
*/
class point_square
diff --git a/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp b/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp
index d081173a3e..edb2c8a712 100644
--- a/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp
+++ b/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp
@@ -4,8 +4,8 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2018.
+// Modifications copyright (c) 2015, 2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -31,6 +31,7 @@
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/strategies/centroid.hpp>
+#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
diff --git a/boost/geometry/strategies/cartesian/densify.hpp b/boost/geometry/strategies/cartesian/densify.hpp
index 23651637b9..9e6dd39b56 100644
--- a/boost/geometry/strategies/cartesian/densify.hpp
+++ b/boost/geometry/strategies/cartesian/densify.hpp
@@ -18,6 +18,7 @@
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/strategies/densify.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
diff --git a/boost/geometry/strategies/cartesian/disjoint_box_box.hpp b/boost/geometry/strategies/cartesian/disjoint_box_box.hpp
new file mode 100644
index 0000000000..706c93ec79
--- /dev/null
+++ b/boost/geometry/strategies/cartesian/disjoint_box_box.hpp
@@ -0,0 +1,112 @@
+// 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) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
+
+// This file was modified by Oracle on 2013-2018.
+// Modifications copyright (c) 2013-2018, 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.
+
+// 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_STRATEGIES_CARTESIAN_DISJOINT_BOX_BOX_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISJOINT_BOX_BOX_HPP
+
+#include <cstddef>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/strategies/disjoint.hpp>
+
+
+namespace boost { namespace geometry { namespace strategy { namespace disjoint
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template
+<
+ typename Box1, typename Box2,
+ std::size_t Dimension = 0,
+ std::size_t DimensionCount = dimension<Box1>::value
+>
+struct box_box
+{
+ static inline bool apply(Box1 const& box1, Box2 const& box2)
+ {
+ if (get<max_corner, Dimension>(box1) < get<min_corner, Dimension>(box2))
+ {
+ return true;
+ }
+ if (get<min_corner, Dimension>(box1) > get<max_corner, Dimension>(box2))
+ {
+ return true;
+ }
+ return box_box
+ <
+ Box1, Box2,
+ Dimension + 1, DimensionCount
+ >::apply(box1, box2);
+ }
+};
+
+
+template <typename Box1, typename Box2, std::size_t DimensionCount>
+struct box_box<Box1, Box2, DimensionCount, DimensionCount>
+{
+ static inline bool apply(Box1 const& , Box2 const& )
+ {
+ return false;
+ }
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+struct cartesian_box_box
+{
+ template <typename Box1, typename Box2>
+ static inline bool apply(Box1 const& box1, Box2 const& box2)
+ {
+ return detail::box_box<Box1, Box2>::apply(box1, box2);
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+namespace services
+{
+
+template <typename Box1, typename Box2, int TopDim1, int TopDim2>
+struct default_strategy<Box1, Box2, box_tag, box_tag, TopDim1, TopDim2, cartesian_tag, cartesian_tag>
+{
+ typedef disjoint::cartesian_box_box type;
+};
+
+
+} // namespace services
+
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}}}} // namespace boost::geometry::strategy::disjoint
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISJOINT_BOX_BOX_HPP
diff --git a/boost/geometry/strategies/cartesian/distance_projected_point.hpp b/boost/geometry/strategies/cartesian/distance_projected_point.hpp
index 84f1c948c1..bd4f7130ca 100644
--- a/boost/geometry/strategies/cartesian/distance_projected_point.hpp
+++ b/boost/geometry/strategies/cartesian/distance_projected_point.hpp
@@ -4,10 +4,11 @@
// Copyright (c) 2008-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2018.
+// Modifications copyright (c) 2014-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -36,6 +37,7 @@
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/default_distance_result.hpp>
#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
+#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
@@ -76,6 +78,8 @@ template
class projected_point
{
public :
+ typedef within::cartesian_point_point equals_point_point_strategy_type;
+
// The three typedefs below are necessary to calculate distances
// from segments defined in integer coordinates.
diff --git a/boost/geometry/strategies/cartesian/distance_pythagoras.hpp b/boost/geometry/strategies/cartesian/distance_pythagoras.hpp
index 8a8889dc99..8d8b954362 100644
--- a/boost/geometry/strategies/cartesian/distance_pythagoras.hpp
+++ b/boost/geometry/strategies/cartesian/distance_pythagoras.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -17,6 +22,8 @@
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/util/math.hpp>
diff --git a/boost/geometry/strategies/cartesian/distance_pythagoras_box_box.hpp b/boost/geometry/strategies/cartesian/distance_pythagoras_box_box.hpp
index 4c1b6539be..85ee4b78f3 100644
--- a/boost/geometry/strategies/cartesian/distance_pythagoras_box_box.hpp
+++ b/boost/geometry/strategies/cartesian/distance_pythagoras_box_box.hpp
@@ -4,10 +4,11 @@
// Copyright (c) 2008-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2018.
+// Modifications copyright (c) 2014, 2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -21,6 +22,9 @@
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/point_type.hpp>
+
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
#include <boost/geometry/strategies/distance.hpp>
@@ -29,7 +33,6 @@
-
namespace boost { namespace geometry
{
diff --git a/boost/geometry/strategies/cartesian/distance_pythagoras_point_box.hpp b/boost/geometry/strategies/cartesian/distance_pythagoras_point_box.hpp
index 8423d16a63..d5f62c9ef8 100644
--- a/boost/geometry/strategies/cartesian/distance_pythagoras_point_box.hpp
+++ b/boost/geometry/strategies/cartesian/distance_pythagoras_point_box.hpp
@@ -4,10 +4,11 @@
// Copyright (c) 2008-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2018.
+// Modifications copyright (c) 2014, 2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -21,6 +22,9 @@
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/point_type.hpp>
+
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
#include <boost/geometry/strategies/distance.hpp>
diff --git a/boost/geometry/strategies/cartesian/distance_segment_box.hpp b/boost/geometry/strategies/cartesian/distance_segment_box.hpp
index 80f5094a59..b623822eca 100644
--- a/boost/geometry/strategies/cartesian/distance_segment_box.hpp
+++ b/boost/geometry/strategies/cartesian/distance_segment_box.hpp
@@ -1,7 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2018 Oracle and/or its affiliates.
+// Copyright (c) 2018-2019 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -12,6 +13,9 @@
#include <boost/geometry/algorithms/detail/distance/segment_to_box.hpp>
+#include <boost/geometry/strategies/cartesian/distance_projected_point.hpp>
+#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
+
namespace boost { namespace geometry
{
@@ -60,6 +64,13 @@ struct cartesian_segment_box
return typename distance_ps_strategy::type();
}
+ typedef within::cartesian_point_point equals_point_point_strategy_type;
+
+ static inline equals_point_point_strategy_type get_equals_point_point_strategy()
+ {
+ return equals_point_point_strategy_type();
+ }
+
template <typename LessEqual, typename ReturnType,
typename SegmentPoint, typename BoxPoint>
inline ReturnType segment_below_of_box(SegmentPoint const& p0,
diff --git a/boost/geometry/strategies/cartesian/envelope.hpp b/boost/geometry/strategies/cartesian/envelope.hpp
new file mode 100644
index 0000000000..2a11dc5a52
--- /dev/null
+++ b/boost/geometry/strategies/cartesian/envelope.hpp
@@ -0,0 +1,153 @@
+// 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, 2016, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// 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_STRATEGIES_CARTESIAN_ENVELOPE_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_HPP
+
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/initialize.hpp>
+
+#include <boost/geometry/strategies/cartesian/envelope_box.hpp>
+#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
+#include <boost/geometry/strategies/cartesian/expand_box.hpp>
+#include <boost/geometry/strategies/cartesian/expand_segment.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace envelope
+{
+
+template <typename CalculationType = void>
+class cartesian
+{
+public:
+ typedef cartesian_point element_envelope_strategy_type;
+ static inline element_envelope_strategy_type get_element_envelope_strategy()
+ {
+ return element_envelope_strategy_type();
+ }
+
+ typedef expand::cartesian_point element_expand_strategy_type;
+ static inline element_expand_strategy_type get_element_expand_strategy()
+ {
+ return element_expand_strategy_type();
+ }
+
+ typedef expand::cartesian_box box_expand_strategy_type;
+ static inline box_expand_strategy_type get_box_expand_strategy()
+ {
+ return box_expand_strategy_type();
+ }
+
+ // Linestring, Ring, Polygon
+
+ template <typename Range>
+ static inline typename boost::range_iterator<Range const>::type begin(Range const& range)
+ {
+ return boost::begin(range);
+ }
+
+ template <typename Range>
+ static inline typename boost::range_iterator<Range const>::type end(Range const& range)
+ {
+ return boost::end(range);
+ }
+
+ // MultiLinestring, MultiPolygon
+
+ template <typename Box>
+ struct multi_state
+ {
+ multi_state()
+ : m_initialized(false)
+ {}
+
+ void apply(Box const& single_box)
+ {
+ if (! m_initialized)
+ {
+ m_box = single_box;
+ m_initialized = true;
+ }
+ else
+ {
+ box_expand_strategy_type::apply(m_box, single_box);
+ }
+ }
+
+ void result(Box & box)
+ {
+ if (m_initialized)
+ {
+ box = m_box;
+ }
+ else
+ {
+ geometry::detail::envelope::initialize<Box, 0, dimension<Box>::value>::apply(box);
+ }
+ }
+
+ private:
+ bool m_initialized;
+ Box m_box;
+ };
+
+ // Segment
+
+ template <typename Point1, typename Point2, typename Box>
+ static inline void apply(Point1 const& point1, Point2 const& point2,
+ Box& box)
+ {
+ cartesian_segment<CalculationType>::apply(point1, point2, box);
+ }
+
+ // Box
+
+ template <typename BoxIn, typename Box>
+ static inline void apply(BoxIn const& box_in, Box& box)
+ {
+ cartesian_box::apply(box_in, box);
+ }
+};
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+template <typename Tag, typename CalculationType>
+struct default_strategy<Tag, cartesian_tag, CalculationType>
+{
+ typedef strategy::envelope::cartesian<CalculationType> type;
+};
+
+} // namespace services
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::envelope
+
+}} //namepsace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_HPP
diff --git a/boost/geometry/strategies/cartesian/envelope_box.hpp b/boost/geometry/strategies/cartesian/envelope_box.hpp
new file mode 100644
index 0000000000..c6dd218354
--- /dev/null
+++ b/boost/geometry/strategies/cartesian/envelope_box.hpp
@@ -0,0 +1,119 @@
+// 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-2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, 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_STRATEGIES_CARTESIAN_ENVELOPE_BOX_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_BOX_HPP
+
+#include <cstddef>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.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>
+
+#include <boost/geometry/strategies/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);
+ }
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+
+namespace strategy { namespace envelope
+{
+
+
+struct cartesian_box
+{
+ template<typename BoxIn, typename BoxOut>
+ static inline void apply(BoxIn const& box_in, BoxOut& mbr)
+ {
+ geometry::detail::envelope::envelope_indexed_box
+ <
+ min_corner, 0, dimension<BoxIn>::value
+ >::apply(box_in, mbr);
+
+ geometry::detail::envelope::envelope_indexed_box
+ <
+ max_corner, 0, dimension<BoxIn>::value
+ >::apply(box_in, mbr);
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+template <typename CalculationType>
+struct default_strategy<box_tag, cartesian_tag, CalculationType>
+{
+ typedef strategy::envelope::cartesian_box type;
+};
+
+}
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::envelope
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_BOX_HPP
diff --git a/boost/geometry/strategies/cartesian/envelope_multipoint.hpp b/boost/geometry/strategies/cartesian/envelope_multipoint.hpp
new file mode 100644
index 0000000000..28c2374ce8
--- /dev/null
+++ b/boost/geometry/strategies/cartesian/envelope_multipoint.hpp
@@ -0,0 +1,59 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, 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_STRATEGIES_CARTESIAN_ENVELOPE_MULTIPOINT_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_MULTIPOINT_HPP
+
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/detail/envelope/range.hpp>
+
+#include <boost/geometry/strategies/cartesian/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace envelope
+{
+
+class cartesian_multipoint
+{
+public:
+ template <typename MultiPoint, typename Box>
+ static inline void apply(MultiPoint const& multipoint, Box& mbr)
+ {
+ geometry::detail::envelope::envelope_range::apply(multipoint, mbr, cartesian<>());
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+template <typename CalculationType>
+struct default_strategy<multi_point_tag, cartesian_tag, CalculationType>
+{
+ typedef strategy::envelope::cartesian_multipoint type;
+};
+
+
+} // namespace services
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::envelope
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_MULTIPOINT_HPP
diff --git a/boost/geometry/strategies/cartesian/envelope_point.hpp b/boost/geometry/strategies/cartesian/envelope_point.hpp
new file mode 100644
index 0000000000..3f900c7184
--- /dev/null
+++ b/boost/geometry/strategies/cartesian/envelope_point.hpp
@@ -0,0 +1,111 @@
+// 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, 2016, 2017, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, 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_STRATEGIES_CARTESIAN_ENVELOPE_POINT_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_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/strategies/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);
+ }
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+
+namespace strategy { namespace envelope
+{
+
+struct cartesian_point
+{
+ template <typename Point, typename Box>
+ static inline void apply(Point const& point, Box& mbr)
+ {
+ geometry::detail::envelope::envelope_one_point
+ <
+ 0, dimension<Point>::value
+ >::apply(point, mbr);
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+template <typename CalculationType>
+struct default_strategy<point_tag, cartesian_tag, CalculationType>
+{
+ typedef strategy::envelope::cartesian_point type;
+};
+
+
+}
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::envelope
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_POINT_HPP
diff --git a/boost/geometry/strategies/cartesian/envelope_segment.hpp b/boost/geometry/strategies/cartesian/envelope_segment.hpp
index a591996b84..cd52775da5 100644
--- a/boost/geometry/strategies/cartesian/envelope_segment.hpp
+++ b/boost/geometry/strategies/cartesian/envelope_segment.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2017 Oracle and/or its affiliates.
+// Copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -11,18 +11,45 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_SEGMENT_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_SEGMENT_HPP
+#include <cstddef>
-#include <boost/geometry/algorithms/detail/envelope/segment.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/strategies/cartesian/envelope_point.hpp>
+#include <boost/geometry/strategies/cartesian/expand_point.hpp>
#include <boost/geometry/strategies/envelope.hpp>
-#include <boost/geometry/util/select_calculation_type.hpp>
+namespace boost { namespace geometry { namespace strategy { namespace envelope
+{
-namespace boost { namespace geometry
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
{
-namespace strategy { 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)
+ {
+ geometry::detail::envelope::envelope_one_point
+ <
+ Dimension, DimensionCount
+ >::apply(p1, mbr);
+
+ strategy::expand::detail::point_loop
+ <
+ Dimension, DimensionCount
+ >::apply(mbr, p2);
+ }
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
template
<
@@ -30,21 +57,15 @@ template
>
class cartesian_segment
{
-public :
-
- template <typename Point1, typename Point2, typename Box>
- inline void
- apply(Point1 const& point1, Point2 const& point2, Box& box) const
+public:
+ template <typename Point, typename Box>
+ static inline void apply(Point const& point1, Point const& point2, Box& box)
{
- geometry::detail::envelope::envelope_one_segment
- <
- 0,
- dimension<Point1>::value
- >
- ::apply(point1,
- point2,
- box,
- strategy::envelope::cartesian_segment<CalculationType>());
+ strategy::envelope::detail::envelope_one_segment
+ <
+ 0,
+ dimension<Point>::value
+ >::apply(point1, point2, box);
}
};
@@ -55,7 +76,7 @@ namespace services
{
template <typename CalculationType>
-struct default_strategy<cartesian_tag, CalculationType>
+struct default_strategy<segment_tag, cartesian_tag, CalculationType>
{
typedef strategy::envelope::cartesian_segment<CalculationType> type;
};
diff --git a/boost/geometry/strategies/cartesian/expand_box.hpp b/boost/geometry/strategies/cartesian/expand_box.hpp
new file mode 100644
index 0000000000..68b8824f81
--- /dev/null
+++ b/boost/geometry/strategies/cartesian/expand_box.hpp
@@ -0,0 +1,69 @@
+// 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, 2016, 2017.
+// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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_STRATEGIES_CARTESIAN_EXPAND_BOX_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_BOX_HPP
+
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/detail/expand/indexed.hpp>
+
+#include <boost/geometry/strategies/expand.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace expand
+{
+
+struct cartesian_box
+{
+ template <typename BoxOut, typename BoxIn>
+ static void apply(BoxOut & box_out, BoxIn const& box_in)
+ {
+ geometry::detail::expand::expand_indexed
+ <
+ 0, dimension<BoxIn>::value
+ >::apply(box_out, box_in);
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+template <typename CalculationType>
+struct default_strategy<box_tag, cartesian_tag, CalculationType>
+{
+ typedef cartesian_box type;
+};
+
+
+} // namespace services
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::expand
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_BOX_HPP
diff --git a/boost/geometry/strategies/cartesian/expand_point.hpp b/boost/geometry/strategies/cartesian/expand_point.hpp
new file mode 100644
index 0000000000..87d82dca08
--- /dev/null
+++ b/boost/geometry/strategies/cartesian/expand_point.hpp
@@ -0,0 +1,125 @@
+// 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-2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// 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_STRATEGIES_CARTESIAN_EXPAND_POINT_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_POINT_HPP
+
+#include <cstddef>
+#include <functional>
+
+#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/select_coordinate_type.hpp>
+
+#include <boost/geometry/strategies/expand.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace expand
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <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 select_coordinate_type
+ <
+ Point, Box
+ >::type coordinate_type;
+
+ std::less<coordinate_type> less;
+ std::greater<coordinate_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<Dimension + 1, DimensionCount>::apply(box, source);
+ }
+};
+
+
+template <std::size_t DimensionCount>
+struct point_loop<DimensionCount, DimensionCount>
+{
+ template <typename Box, typename Point>
+ static inline void apply(Box&, Point const&) {}
+};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+struct cartesian_point
+{
+ template <typename Box, typename Point>
+ static void apply(Box & box, Point const& point)
+ {
+ expand::detail::point_loop
+ <
+ 0, dimension<Point>::value
+ >::apply(box, point);
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+template <typename CalculationType>
+struct default_strategy<point_tag, cartesian_tag, CalculationType>
+{
+ typedef cartesian_point type;
+};
+
+
+} // namespace services
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::expand
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_POINT_HPP
diff --git a/boost/geometry/strategies/cartesian/expand_segment.hpp b/boost/geometry/strategies/cartesian/expand_segment.hpp
new file mode 100644
index 0000000000..18fd9c9a78
--- /dev/null
+++ b/boost/geometry/strategies/cartesian/expand_segment.hpp
@@ -0,0 +1,71 @@
+// 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, 2016, 2017, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, 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_STRATEGIES_CARTESIAN_EXPAND_SEGMENT_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_SEGMENT_HPP
+
+
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/detail/expand/indexed.hpp>
+
+#include <boost/geometry/strategies/expand.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace expand
+{
+
+class cartesian_segment
+{
+public:
+ template <typename Box, typename Segment>
+ static void apply(Box & box, Segment const& segment)
+ {
+ geometry::detail::expand::expand_indexed
+ <
+ 0, dimension<Segment>::value
+ >::apply(box, segment);
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+template <typename CalculationType>
+struct default_strategy<segment_tag, cartesian_tag, CalculationType>
+{
+ typedef cartesian_segment type;
+};
+
+
+} // namespace services
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::expand
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_SEGMENT_HPP
diff --git a/boost/geometry/strategies/cartesian/intersection.hpp b/boost/geometry/strategies/cartesian/intersection.hpp
index 10fd73ba54..01d1c9433a 100644
--- a/boost/geometry/strategies/cartesian/intersection.hpp
+++ b/boost/geometry/strategies/cartesian/intersection.hpp
@@ -3,8 +3,8 @@
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2013-2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2014, 2016, 2017.
-// Modifications copyright (c) 2014-2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2016, 2017, 2018, 2019.
+// Modifications copyright (c) 2014-2019, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -34,8 +34,13 @@
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/strategies/cartesian/area.hpp>
+#include <boost/geometry/strategies/cartesian/disjoint_box_box.hpp>
+#include <boost/geometry/strategies/cartesian/disjoint_segment_box.hpp>
#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
-#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
+#include <boost/geometry/strategies/cartesian/envelope.hpp>
+#include <boost/geometry/strategies/cartesian/expand_box.hpp>
+#include <boost/geometry/strategies/cartesian/expand_segment.hpp>
+#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
#include <boost/geometry/strategies/cartesian/point_in_poly_winding.hpp>
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategies/covered_by.hpp>
@@ -132,14 +137,51 @@ struct cartesian_segments
return strategy_type();
}
- typedef envelope::cartesian_segment<CalculationType>
- envelope_strategy_type;
+ typedef envelope::cartesian<CalculationType> envelope_strategy_type;
static inline envelope_strategy_type get_envelope_strategy()
{
return envelope_strategy_type();
}
+ typedef expand::cartesian_segment expand_strategy_type;
+
+ static inline expand_strategy_type get_expand_strategy()
+ {
+ return expand_strategy_type();
+ }
+
+ typedef within::cartesian_point_point point_in_point_strategy_type;
+
+ static inline point_in_point_strategy_type get_point_in_point_strategy()
+ {
+ return point_in_point_strategy_type();
+ }
+
+ typedef within::cartesian_point_point equals_point_point_strategy_type;
+
+ static inline equals_point_point_strategy_type get_equals_point_point_strategy()
+ {
+ return equals_point_point_strategy_type();
+ }
+
+ typedef disjoint::cartesian_box_box disjoint_box_box_strategy_type;
+
+ static inline disjoint_box_box_strategy_type get_disjoint_box_box_strategy()
+ {
+ return disjoint_box_box_strategy_type();
+ }
+
+ typedef disjoint::segment_box disjoint_segment_box_strategy_type;
+
+ static inline disjoint_segment_box_strategy_type get_disjoint_segment_box_strategy()
+ {
+ return disjoint_segment_box_strategy_type();
+ }
+
+ typedef covered_by::cartesian_point_box disjoint_point_box_strategy_type;
+ typedef expand::cartesian_box expand_box_strategy_type;
+
template <typename CoordinateType, typename SegmentRatio>
struct segment_intersection_info
{
@@ -314,12 +356,12 @@ struct cartesian_segments
BOOST_CONCEPT_ASSERT( (concepts::ConstSegment<Segment2>) );
using geometry::detail::equals::equals_point_point;
- bool const a_is_point = equals_point_point(robust_a1, robust_a2);
- bool const b_is_point = equals_point_point(robust_b1, robust_b2);
+ bool const a_is_point = equals_point_point(robust_a1, robust_a2, point_in_point_strategy_type());
+ bool const b_is_point = equals_point_point(robust_b1, robust_b2, point_in_point_strategy_type());
if(a_is_point && b_is_point)
{
- return equals_point_point(robust_a1, robust_b2)
+ return equals_point_point(robust_a1, robust_b2, point_in_point_strategy_type())
? Policy::degenerate(a, true)
: Policy::disjoint()
;
diff --git a/boost/geometry/strategies/cartesian/line_interpolate.hpp b/boost/geometry/strategies/cartesian/line_interpolate.hpp
new file mode 100644
index 0000000000..ffad476ee4
--- /dev/null
+++ b/boost/geometry/strategies/cartesian/line_interpolate.hpp
@@ -0,0 +1,129 @@
+// Boost.Geometry
+
+// Copyright (c) 2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_LINE_INTERPOLATE_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_LINE_INTERPOLATE_HPP
+
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/strategies/line_interpolate.hpp>
+#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace line_interpolate
+{
+
+
+/*!
+\brief Interpolate point on a cartesian segment.
+\ingroup strategies
+\tparam CalculationType \tparam_calculation
+\tparam DistanceStrategy The underlying point-point distance strategy
+
+\qbk{
+[heading See also]
+\* [link geometry.reference.algorithms.line_interpolate.line_interpolate_4_with_strategy line_interpolate (with strategy)]
+}
+
+*/
+template
+<
+ typename CalculationType = void,
+ typename DistanceStrategy = distance::pythagoras<CalculationType>
+>
+class cartesian
+{
+public:
+
+ // point-point strategy getters
+ struct distance_pp_strategy
+ {
+ typedef DistanceStrategy type;
+ };
+
+ inline typename distance_pp_strategy::type get_distance_pp_strategy() const
+ {
+ typedef typename distance_pp_strategy::type distance_type;
+ return distance_type();
+ }
+
+ template <typename Point, typename Fraction, typename Distance>
+ inline void apply(Point const& p0,
+ Point const& p1,
+ Fraction const& fraction,
+ Point & p,
+ Distance const&) const
+ {
+ typedef typename select_calculation_type_alt
+ <
+ CalculationType,
+ Point
+ >::type calc_t;
+
+ typedef model::point
+ <
+ calc_t,
+ geometry::dimension<Point>::value,
+ cs::cartesian
+ > calc_point_t;
+
+ calc_point_t cp0, cp1;
+ geometry::detail::conversion::convert_point_to_point(p0, cp0);
+ geometry::detail::conversion::convert_point_to_point(p1, cp1);
+
+ //segment convex combination: p0*fraction + p1*(1-fraction)
+ Fraction const one_minus_fraction = 1-fraction;
+ for_each_coordinate(cp1, detail::value_operation
+ <
+ Fraction,
+ std::multiplies
+ >(fraction));
+ for_each_coordinate(cp0, detail::value_operation
+ <
+ Fraction,
+ std::multiplies
+ >(one_minus_fraction));
+ for_each_coordinate(cp1, detail::point_operation
+ <
+ calc_point_t,
+ std::plus
+ >(cp0));
+
+ assert_dimension_equal<calc_point_t, Point>();
+ geometry::detail::conversion::convert_point_to_point(cp1, p);
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <>
+struct default_strategy<cartesian_tag>
+{
+ typedef strategy::line_interpolate::cartesian<> type;
+};
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::line_interpolate
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_LINE_INTERPOLATE_HPP
diff --git a/boost/geometry/strategies/cartesian/point_in_box.hpp b/boost/geometry/strategies/cartesian/point_in_box.hpp
index 1c14125a6d..468e167c60 100644
--- a/boost/geometry/strategies/cartesian/point_in_box.hpp
+++ b/boost/geometry/strategies/cartesian/point_in_box.hpp
@@ -4,8 +4,8 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2015-2017.
-// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015-2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -22,6 +22,7 @@
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/strategies/covered_by.hpp>
#include <boost/geometry/strategies/within.hpp>
#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
@@ -33,6 +34,10 @@ namespace boost { namespace geometry { namespace strategy
namespace within
{
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
struct within_coord
{
template <typename Value1, typename Value2>
@@ -101,7 +106,7 @@ struct longitude_range
<
Value1, Value2
>::type calc_t;
- typedef typename coordinate_system<Geometry>::type::units units_t;
+ typedef typename geometry::detail::cs_angular_units<Geometry>::type units_t;
typedef math::detail::constants_on_spheroid<calc_t, units_t> constants;
if (CoordCheck::apply(value, min_value, max_value))
@@ -142,18 +147,16 @@ struct covered_by_range<Geometry, 0, spherical_tag>
template
<
template <typename, std::size_t, typename> class SubStrategy,
- typename Point,
- typename Box,
+ typename CSTag, // cartesian_tag or spherical_tag
std::size_t Dimension,
std::size_t DimensionCount
>
struct relate_point_box_loop
{
+ template <typename Point, typename Box>
static inline bool apply(Point const& point, Box const& box)
{
- typedef typename tag_cast<typename cs_tag<Point>::type, spherical_tag>::type cs_tag_t;
-
- if (! SubStrategy<Point, Dimension, cs_tag_t>::apply(get<Dimension>(point),
+ if (! SubStrategy<Point, Dimension, CSTag>::apply(get<Dimension>(point),
get<min_corner, Dimension>(box),
get<max_corner, Dimension>(box))
)
@@ -164,7 +167,7 @@ struct relate_point_box_loop
return relate_point_box_loop
<
SubStrategy,
- Point, Box,
+ CSTag,
Dimension + 1, DimensionCount
>::apply(point, box);
}
@@ -174,46 +177,52 @@ struct relate_point_box_loop
template
<
template <typename, std::size_t, typename> class SubStrategy,
- typename Point,
- typename Box,
+ typename CSTag,
std::size_t DimensionCount
>
-struct relate_point_box_loop<SubStrategy, Point, Box, DimensionCount, DimensionCount>
+struct relate_point_box_loop<SubStrategy, CSTag, DimensionCount, DimensionCount>
{
+ template <typename Point, typename Box>
static inline bool apply(Point const& , Box const& )
{
return true;
}
};
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
-template
-<
- typename Point,
- typename Box,
- template <typename, std::size_t, typename> class SubStrategy = within_range
->
-struct point_in_box
+struct cartesian_point_box
{
+ template <typename Point, typename Box>
static inline bool apply(Point const& point, Box const& box)
{
- return relate_point_box_loop
+ return detail::relate_point_box_loop
<
- SubStrategy,
- Point, Box,
- 0, dimension<Point>::type::value
+ detail::within_range,
+ cartesian_tag,
+ 0, dimension<Point>::value
>::apply(point, box);
}
};
-
-} // namespace within
+struct spherical_point_box
+{
+ template <typename Point, typename Box>
+ static inline bool apply(Point const& point, Box const& box)
+ {
+ return detail::relate_point_box_loop
+ <
+ detail::within_range,
+ spherical_tag,
+ 0, dimension<Point>::value
+ >::apply(point, box);
+ }
+};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-
-
-namespace within { namespace services
+namespace services
{
template <typename Point, typename Box>
@@ -225,7 +234,7 @@ struct default_strategy
cartesian_tag, cartesian_tag
>
{
- typedef within::point_in_box<Point, Box> type;
+ typedef within::cartesian_point_box type;
};
// spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
@@ -238,14 +247,49 @@ struct default_strategy
spherical_tag, spherical_tag
>
{
- typedef within::point_in_box<Point, Box> type;
+ typedef within::spherical_point_box type;
};
-}} // namespace within::services
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+} // namespace within
-namespace covered_by { namespace services
+namespace covered_by
+{
+
+struct cartesian_point_box
+{
+ template <typename Point, typename Box>
+ static inline bool apply(Point const& point, Box const& box)
+ {
+ return within::detail::relate_point_box_loop
+ <
+ within::detail::covered_by_range,
+ cartesian_tag,
+ 0, dimension<Point>::value
+ >::apply(point, box);
+ }
+};
+
+struct spherical_point_box
+{
+ template <typename Point, typename Box>
+ static inline bool apply(Point const& point, Box const& box)
+ {
+ return within::detail::relate_point_box_loop
+ <
+ within::detail::covered_by_range,
+ spherical_tag,
+ 0, dimension<Point>::value
+ >::apply(point, box);
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
{
@@ -258,11 +302,7 @@ struct default_strategy
cartesian_tag, cartesian_tag
>
{
- typedef within::point_in_box
- <
- Point, Box,
- within::covered_by_range
- > type;
+ typedef covered_by::cartesian_point_box type;
};
// spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
@@ -275,18 +315,15 @@ struct default_strategy
spherical_tag, spherical_tag
>
{
- typedef within::point_in_box
- <
- Point, Box,
- within::covered_by_range
- > type;
+ typedef covered_by::spherical_point_box type;
};
-}} // namespace covered_by::services
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+} // namespace covered_by
}}} // namespace boost::geometry::strategy
diff --git a/boost/geometry/strategies/cartesian/point_in_point.hpp b/boost/geometry/strategies/cartesian/point_in_point.hpp
new file mode 100644
index 0000000000..fc849dcd48
--- /dev/null
+++ b/boost/geometry/strategies/cartesian/point_in_point.hpp
@@ -0,0 +1,124 @@
+// 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) 2013-2015 Adam Wulkiewicz, Lodz, Poland
+
+// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018.
+// Modifications copyright (c) 2013-2018, 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.
+
+// 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_STRATEGY_CARTESIAN_POINT_IN_POINT_HPP
+#define BOOST_GEOMETRY_STRATEGY_CARTESIAN_POINT_IN_POINT_HPP
+
+#include <cstddef>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/strategies/covered_by.hpp>
+#include <boost/geometry/strategies/within.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace within
+{
+
+
+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 false;
+ }
+ return
+ point_point_generic<Dimension + 1, DimensionCount>::apply(p1, p2);
+ }
+};
+
+template <std::size_t DimensionCount>
+struct point_point_generic<DimensionCount, DimensionCount>
+{
+ template <typename Point1, typename Point2>
+ static inline bool apply(Point1 const&, Point2 const& )
+ {
+ return true;
+ }
+};
+
+}} // namespace detail::within
+#endif // DOXYGEN_NO_DETAIL
+
+
+namespace strategy { namespace within
+{
+
+struct cartesian_point_point
+{
+ template <typename Point1, typename Point2>
+ static inline bool apply(Point1 const& point1, Point2 const& point2)
+ {
+ return geometry::detail::within::point_point_generic
+ <
+ 0, dimension<Point1>::type::value
+ >::apply(point1, point2);
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename PointLike1, typename PointLike2, typename Tag1, typename Tag2>
+struct default_strategy<PointLike1, PointLike2, Tag1, Tag2, pointlike_tag, pointlike_tag, cartesian_tag, cartesian_tag>
+{
+ typedef strategy::within::cartesian_point_point type;
+};
+
+} // namespace services
+#endif
+
+
+}} // namespace strategy::within
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace strategy { namespace covered_by { namespace services
+{
+
+template <typename PointLike1, typename PointLike2, typename Tag1, typename Tag2>
+struct default_strategy<PointLike1, PointLike2, Tag1, Tag2, pointlike_tag, pointlike_tag, cartesian_tag, cartesian_tag>
+{
+ typedef strategy::within::cartesian_point_point type;
+};
+
+}}} // namespace strategy::covered_by::services
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGY_CARTESIAN_POINT_IN_POINT_HPP
diff --git a/boost/geometry/strategies/cartesian/point_in_poly_crossings_multiply.hpp b/boost/geometry/strategies/cartesian/point_in_poly_crossings_multiply.hpp
index 94da5cc677..a8e0de7b7a 100644
--- a/boost/geometry/strategies/cartesian/point_in_poly_crossings_multiply.hpp
+++ b/boost/geometry/strategies/cartesian/point_in_poly_crossings_multiply.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -15,6 +20,7 @@
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_POLY_CROSSINGS_MULTIPLY_HPP
+#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
diff --git a/boost/geometry/strategies/cartesian/point_in_poly_franklin.hpp b/boost/geometry/strategies/cartesian/point_in_poly_franklin.hpp
index a774d3c52d..16e7987472 100644
--- a/boost/geometry/strategies/cartesian/point_in_poly_franklin.hpp
+++ b/boost/geometry/strategies/cartesian/point_in_poly_franklin.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -15,6 +20,7 @@
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_POLY_FRANKLIN_HPP
+#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
diff --git a/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp b/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp
index c41bc9b83d..696a86c984 100644
--- a/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp
+++ b/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp
@@ -3,8 +3,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013, 2014, 2016, 2017.
-// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2016, 2017, 2018.
+// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@@ -23,6 +23,8 @@
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
+#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
+#include <boost/geometry/strategies/cartesian/disjoint_box_box.hpp>
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategies/covered_by.hpp>
#include <boost/geometry/strategies/within.hpp>
@@ -42,8 +44,6 @@ namespace strategy { namespace within
\tparam PointOfSegment \tparam_segment_point
\tparam CalculationType \tparam_calculation
\author Barend Gehrels
-\note The implementation is inspired by terralib http://www.terralib.org (LGPL)
-\note but totally revised afterwards, especially for cases on segments
\qbk{
[heading See also]
@@ -103,6 +103,20 @@ public:
return side_strategy_type::get_disjoint_strategy();
}
+ typedef typename side_strategy_type::equals_point_point_strategy_type equals_point_point_strategy_type;
+ static inline equals_point_point_strategy_type get_equals_point_point_strategy()
+ {
+ return side_strategy_type::get_equals_point_point_strategy();
+ }
+
+ typedef disjoint::cartesian_box_box disjoint_box_box_strategy_type;
+ static inline disjoint_box_box_strategy_type get_disjoint_box_box_strategy()
+ {
+ return disjoint_box_box_strategy_type();
+ }
+
+ typedef covered_by::cartesian_point_box disjoint_point_box_strategy_type;
+
// Typedefs and static methods to fulfill the concept
typedef Point point_type;
typedef PointOfSegment segment_point_type;
diff --git a/boost/geometry/strategies/cartesian/side_by_triangle.hpp b/boost/geometry/strategies/cartesian/side_by_triangle.hpp
index 91bbee7bb2..9760f560c7 100644
--- a/boost/geometry/strategies/cartesian/side_by_triangle.hpp
+++ b/boost/geometry/strategies/cartesian/side_by_triangle.hpp
@@ -4,8 +4,8 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2015, 2017.
-// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2017, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -29,7 +29,8 @@
#include <boost/geometry/util/select_coordinate_type.hpp>
#include <boost/geometry/strategies/cartesian/disjoint_segment_box.hpp>
-#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
+#include <boost/geometry/strategies/cartesian/envelope.hpp>
+#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
#include <boost/geometry/strategies/compare.hpp>
#include <boost/geometry/strategies/side.hpp>
@@ -70,7 +71,7 @@ class side_by_triangle
};
public :
- typedef strategy::envelope::cartesian_segment<CalculationType> envelope_strategy_type;
+ typedef strategy::envelope::cartesian<CalculationType> envelope_strategy_type;
static inline envelope_strategy_type get_envelope_strategy()
{
@@ -84,6 +85,12 @@ public :
return disjoint_strategy_type();
}
+ typedef strategy::within::cartesian_point_point equals_point_point_strategy_type;
+ static inline equals_point_point_strategy_type get_equals_point_point_strategy()
+ {
+ return equals_point_point_strategy_type();
+ }
+
// Template member function, because it is not always trivial
// or convenient to explicitly mention the typenames in the
// strategy-struct itself.
@@ -166,9 +173,9 @@ public :
// For robustness purposes, first check if any two points are
// the same; in this case simply return that the points are
// collinear
- if (geometry::detail::equals::equals_point_point(p1, p2)
- || geometry::detail::equals::equals_point_point(p1, p)
- || geometry::detail::equals::equals_point_point(p2, p))
+ if (equals_point_point(p1, p2)
+ || equals_point_point(p1, p)
+ || equals_point_point(p2, p))
{
return PromotedType(0);
}
@@ -258,6 +265,13 @@ public :
: -1;
}
+private:
+ template <typename P1, typename P2>
+ static inline bool equals_point_point(P1 const& p1, P2 const& p2)
+ {
+ typedef equals_point_point_strategy_type strategy_t;
+ return geometry::detail::equals::equals_point_point(p1, p2, strategy_t());
+ }
};
diff --git a/boost/geometry/strategies/cartesian/side_of_intersection.hpp b/boost/geometry/strategies/cartesian/side_of_intersection.hpp
index db57644ad5..9c0a5f0d3b 100644
--- a/boost/geometry/strategies/cartesian/side_of_intersection.hpp
+++ b/boost/geometry/strategies/cartesian/side_of_intersection.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2019.
+// Modifications copyright (c) 2015-2019, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -118,6 +118,7 @@ struct multiplicable_integral
return b < a;
}
+#ifdef BOOST_GEOMETRY_SIDE_OF_INTERSECTION_DEBUG
template <typename CmpVal>
void check_value(CmpVal const& cmp_val) const
{
@@ -125,6 +126,7 @@ struct multiplicable_integral
CmpVal val = CmpVal(m_sign) * (CmpVal(m_ms) * CmpVal(b) + CmpVal(m_ls));
BOOST_GEOMETRY_ASSERT(cmp_val == val);
}
+#endif // BOOST_GEOMETRY_SIDE_OF_INTERSECTION_DEBUG
};
} // namespace detail
diff --git a/boost/geometry/strategies/concepts/area_concept.hpp b/boost/geometry/strategies/concepts/area_concept.hpp
index 6edc516f92..da983bac57 100644
--- a/boost/geometry/strategies/concepts/area_concept.hpp
+++ b/boost/geometry/strategies/concepts/area_concept.hpp
@@ -5,6 +5,10 @@
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018 Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -19,6 +23,9 @@
#include <boost/concept_check.hpp>
#include <boost/core/ignore_unused.hpp>
+#include <boost/geometry/geometries/point.hpp>
+
+
namespace boost { namespace geometry { namespace concepts
{
diff --git a/boost/geometry/strategies/concepts/distance_concept.hpp b/boost/geometry/strategies/concepts/distance_concept.hpp
index 0064d438d5..ea811d921b 100644
--- a/boost/geometry/strategies/concepts/distance_concept.hpp
+++ b/boost/geometry/strategies/concepts/distance_concept.hpp
@@ -4,10 +4,11 @@
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2018.
+// Modifications copyright (c) 2014, 2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -33,6 +34,7 @@
#include <boost/geometry/geometries/segment.hpp>
#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/tags.hpp>
diff --git a/boost/geometry/strategies/concepts/within_concept.hpp b/boost/geometry/strategies/concepts/within_concept.hpp
index c02d0dc50f..e8b0b767ac 100644
--- a/boost/geometry/strategies/concepts/within_concept.hpp
+++ b/boost/geometry/strategies/concepts/within_concept.hpp
@@ -4,6 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018 Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -20,6 +24,13 @@
#include <boost/core/ignore_unused.hpp>
#include <boost/function_types/result_type.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tag_cast.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/geometries/concepts/box_concept.hpp>
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+
#include <boost/geometry/util/parameter_type_of.hpp>
@@ -107,7 +118,7 @@ public :
#endif
};
-template <typename Strategy>
+template <typename Point, typename Box, typename Strategy>
class WithinStrategyPointBox
{
#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
@@ -165,7 +176,7 @@ class WithinStrategyPointBox
public :
BOOST_CONCEPT_USAGE(WithinStrategyPointBox)
{
- checker::apply(&Strategy::apply);
+ checker::apply(&Strategy::template apply<Point, Box>);
}
#endif
};
@@ -241,26 +252,36 @@ namespace within
namespace dispatch
{
-template <typename FirstTag, typename SecondTag, typename CastedTag, typename Strategy>
+template
+<
+ typename Geometry1, typename Geometry2,
+ typename FirstTag, typename SecondTag, typename CastedTag,
+ typename Strategy
+>
struct check_within
{};
-template <typename AnyTag, typename Strategy>
-struct check_within<point_tag, AnyTag, areal_tag, Strategy>
+template
+<
+ typename Geometry1, typename Geometry2,
+ typename AnyTag,
+ typename Strategy
+>
+struct check_within<Geometry1, Geometry2, point_tag, AnyTag, areal_tag, Strategy>
{
BOOST_CONCEPT_ASSERT( (WithinStrategyPolygonal<Strategy>) );
};
-template <typename Strategy>
-struct check_within<point_tag, box_tag, areal_tag, Strategy>
+template <typename Geometry1, typename Geometry2, typename Strategy>
+struct check_within<Geometry1, Geometry2, point_tag, box_tag, areal_tag, Strategy>
{
- BOOST_CONCEPT_ASSERT( (WithinStrategyPointBox<Strategy>) );
+ BOOST_CONCEPT_ASSERT( (WithinStrategyPointBox<Geometry1, Geometry2, Strategy>) );
};
-template <typename Strategy>
-struct check_within<box_tag, box_tag, areal_tag, Strategy>
+template <typename Geometry1, typename Geometry2, typename Strategy>
+struct check_within<Geometry1, Geometry2, box_tag, box_tag, areal_tag, Strategy>
{
BOOST_CONCEPT_ASSERT( (WithinStrategyBoxBox<Strategy>) );
};
@@ -274,10 +295,18 @@ struct check_within<box_tag, box_tag, areal_tag, Strategy>
\brief Checks, in compile-time, the concept of any within-strategy
\ingroup concepts
*/
-template <typename FirstTag, typename SecondTag, typename CastedTag, typename Strategy>
+template <typename Geometry1, typename Geometry2, typename Strategy>
inline void check()
{
- dispatch::check_within<FirstTag, SecondTag, CastedTag, Strategy> c;
+ dispatch::check_within
+ <
+ Geometry1,
+ Geometry2,
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
+ Strategy
+ > c;
boost::ignore_unused(c);
}
diff --git a/boost/geometry/strategies/convex_hull.hpp b/boost/geometry/strategies/convex_hull.hpp
index f4edc5ba3f..8208a4eb9f 100644
--- a/boost/geometry/strategies/convex_hull.hpp
+++ b/boost/geometry/strategies/convex_hull.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -14,6 +19,7 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_HPP
#define BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_HPP
+#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/strategies/tags.hpp>
diff --git a/boost/geometry/strategies/disjoint.hpp b/boost/geometry/strategies/disjoint.hpp
index 23d2cede49..c111d2b8f5 100644
--- a/boost/geometry/strategies/disjoint.hpp
+++ b/boost/geometry/strategies/disjoint.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry
-// Copyright (c) 2017, Oracle and/or its affiliates.
+// Copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -77,13 +77,6 @@ struct default_strategy<Box, MultiPoint, box_tag, multi_point_tag, 2, 0>
>
{};
-template <typename Box1, typename Box2>
-struct default_strategy<Box1, Box2, box_tag, box_tag, 2, 2>
-{
- // dummy strategy which will be ignored
- typedef geometry::default_strategy type;
-};
-
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
diff --git a/boost/geometry/strategies/envelope.hpp b/boost/geometry/strategies/envelope.hpp
index fde9c858a6..050ed4658c 100644
--- a/boost/geometry/strategies/envelope.hpp
+++ b/boost/geometry/strategies/envelope.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2016-2017 Oracle and/or its affiliates.
+// Copyright (c) 2016-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -23,16 +23,17 @@ namespace strategy { namespace envelope { namespace services
/*!
\brief Traits class binding a default envelope strategy to a coordinate system
\ingroup util
+\tparam Tag tag of geometry
\tparam CSTag tag of coordinate system
\tparam CalculationType \tparam_calculation
*/
-template <typename CSTag, typename CalculationType = void>
+template <typename Tag, typename CSTag, typename CalculationType = void>
struct default_strategy
{
BOOST_MPL_ASSERT_MSG
(
false, NOT_IMPLEMENTED_FOR_THIS_TYPE
- , (types<CSTag>)
+ , (types<Tag, CSTag>)
);
};
diff --git a/boost/geometry/strategies/expand.hpp b/boost/geometry/strategies/expand.hpp
new file mode 100644
index 0000000000..39d4145144
--- /dev/null
+++ b/boost/geometry/strategies/expand.hpp
@@ -0,0 +1,45 @@
+// Boost.Geometry
+
+// Copyright (c) 2018 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_STRATEGIES_EXPAND_HPP
+#define BOOST_GEOMETRY_STRATEGIES_EXPAND_HPP
+
+#include <boost/mpl/assert.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+namespace strategy { namespace expand { namespace services
+{
+
+/*!
+\brief Traits class binding a default envelope strategy to a coordinate system
+\ingroup util
+\tparam Tag tag of geometry
+\tparam CSTag tag of coordinate system
+\tparam CalculationType \tparam_calculation
+*/
+template <typename Tag, typename CSTag, typename CalculationType = void>
+struct default_strategy
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_TYPE
+ , (types<Tag, CSTag>)
+ );
+};
+
+}}} // namespace strategy::expand::services
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_EXPAND_HPP
+
diff --git a/boost/geometry/strategies/geographic/area.hpp b/boost/geometry/strategies/geographic/area.hpp
index ac7d933ce7..d40a30cf22 100644
--- a/boost/geometry/strategies/geographic/area.hpp
+++ b/boost/geometry/strategies/geographic/area.hpp
@@ -20,6 +20,7 @@
#include <boost/geometry/formulas/authalic_radius_sqr.hpp>
#include <boost/geometry/formulas/eccentricity_sqr.hpp>
+#include <boost/geometry/strategies/area.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
diff --git a/boost/geometry/strategies/geographic/buffer_point_circle.hpp b/boost/geometry/strategies/geographic/buffer_point_circle.hpp
new file mode 100644
index 0000000000..7e7c8fe81d
--- /dev/null
+++ b/boost/geometry/strategies/geographic/buffer_point_circle.hpp
@@ -0,0 +1,127 @@
+// Boost.Geometry
+
+// Copyright (c) 2018-2019 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_STRATEGIES_GEOGRAPHIC_BUFFER_POINT_CIRCLE_HPP
+#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_BUFFER_POINT_CIRCLE_HPP
+
+#include <cstddef>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/strategies/buffer.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace buffer
+{
+
+/*!
+\brief Create a circular buffer around a point, on the Earth
+\ingroup strategies
+\details This strategy can be used as PointStrategy for the buffer algorithm.
+ It creates a circular buffer around a point, on the Earth. It can be applied
+ for points and multi_points.
+
+\qbk{
+[heading Example]
+[buffer_geographic_point_circle]
+[buffer_geographic_point_circle_output]
+[heading See also]
+\* [link geometry.reference.algorithms.buffer.buffer_7_with_strategies buffer (with strategies)]
+\* [link geometry.reference.strategies.strategy_buffer_point_circle point_circle]
+\* [link geometry.reference.strategies.strategy_buffer_point_square point_square]
+}
+ */
+template
+<
+ typename FormulaPolicy = strategy::andoyer,
+ typename Spheroid = srs::spheroid<double>,
+ typename CalculationType = void
+>
+class geographic_point_circle
+{
+public :
+ //! \brief Constructs the strategy
+ //! \param count number of points for the created circle (if count
+ //! is smaller than 3, count is internally set to 3)
+ explicit geographic_point_circle(std::size_t count = 90)
+ : m_count((count < 3u) ? 3u : count)
+ {}
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+ //! Fills output_range with a circle around point using distance_strategy
+ template
+ <
+ typename Point,
+ typename OutputRange,
+ typename DistanceStrategy
+ >
+ inline void apply(Point const& point,
+ DistanceStrategy const& distance_strategy,
+ OutputRange& output_range) const
+ {
+ typedef typename boost::range_value<OutputRange>::type output_point_type;
+
+ typedef typename select_most_precise
+ <
+ typename geometry::coordinate_type<Point>::type,
+ typename geometry::coordinate_type<output_point_type>::type,
+ CalculationType
+ //double
+ >::type calculation_type;
+
+ calculation_type const buffer_distance = distance_strategy.apply(point, point,
+ strategy::buffer::buffer_side_left);
+
+ typedef typename FormulaPolicy::template direct
+ <
+ calculation_type, true, false, false, false
+ > direct_t;
+
+ calculation_type const two_pi = geometry::math::two_pi<calculation_type>();
+
+ calculation_type const diff = two_pi / calculation_type(m_count);
+ // TODO: after calculation of some angles is corrected,
+ // we can start at 0.0
+ calculation_type angle = 0.001;
+
+ for (std::size_t i = 0; i < m_count; i++, angle += diff)
+ {
+ typename direct_t::result_type
+ dir_r = direct_t::apply(get_as_radian<0>(point), get_as_radian<1>(point),
+ buffer_distance, angle,
+ m_spheroid);
+ output_point_type p;
+ set_from_radian<0>(p, dir_r.lon2);
+ set_from_radian<1>(p, dir_r.lat2);
+ output_range.push_back(p);
+ }
+
+ {
+ // Close the range
+ const output_point_type p = output_range.front();
+ output_range.push_back(p);
+ }
+ }
+#endif // DOXYGEN_SHOULD_SKIP_THIS
+
+private :
+ std::size_t m_count;
+ Spheroid m_spheroid;
+};
+
+
+}} // namespace strategy::buffer
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_BUFFER_POINT_CIRCLE_HPP
diff --git a/boost/geometry/strategies/geographic/disjoint_segment_box.hpp b/boost/geometry/strategies/geographic/disjoint_segment_box.hpp
index afc9d66775..49c80a5e78 100644
--- a/boost/geometry/strategies/geographic/disjoint_segment_box.hpp
+++ b/boost/geometry/strategies/geographic/disjoint_segment_box.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry
-// Copyright (c) 2017 Oracle and/or its affiliates.
+// Copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -29,9 +29,14 @@
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
#include <boost/geometry/algorithms/detail/disjoint/segment_box.hpp>
+#include <boost/geometry/srs/spheroid.hpp>
+
#include <boost/geometry/strategies/disjoint.hpp>
#include <boost/geometry/strategies/geographic/azimuth.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
+#include <boost/geometry/strategies/normalize.hpp>
+#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
+#include <boost/geometry/strategies/spherical/disjoint_box_box.hpp>
namespace boost { namespace geometry { namespace strategy { namespace disjoint
@@ -89,7 +94,13 @@ public:
> azimuth_geographic(m_spheroid);
return geometry::detail::disjoint::disjoint_segment_box_sphere_or_spheroid
- <geographic_tag>::apply(segment, box, azimuth_geographic);
+ <
+ geographic_tag
+ >::apply(segment, box,
+ azimuth_geographic,
+ strategy::normalize::spherical_point(),
+ strategy::covered_by::spherical_point_box(),
+ strategy::disjoint::spherical_box_box());
}
private:
diff --git a/boost/geometry/strategies/geographic/distance_cross_track.hpp b/boost/geometry/strategies/geographic/distance_cross_track.hpp
index f84bb4134f..53942529bf 100644
--- a/boost/geometry/strategies/geographic/distance_cross_track.hpp
+++ b/boost/geometry/strategies/geographic/distance_cross_track.hpp
@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2016-2017, Oracle and/or its affiliates.
+// Copyright (c) 2016-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -27,7 +28,9 @@
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/concepts/distance_concept.hpp>
+#include <boost/geometry/strategies/spherical/distance_cross_track.hpp>
#include <boost/geometry/strategies/spherical/distance_haversine.hpp>
+#include <boost/geometry/strategies/spherical/point_in_point.hpp>
#include <boost/geometry/strategies/geographic/azimuth.hpp>
#include <boost/geometry/strategies/geographic/distance.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
@@ -84,6 +87,8 @@ template
class geographic_cross_track
{
public :
+ typedef within::spherical_point_point equals_point_point_strategy_type;
+
template <typename Point, typename PointOfSegment>
struct return_type
: promote_floating_point
@@ -105,7 +110,7 @@ public :
inline typename return_type<Point, PointOfSegment>::type
apply(Point const& p, PointOfSegment const& sp1, PointOfSegment const& sp2) const
{
- typedef typename coordinate_system<Point>::type::units units_type;
+ typedef typename geometry::detail::cs_angular_units<Point>::type units_type;
return (apply<units_type>(get<0>(sp1), get<1>(sp1),
get<0>(sp2), get<1>(sp2),
@@ -404,7 +409,7 @@ private :
return non_iterative_case(lon2, lat2, lon3, lat3, spheroid);
}
- // Guess s14 (SPHERICAL)
+ // Guess s14 (SPHERICAL) aka along-track distance
typedef geometry::model::point
<
CT, 2,
@@ -420,7 +425,12 @@ private :
geometry::strategy::distance::haversine<CT> str(earth_radius);
CT s13 = str.apply(p1, p3);
- CT s14 = acos( cos(s13/earth_radius) / cos(s34/earth_radius) ) * earth_radius;
+
+ //CT s14 = acos( cos(s13/earth_radius) / cos(s34/earth_radius) ) * earth_radius;
+ CT cos_frac = cos(s13/earth_radius) / cos(s34/earth_radius);
+ CT s14 = cos_frac >= 1 ? CT(0)
+ : cos_frac <= -1 ? pi * earth_radius
+ : acos(cos_frac) * earth_radius;
#ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK
std::cout << "s34=" << s34 << std::endl;
@@ -638,15 +648,11 @@ template
>
struct get_comparable<geographic_cross_track<FormulaPolicy, Spheroid, CalculationType> >
{
- typedef typename comparable_type
- <
- geographic_cross_track<FormulaPolicy, Spheroid, CalculationType>
- >::type comparable_type;
public :
- static inline comparable_type
- apply(geographic_cross_track<FormulaPolicy, Spheroid, CalculationType> const& )
+ static inline geographic_cross_track<FormulaPolicy, Spheroid, CalculationType>
+ apply(geographic_cross_track<FormulaPolicy, Spheroid, CalculationType> const& strategy)
{
- return comparable_type();
+ return strategy;
}
};
diff --git a/boost/geometry/strategies/geographic/distance_cross_track_box_box.hpp b/boost/geometry/strategies/geographic/distance_cross_track_box_box.hpp
index 8e48fbf19a..2bc33096ad 100644
--- a/boost/geometry/strategies/geographic/distance_cross_track_box_box.hpp
+++ b/boost/geometry/strategies/geographic/distance_cross_track_box_box.hpp
@@ -25,6 +25,8 @@
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/concepts/distance_concept.hpp>
+#include <boost/geometry/strategies/geographic/distance.hpp>
+#include <boost/geometry/strategies/geographic/distance_cross_track.hpp>
#include <boost/geometry/strategies/spherical/distance_cross_track.hpp>
#include <boost/geometry/strategies/spherical/distance_cross_track_box_box.hpp>
@@ -171,13 +173,11 @@ struct comparable_type<geographic_cross_track_box_box<Strategy, Spheroid, Calcul
template <typename Strategy, typename Spheroid, typename CalculationType>
struct get_comparable<geographic_cross_track_box_box<Strategy, Spheroid, CalculationType> >
{
- typedef geographic_cross_track_box_box<Strategy, Spheroid, CalculationType> this_strategy;
- typedef typename comparable_type<this_strategy>::type comparable_type;
-
public:
- static inline comparable_type apply(this_strategy const& /*strategy*/)
+ static inline geographic_cross_track_box_box<Strategy, Spheroid, CalculationType>
+ apply(geographic_cross_track_box_box<Strategy, Spheroid, CalculationType> const& str)
{
- return comparable_type();
+ return str;
}
};
diff --git a/boost/geometry/strategies/geographic/distance_cross_track_point_box.hpp b/boost/geometry/strategies/geographic/distance_cross_track_point_box.hpp
index 4508d5acb5..b6694b4e02 100644
--- a/boost/geometry/strategies/geographic/distance_cross_track_point_box.hpp
+++ b/boost/geometry/strategies/geographic/distance_cross_track_point_box.hpp
@@ -157,13 +157,11 @@ struct comparable_type<geographic_cross_track_point_box<Strategy, Spheroid, Calc
template <typename Strategy, typename Spheroid, typename CalculationType>
struct get_comparable<geographic_cross_track_point_box<Strategy, Spheroid, CalculationType> >
{
- typedef geographic_cross_track_point_box<Strategy, Spheroid, CalculationType> this_strategy;
- typedef typename comparable_type<this_strategy>::type comparable_type;
-
public:
- static inline comparable_type apply(this_strategy const&)
+ static inline geographic_cross_track_point_box<Strategy, Spheroid, CalculationType>
+ apply(geographic_cross_track_point_box<Strategy, Spheroid, CalculationType> const& str)
{
- return comparable_type();
+ return str;
}
};
diff --git a/boost/geometry/strategies/geographic/distance_segment_box.hpp b/boost/geometry/strategies/geographic/distance_segment_box.hpp
index 6bde78ca27..615f938739 100644
--- a/boost/geometry/strategies/geographic/distance_segment_box.hpp
+++ b/boost/geometry/strategies/geographic/distance_segment_box.hpp
@@ -1,7 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2018 Oracle and/or its affiliates.
+// Copyright (c) 2018-2019 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -10,8 +11,22 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_SEGMENT_BOX_HPP
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_SEGMENT_BOX_HPP
+#include <boost/geometry/srs/spheroid.hpp>
+
#include <boost/geometry/algorithms/detail/distance/segment_to_box.hpp>
+#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/strategies/geographic/parameters.hpp>
+#include <boost/geometry/strategies/geographic/azimuth.hpp>
+#include <boost/geometry/strategies/geographic/distance_cross_track.hpp>
+#include <boost/geometry/strategies/normalize.hpp>
+#include <boost/geometry/strategies/spherical/disjoint_box_box.hpp>
+#include <boost/geometry/strategies/spherical/distance_segment_box.hpp>
+#include <boost/geometry/strategies/spherical/point_in_point.hpp>
+
+#include <boost/geometry/util/promote_floating_point.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+
namespace boost { namespace geometry
{
@@ -68,6 +83,13 @@ struct geographic_segment_box
return distance_type(m_spheroid);
}
+ typedef within::spherical_point_point equals_point_point_strategy_type;
+
+ static inline equals_point_point_strategy_type get_equals_point_point_strategy()
+ {
+ return equals_point_point_strategy_type();
+ }
+
//constructor
explicit geographic_segment_box(Spheroid const& spheroid = Spheroid())
@@ -107,7 +129,10 @@ struct geographic_segment_box
ReturnType
>(p0,p1,top_left,top_right,bottom_left,bottom_right,
geographic_segment_box<FormulaPolicy, Spheroid, CalculationType>(),
- az_strategy, es_strategy);
+ az_strategy, es_strategy,
+ normalize::spherical_point(),
+ covered_by::spherical_point_box(),
+ disjoint::spherical_box_box());
}
template <typename SPoint, typename BPoint>
diff --git a/boost/geometry/strategies/geographic/envelope.hpp b/boost/geometry/strategies/geographic/envelope.hpp
new file mode 100644
index 0000000000..4623f1a6cd
--- /dev/null
+++ b/boost/geometry/strategies/geographic/envelope.hpp
@@ -0,0 +1,116 @@
+// 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, 2016, 2018, 2019.
+// Modifications copyright (c) 2015-2019, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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_STRATEGIES_GEOGRAPHIC_ENVELOPE_HPP
+#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_ENVELOPE_HPP
+
+#include <boost/geometry/srs/spheroid.hpp>
+
+#include <boost/geometry/strategies/geographic/envelope_segment.hpp>
+#include <boost/geometry/strategies/geographic/expand_segment.hpp>
+#include <boost/geometry/strategies/geographic/parameters.hpp>
+#include <boost/geometry/strategies/spherical/envelope.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace envelope
+{
+
+
+template
+<
+ typename FormulaPolicy = strategy::andoyer,
+ typename Spheroid = geometry::srs::spheroid<double>,
+ typename CalculationType = void
+>
+class geographic
+ : public spherical<CalculationType>
+{
+public:
+ typedef Spheroid model_type;
+
+ inline geographic()
+ : m_spheroid()
+ {}
+
+ explicit inline geographic(Spheroid const& spheroid)
+ : m_spheroid(spheroid)
+ {}
+
+ typedef geographic_segment
+ <
+ FormulaPolicy, Spheroid, CalculationType
+ > element_envelope_strategy_type;
+ inline element_envelope_strategy_type get_element_envelope_strategy() const
+ {
+ return element_envelope_strategy_type(m_spheroid);
+ }
+
+ typedef expand::geographic_segment
+ <
+ FormulaPolicy, Spheroid, CalculationType
+ > element_expand_strategy_type;
+ inline element_expand_strategy_type get_element_expand_strategy() const
+ {
+ return element_expand_strategy_type(m_spheroid);
+ }
+
+ template <typename Point1, typename Point2, typename Box>
+ inline void apply(Point1 const& point1, Point2 const& point2, Box& box) const
+ {
+ geographic_segment
+ <
+ FormulaPolicy,
+ Spheroid,
+ CalculationType
+ >(m_spheroid).apply(point1, point2, box);
+ }
+
+private:
+ Spheroid m_spheroid;
+};
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+template <typename Tag, typename CalculationType>
+struct default_strategy<Tag, geographic_tag, CalculationType>
+{
+ typedef strategy::envelope::geographic
+ <
+ strategy::andoyer,
+ geometry::srs::spheroid<double>,
+ CalculationType
+ > type;
+};
+
+}
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::envelope
+
+}} //namepsace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_ENVELOPE_HPP
diff --git a/boost/geometry/strategies/geographic/envelope_segment.hpp b/boost/geometry/strategies/geographic/envelope_segment.hpp
index 5bada63f63..fda7868af2 100644
--- a/boost/geometry/strategies/geographic/envelope_segment.hpp
+++ b/boost/geometry/strategies/geographic/envelope_segment.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2017 Oracle and/or its affiliates.
+// Copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -12,15 +12,15 @@
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_ENVELOPE_SEGMENT_HPP
-#include <boost/geometry/algorithms/detail/envelope/segment.hpp>
-#include <boost/geometry/algorithms/detail/normalize.hpp>
-
#include <boost/geometry/srs/spheroid.hpp>
+#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
#include <boost/geometry/strategies/envelope.hpp>
#include <boost/geometry/strategies/geographic/azimuth.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
-
+#include <boost/geometry/strategies/normalize.hpp>
+#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
+#include <boost/geometry/strategies/spherical/expand_box.hpp>
namespace boost { namespace geometry
{
@@ -47,11 +47,18 @@ public:
: m_spheroid(spheroid)
{}
- template <typename Point1, typename Point2, typename Box>
- inline void apply(Point1 const& point1, Point2 const& point2, Box& box) const
+ typedef strategy::expand::spherical_box box_expand_strategy_type;
+ static inline box_expand_strategy_type get_box_expand_strategy()
{
- Point1 p1_normalized = detail::return_normalized<Point1>(point1);
- Point2 p2_normalized = detail::return_normalized<Point2>(point2);
+ return box_expand_strategy_type();
+ }
+
+ template <typename Point, typename Box>
+ inline void apply(Point const& point1, Point const& point2, Box& box) const
+ {
+ Point p1_normalized, p2_normalized;
+ strategy::normalize::spherical_point::apply(point1, p1_normalized);
+ strategy::normalize::spherical_point::apply(point2, p2_normalized);
geometry::strategy::azimuth::geographic
<
@@ -60,9 +67,13 @@ public:
CalculationType
> azimuth_geographic(m_spheroid);
- typedef typename coordinate_system<Point1>::type::units units_type;
+ typedef typename geometry::detail::cs_angular_units
+ <
+ Point
+ >::type units_type;
- detail::envelope::envelope_segment_impl
+ // first compute the envelope range for the first two coordinates
+ strategy::envelope::detail::envelope_segment_impl
<
geographic_tag
>::template apply<units_type>(geometry::get<0>(p1_normalized),
@@ -72,6 +83,12 @@ public:
box,
azimuth_geographic);
+ // now compute the envelope range for coordinates of
+ // dimension 2 and higher
+ strategy::envelope::detail::envelope_one_segment
+ <
+ 2, dimension<Point>::value
+ >::apply(point1, point2, box);
}
private:
@@ -84,7 +101,7 @@ namespace services
{
template <typename CalculationType>
-struct default_strategy<geographic_tag, CalculationType>
+struct default_strategy<segment_tag, geographic_tag, CalculationType>
{
typedef strategy::envelope::geographic_segment
<
diff --git a/boost/geometry/strategies/geographic/expand_segment.hpp b/boost/geometry/strategies/geographic/expand_segment.hpp
new file mode 100644
index 0000000000..66779c1099
--- /dev/null
+++ b/boost/geometry/strategies/geographic/expand_segment.hpp
@@ -0,0 +1,102 @@
+// 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, 2016, 2017, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, 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_STRATEGIES_GEOGRAPHIC_EXPAND_SEGMENT_HPP
+#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_EXPAND_SEGMENT_HPP
+
+#include <cstddef>
+#include <functional>
+
+#include <boost/geometry/core/access.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/srs/spheroid.hpp>
+
+#include <boost/geometry/strategies/expand.hpp>
+#include <boost/geometry/strategies/geographic/envelope_segment.hpp>
+#include <boost/geometry/strategies/geographic/parameters.hpp>
+#include <boost/geometry/strategies/spherical/expand_segment.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace expand
+{
+
+template
+<
+ typename FormulaPolicy = strategy::andoyer,
+ typename Spheroid = geometry::srs::spheroid<double>,
+ typename CalculationType = void
+>
+class geographic_segment
+{
+public:
+ inline geographic_segment()
+ : m_envelope_strategy()
+ {}
+
+ explicit inline geographic_segment(Spheroid const& spheroid)
+ : m_envelope_strategy(spheroid)
+ {}
+
+ template <typename Box, typename Segment>
+ inline void apply(Box& box, Segment const& segment) const
+ {
+ detail::segment_on_spheroid::apply(box, segment, m_envelope_strategy);
+ }
+
+private:
+ strategy::envelope::geographic_segment
+ <
+ FormulaPolicy, Spheroid, CalculationType
+ > m_envelope_strategy;
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+template <typename CalculationType>
+struct default_strategy<segment_tag, geographic_tag, CalculationType>
+{
+ typedef geographic_segment
+ <
+ strategy::andoyer,
+ geometry::srs::spheroid<double>,
+ CalculationType
+ > type;
+};
+
+} // namespace services
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::expand
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_EXPAND_SEGMENT_HPP
diff --git a/boost/geometry/strategies/geographic/intersection.hpp b/boost/geometry/strategies/geographic/intersection.hpp
index b095f8aefb..37f79e5895 100644
--- a/boost/geometry/strategies/geographic/intersection.hpp
+++ b/boost/geometry/strategies/geographic/intersection.hpp
@@ -2,7 +2,7 @@
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
-// Copyright (c) 2016-2018, Oracle and/or its affiliates.
+// Copyright (c) 2016-2019, 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,
@@ -37,11 +37,15 @@
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/strategies/geographic/area.hpp>
+#include <boost/geometry/strategies/geographic/disjoint_segment_box.hpp>
#include <boost/geometry/strategies/geographic/distance.hpp>
-#include <boost/geometry/strategies/geographic/envelope_segment.hpp>
+#include <boost/geometry/strategies/geographic/envelope.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/strategies/geographic/point_in_poly_winding.hpp>
#include <boost/geometry/strategies/geographic/side.hpp>
+#include <boost/geometry/strategies/spherical/expand_box.hpp>
+#include <boost/geometry/strategies/spherical/disjoint_box_box.hpp>
+#include <boost/geometry/strategies/spherical/point_in_point.hpp>
#include <boost/geometry/strategies/intersection.hpp>
#include <boost/geometry/strategies/intersection_result.hpp>
#include <boost/geometry/strategies/side_info.hpp>
@@ -141,7 +145,7 @@ struct geographic_segments
return strategy_type(m_spheroid);
}
- typedef envelope::geographic_segment<FormulaPolicy, Spheroid, CalculationType>
+ typedef envelope::geographic<FormulaPolicy, Spheroid, CalculationType>
envelope_strategy_type;
inline envelope_strategy_type get_envelope_strategy() const
@@ -149,6 +153,48 @@ struct geographic_segments
return envelope_strategy_type(m_spheroid);
}
+ typedef expand::geographic_segment<FormulaPolicy, Spheroid, CalculationType>
+ expand_strategy_type;
+
+ inline expand_strategy_type get_expand_strategy() const
+ {
+ return expand_strategy_type(m_spheroid);
+ }
+
+ typedef within::spherical_point_point point_in_point_strategy_type;
+
+ static inline point_in_point_strategy_type get_point_in_point_strategy()
+ {
+ return point_in_point_strategy_type();
+ }
+
+ typedef within::spherical_point_point equals_point_point_strategy_type;
+
+ static inline equals_point_point_strategy_type get_equals_point_point_strategy()
+ {
+ return equals_point_point_strategy_type();
+ }
+
+ typedef disjoint::spherical_box_box disjoint_box_box_strategy_type;
+
+ static inline disjoint_box_box_strategy_type get_disjoint_box_box_strategy()
+ {
+ return disjoint_box_box_strategy_type();
+ }
+
+ typedef disjoint::segment_box_geographic
+ <
+ FormulaPolicy, Spheroid, CalculationType
+ > disjoint_segment_box_strategy_type;
+
+ inline disjoint_segment_box_strategy_type get_disjoint_segment_box_strategy() const
+ {
+ return disjoint_segment_box_strategy_type(m_spheroid);
+ }
+
+ typedef covered_by::spherical_point_box disjoint_point_box_strategy_type;
+ typedef expand::spherical_box expand_box_strategy_type;
+
enum intersection_point_flag { ipi_inters = 0, ipi_at_a1, ipi_at_a2, ipi_at_b1, ipi_at_b2 };
template <typename CoordinateType, typename SegmentRatio>
@@ -285,7 +331,6 @@ private:
spheroid_type spheroid = formula::unit_spheroid<spheroid_type>(m_spheroid);
// TODO: check only 2 first coordinates here?
- using geometry::detail::equals::equals_point_point;
bool a_is_point = equals_point_point(a1, a2);
bool b_is_point = equals_point_point(b1, b2);
@@ -615,7 +660,7 @@ private:
// in order to make this independent from is_near()
template <typename Point1, typename Point2, typename ResultInverse, typename CalcT>
static inline bool calculate_collinear_data(Point1 const& a1, Point1 const& a2, // in
- Point2 const& b1, Point2 const& b2, // in
+ Point2 const& b1, Point2 const& /*b2*/, // in
ResultInverse const& res_a1_a2, // in
ResultInverse const& res_a1_b1, // in
ResultInverse const& res_a1_b2, // in
@@ -688,7 +733,6 @@ private:
dist_b1_b2 = res_b1_b2.distance;
// assign the IP if some endpoints overlap
- using geometry::detail::equals::equals_point_point;
if (equals_point_point(a1, b1))
{
lon = a1_lon;
@@ -888,7 +932,6 @@ private:
P1 const& ai, P2 const& b1)
{
static CalcT const c0 = 0;
- using geometry::detail::equals::equals_point_point;
return is_near(dist) && (math::equals(dist, c0) || equals_point_point(ai, b1));
}
@@ -948,6 +991,13 @@ private:
ip_flag;
}
+ template <typename Point1, typename Point2>
+ static inline bool equals_point_point(Point1 const& point1, Point2 const& point2)
+ {
+ return detail::equals::equals_point_point(point1, point2,
+ point_in_point_strategy_type());
+ }
+
private:
Spheroid m_spheroid;
};
diff --git a/boost/geometry/strategies/geographic/line_interpolate.hpp b/boost/geometry/strategies/geographic/line_interpolate.hpp
new file mode 100644
index 0000000000..d5f0e04c93
--- /dev/null
+++ b/boost/geometry/strategies/geographic/line_interpolate.hpp
@@ -0,0 +1,129 @@
+// Boost.Geometry
+
+// Copyright (c) 2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_LINE_INTERPOLATE_HPP
+#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_LINE_INTERPOLATE_HPP
+
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/srs/spheroid.hpp>
+#include <boost/geometry/strategies/line_interpolate.hpp>
+#include <boost/geometry/strategies/geographic/parameters.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace line_interpolate
+{
+
+
+/*!
+\brief Interpolate point on a geographic segment.
+\ingroup strategies
+\tparam FormulaPolicy The geodesic formulas used internally.
+\tparam Spheroid The spheroid model.
+\tparam CalculationType \tparam_calculation
+
+\qbk{
+[heading See also]
+\* [link geometry.reference.algorithms.line_interpolate.line_interpolate_4_with_strategy line_interpolate (with strategy)]
+\* [link geometry.reference.srs.srs_spheroid srs::spheroid]
+}
+ */
+template
+<
+ typename FormulaPolicy = strategy::andoyer,
+ typename Spheroid = srs::spheroid<double>,
+ typename CalculationType = void
+>
+class geographic
+{
+public:
+ geographic()
+ : m_spheroid()
+ {}
+
+ explicit geographic(Spheroid const& spheroid)
+ : m_spheroid(spheroid)
+ {}
+
+ // point-point strategy getters
+ struct distance_pp_strategy
+ {
+ typedef distance::geographic<FormulaPolicy, Spheroid, CalculationType> type;
+ };
+
+ inline typename distance_pp_strategy::type get_distance_pp_strategy() const
+ {
+ typedef typename distance_pp_strategy::type distance_type;
+ return distance_type(m_spheroid);
+ }
+
+ template <typename Point, typename Fraction, typename Distance>
+ inline void apply(Point const& p0,
+ Point const& p1,
+ Fraction const& fraction, //fraction of segment
+ Point & p,
+ Distance const& distance) const
+ {
+ typedef typename select_calculation_type_alt
+ <
+ CalculationType,
+ Point
+ >::type calc_t;
+
+ typedef typename FormulaPolicy::template inverse
+ <calc_t, false, true, false, false, false> inverse_t;
+
+ calc_t azimuth = inverse_t::apply(get_as_radian<0>(p0), get_as_radian<1>(p0),
+ get_as_radian<0>(p1), get_as_radian<1>(p1),
+ m_spheroid).azimuth;
+
+ typedef typename FormulaPolicy::template direct
+ <calc_t, true, false, false, false> direct_t;
+
+ typename direct_t::result_type
+ dir_r = direct_t::apply(get_as_radian<0>(p0), get_as_radian<1>(p0),
+ distance * fraction, azimuth,
+ m_spheroid);
+
+ set_from_radian<0>(p, dir_r.lon2);
+ set_from_radian<1>(p, dir_r.lat2);
+ }
+
+private:
+ Spheroid m_spheroid;
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <>
+struct default_strategy<geographic_tag>
+{
+ typedef strategy::line_interpolate::geographic<> type;
+};
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::line_interpolate
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_LINE_INTERPOLATE_HPP
diff --git a/boost/geometry/strategies/geographic/side.hpp b/boost/geometry/strategies/geographic/side.hpp
index 1201dc2f6d..e22718f32b 100644
--- a/boost/geometry/strategies/geographic/side.hpp
+++ b/boost/geometry/strategies/geographic/side.hpp
@@ -28,9 +28,10 @@
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/strategies/geographic/disjoint_segment_box.hpp>
-#include <boost/geometry/strategies/geographic/envelope_segment.hpp>
+#include <boost/geometry/strategies/geographic/envelope.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/strategies/spherical/point_in_point.hpp>
//#include <boost/geometry/strategies/concepts/side_concept.hpp>
@@ -64,7 +65,7 @@ template
class geographic
{
public:
- typedef strategy::envelope::geographic_segment
+ typedef strategy::envelope::geographic
<
FormulaPolicy,
Spheroid,
@@ -88,6 +89,12 @@ public:
return disjoint_strategy_type(m_model);
}
+ typedef strategy::within::spherical_point_point equals_point_point_strategy_type;
+ static inline equals_point_point_strategy_type get_equals_point_point_strategy()
+ {
+ return equals_point_point_strategy_type();
+ }
+
geographic()
{}
diff --git a/boost/geometry/strategies/line_interpolate.hpp b/boost/geometry/strategies/line_interpolate.hpp
new file mode 100644
index 0000000000..43d4250c0c
--- /dev/null
+++ b/boost/geometry/strategies/line_interpolate.hpp
@@ -0,0 +1,42 @@
+// Boost.Geometry
+
+// Copyright (c) 2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_LINE_INTERPOLATE_HPP
+#define BOOST_GEOMETRY_STRATEGIES_LINE_INTERPOLATE_HPP
+
+
+#include <boost/mpl/assert.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace line_interpolate
+{
+
+namespace services
+{
+
+template <typename CSTag>
+struct default_strategy
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_CS
+ , (types<CSTag>)
+ );
+};
+
+} // namespace services
+
+}} // namespace strategy::line_interpolate
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_LINE_INTERPOLATE_HPP
diff --git a/boost/geometry/strategies/normalize.hpp b/boost/geometry/strategies/normalize.hpp
new file mode 100644
index 0000000000..1887c1e63b
--- /dev/null
+++ b/boost/geometry/strategies/normalize.hpp
@@ -0,0 +1,268 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015-2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_NORMALIZE_HPP
+#define BOOST_GEOMETRY_STRATEGIES_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
+{
+
+namespace strategy { namespace normalize
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+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, bool IsEquatorial = true>
+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 geometry::detail::cs_angular_units<PointIn>::type,
+ IsEquatorial,
+ in_coordinate_type
+ >(longitude, latitude);
+
+ assign_loop
+ <
+ 0, dimension<PointIn>::value
+ >::apply(longitude, latitude, point_in, point_out);
+ }
+};
+
+
+template <typename BoxIn, typename BoxOut, bool IsEquatorial = true>
+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)
+ {
+ geometry::detail::indexed_point_view<BoxOut, min_corner> p_min_out(box_out);
+ assign_loop
+ <
+ 0, dimension<BoxIn>::value
+ >::apply(lon_min,
+ lat_min,
+ geometry::detail::indexed_point_view
+ <
+ BoxIn const, min_corner
+ >(box_in),
+ p_min_out);
+
+ geometry::detail::indexed_point_view<BoxOut, max_corner> p_max_out(box_out);
+ assign_loop
+ <
+ 0, dimension<BoxIn>::value
+ >::apply(lon_max,
+ lat_max,
+ geometry::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 geometry::detail::cs_angular_units<BoxIn>::type,
+ IsEquatorial,
+ in_coordinate_type
+ >(lon_min, lat_min, lon_max, lat_max);
+
+ apply_to_coordinates
+ <
+ typename geometry::detail::cs_angular_units<BoxIn>::type,
+ typename geometry::detail::cs_angular_units<BoxOut>::type
+ >(lon_min, lat_min, lon_max, lat_max, box_in, box_out);
+ }
+};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+struct cartesian_point
+ : detail::do_nothing
+{};
+
+struct cartesian_box
+ : detail::do_nothing
+{};
+
+struct spherical_point
+{
+ template <typename PointIn, typename PointOut>
+ static inline void apply(PointIn const& point_in, PointOut& point_out)
+ {
+ detail::normalize_point
+ <
+ PointIn, PointOut,
+ boost::mpl::not_
+ <
+ boost::is_same
+ <
+ typename cs_tag<PointIn>::type,
+ spherical_polar_tag
+ >
+ >::value
+ >::apply(point_in, point_out);
+ }
+};
+
+struct spherical_box
+{
+ template <typename BoxIn, typename BoxOut>
+ static inline void apply(BoxIn const& box_in, BoxOut& box_out)
+ {
+ detail::normalize_box
+ <
+ BoxIn, BoxOut,
+ boost::mpl::not_
+ <
+ boost::is_same
+ <
+ typename cs_tag<BoxIn>::type,
+ spherical_polar_tag
+ >
+ >::value
+ >::apply(box_in, box_out);
+ }
+};
+
+}} // namespace strategy::normalize
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_NORMALIZE_HPP
diff --git a/boost/geometry/strategies/side.hpp b/boost/geometry/strategies/side.hpp
index 9aaa2bdddc..ea8e5fd226 100644
--- a/boost/geometry/strategies/side.hpp
+++ b/boost/geometry/strategies/side.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -15,6 +20,8 @@
#define BOOST_GEOMETRY_STRATEGIES_SIDE_HPP
+#include <boost/mpl/assert.hpp>
+
#include <boost/geometry/strategies/tags.hpp>
diff --git a/boost/geometry/strategies/spherical/compare.hpp b/boost/geometry/strategies/spherical/compare.hpp
index 26163f7406..bf28fe75a8 100644
--- a/boost/geometry/strategies/spherical/compare.hpp
+++ b/boost/geometry/strategies/spherical/compare.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2017.
-// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2017, 2018.
+// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -25,6 +25,7 @@
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/strategies/compare.hpp>
diff --git a/boost/geometry/strategies/spherical/densify.hpp b/boost/geometry/strategies/spherical/densify.hpp
index 97f4605a98..11eb866c1a 100644
--- a/boost/geometry/strategies/spherical/densify.hpp
+++ b/boost/geometry/strategies/spherical/densify.hpp
@@ -1,7 +1,8 @@
// Boost.Geometry
-// Copyright (c) 2017-2018, Oracle and/or its affiliates.
+// Copyright (c) 2017-2019, Oracle and/or its affiliates.
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
@@ -22,6 +23,8 @@
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/formulas/spherical.hpp>
+#include <boost/geometry/formulas/interpolate_point_spherical.hpp>
+#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/srs/sphere.hpp>
#include <boost/geometry/strategies/densify.hpp>
#include <boost/geometry/strategies/spherical/get_radius.hpp>
@@ -79,15 +82,10 @@ public:
CalculationType
>::type calc_t;
- calc_t const c0 = 0;
- calc_t const c1 = 1;
- calc_t const pi = math::pi<calc_t>();
+ calc_t angle01;
- typedef model::point<calc_t, 3, cs::cartesian> point3d_t;
- point3d_t const xyz0 = formula::sph_to_cart3d<point3d_t>(p0);
- point3d_t const xyz1 = formula::sph_to_cart3d<point3d_t>(p1);
- calc_t const dot01 = geometry::dot_product(xyz0, xyz1);
- calc_t const angle01 = acos(dot01);
+ formula::interpolate_point_spherical<calc_t> formula;
+ formula.compute_angle(p0, p1, angle01);
BOOST_GEOMETRY_ASSERT(length_threshold > T(0));
@@ -95,59 +93,16 @@ public:
if (n <= 0)
return;
- point3d_t axis;
- if (! math::equals(angle01, pi))
- {
- axis = geometry::cross_product(xyz0, xyz1);
- geometry::detail::vec_normalize(axis);
- }
- else // antipodal
- {
- calc_t const half_pi = math::half_pi<calc_t>();
- calc_t const lat = geometry::get_as_radian<1>(p0);
-
- if (math::equals(lat, half_pi))
- {
- // pointing east, segment lies on prime meridian, going south
- axis = point3d_t(c0, c1, c0);
- }
- else if (math::equals(lat, -half_pi))
- {
- // pointing west, segment lies on prime meridian, going north
- axis = point3d_t(c0, -c1, c0);
- }
- else
- {
- // lon rotated west by pi/2 at equator
- calc_t const lon = geometry::get_as_radian<0>(p0);
- axis = point3d_t(sin(lon), -cos(lon), c0);
- }
- }
+ formula.compute_axis(p0, angle01);
calc_t step = angle01 / (n + 1);
calc_t a = step;
for (signed_size_type i = 0 ; i < n ; ++i, a += step)
{
- // Axis-Angle rotation
- // see: https://en.wikipedia.org/wiki/Axis-angle_representation
- calc_t const cos_a = cos(a);
- calc_t const sin_a = sin(a);
- // cos_a * v
- point3d_t s1 = xyz0;
- geometry::multiply_value(s1, cos_a);
- // sin_a * (n x v)
- point3d_t s2 = geometry::cross_product(axis, xyz0);
- geometry::multiply_value(s2, sin_a);
- // (1 - cos_a)(n.v) * n
- point3d_t s3 = axis;
- geometry::multiply_value(s3, (c1 - cos_a) * geometry::dot_product(axis, xyz0));
- // v_rot = cos_a * v + sin_a * (n x v) + (1 - cos_a)(n.v) * e
- point3d_t v_rot = s1;
- geometry::add_point(v_rot, s2);
- geometry::add_point(v_rot, s3);
-
- out_point_t p = formula::cart3d_to_sph<out_point_t>(v_rot);
+ out_point_t p;
+ formula.compute_point(a, p);
+
geometry::detail::conversion::point_to_point
<
Point, out_point_t,
diff --git a/boost/geometry/strategies/spherical/disjoint_box_box.hpp b/boost/geometry/strategies/spherical/disjoint_box_box.hpp
new file mode 100644
index 0000000000..f0504a8b17
--- /dev/null
+++ b/boost/geometry/strategies/spherical/disjoint_box_box.hpp
@@ -0,0 +1,134 @@
+// 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) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
+
+// This file was modified by Oracle on 2013-2018.
+// Modifications copyright (c) 2013-2018, 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.
+
+// 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_STRATEGIES_SPHERICAL_DISJOINT_BOX_BOX_HPP
+#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISJOINT_BOX_BOX_HPP
+
+#include <cstddef>
+
+#include <boost/geometry/core/cs.hpp>
+
+#include <boost/geometry/strategies/cartesian/disjoint_box_box.hpp>
+#include <boost/geometry/strategies/disjoint.hpp>
+
+#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+
+namespace boost { namespace geometry { namespace strategy { namespace disjoint
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+struct box_box_on_spheroid
+{
+ template <typename Box1, typename Box2>
+ static inline bool apply(Box1 const& box1, Box2 const& box2)
+ {
+ typedef typename geometry::select_most_precise
+ <
+ typename coordinate_type<Box1>::type,
+ typename coordinate_type<Box2>::type
+ >::type calc_t;
+ typedef typename geometry::detail::cs_angular_units<Box1>::type units_t;
+ typedef math::detail::constants_on_spheroid<calc_t, units_t> constants;
+
+ calc_t const b1_min = get<min_corner, 0>(box1);
+ calc_t const b1_max = get<max_corner, 0>(box1);
+ calc_t const b2_min = get<min_corner, 0>(box2);
+ calc_t const b2_max = get<max_corner, 0>(box2);
+
+ // min <= max <=> diff >= 0
+ calc_t const diff1 = b1_max - b1_min;
+ calc_t const diff2 = b2_max - b2_min;
+
+ // check the intersection if neither box cover the whole globe
+ if (diff1 < constants::period() && diff2 < constants::period())
+ {
+ // calculate positive longitude translation with b1_min as origin
+ calc_t const diff_min = math::longitude_distance_unsigned<units_t>(b1_min, b2_min);
+ calc_t const b2_min_transl = b1_min + diff_min; // always right of b1_min
+ calc_t b2_max_transl = b2_min_transl - constants::period() + diff2;
+
+ // if the translation is too close then use the original point
+ // note that math::abs(b2_max_transl - b2_max) takes values very
+ // close to k*2*constants::period() for k=0,1,2,...
+ if (math::abs(b2_max_transl - b2_max) < constants::period() / 2)
+ {
+ b2_max_transl = b2_max;
+ }
+
+ if (b2_min_transl > b1_max // b2_min right of b1_max
+ && b2_max_transl < b1_min) // b2_max left of b1_min
+ {
+ return true;
+ }
+ }
+
+ return box_box
+ <
+ Box1, Box2, 1
+ >::apply(box1, box2);
+ }
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+struct spherical_box_box
+{
+ template <typename Box1, typename Box2>
+ static inline bool apply(Box1 const& box1, Box2 const& box2)
+ {
+ return detail::box_box_on_spheroid::apply(box1, box2);
+ }
+};
+
+
+namespace services
+{
+
+template <typename Box1, typename Box2, int TopDim1, int TopDim2>
+struct default_strategy<Box1, Box2, box_tag, box_tag, TopDim1, TopDim2, spherical_equatorial_tag, spherical_equatorial_tag>
+{
+ typedef disjoint::spherical_box_box type;
+};
+
+template <typename Box1, typename Box2, int TopDim1, int TopDim2>
+struct default_strategy<Box1, Box2, box_tag, box_tag, TopDim1, TopDim2, spherical_polar_tag, spherical_polar_tag>
+{
+ typedef disjoint::spherical_box_box type;
+};
+
+template <typename Box1, typename Box2, int TopDim1, int TopDim2>
+struct default_strategy<Box1, Box2, box_tag, box_tag, TopDim1, TopDim2, geographic_tag, geographic_tag>
+{
+ typedef disjoint::spherical_box_box type;
+};
+
+} // namespace services
+
+}}}} // namespace boost::geometry::strategy::disjoint
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISJOINT_BOX_BOX_HPP
diff --git a/boost/geometry/strategies/spherical/disjoint_segment_box.hpp b/boost/geometry/strategies/spherical/disjoint_segment_box.hpp
index bda62a77fc..9c6711dea6 100644
--- a/boost/geometry/strategies/spherical/disjoint_segment_box.hpp
+++ b/boost/geometry/strategies/spherical/disjoint_segment_box.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry
-// Copyright (c) 2017 Oracle and/or its affiliates.
+// Copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -29,8 +29,13 @@
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
#include <boost/geometry/algorithms/detail/disjoint/segment_box.hpp>
-#include <boost/geometry/strategies/spherical/azimuth.hpp>
+// TODO: spherical_point_box currently defined in the same file as cartesian
+#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
#include <boost/geometry/strategies/disjoint.hpp>
+#include <boost/geometry/strategies/normalize.hpp>
+#include <boost/geometry/strategies/spherical/azimuth.hpp>
+#include <boost/geometry/strategies/spherical/disjoint_box_box.hpp>
+
namespace boost { namespace geometry { namespace strategy { namespace disjoint
{
@@ -67,7 +72,13 @@ struct segment_box_spherical
geometry::strategy::azimuth::spherical<CT> azimuth_strategy;
return geometry::detail::disjoint::disjoint_segment_box_sphere_or_spheroid
- <spherical_equatorial_tag>::apply(segment, box, azimuth_strategy);
+ <
+ spherical_equatorial_tag
+ >::apply(segment, box,
+ azimuth_strategy,
+ strategy::normalize::spherical_point(),
+ strategy::covered_by::spherical_point_box(),
+ strategy::disjoint::spherical_box_box());
}
};
diff --git a/boost/geometry/strategies/spherical/distance_cross_track.hpp b/boost/geometry/strategies/spherical/distance_cross_track.hpp
index 97a36b8b27..280bf76b43 100644
--- a/boost/geometry/strategies/spherical/distance_cross_track.hpp
+++ b/boost/geometry/strategies/spherical/distance_cross_track.hpp
@@ -2,11 +2,12 @@
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2014-2017.
-// Modifications copyright (c) 2014-2017, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014-2018.
+// Modifications copyright (c) 2014-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// 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
@@ -27,9 +28,12 @@
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/formulas/spherical.hpp>
+
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/concepts/distance_concept.hpp>
#include <boost/geometry/strategies/spherical/distance_haversine.hpp>
+#include <boost/geometry/strategies/spherical/point_in_point.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
@@ -326,6 +330,8 @@ template
class cross_track
{
public :
+ typedef within::spherical_point_point equals_point_point_strategy_type;
+
template <typename Point, typename PointOfSegment>
struct return_type
: promote_floating_point
@@ -505,6 +511,8 @@ template
class cross_track
{
public :
+ typedef within::spherical_point_point equals_point_point_strategy_type;
+
template <typename Point, typename PointOfSegment>
struct return_type
: promote_floating_point
diff --git a/boost/geometry/strategies/spherical/distance_segment_box.hpp b/boost/geometry/strategies/spherical/distance_segment_box.hpp
index d5647182a8..bb622ec52d 100644
--- a/boost/geometry/strategies/spherical/distance_segment_box.hpp
+++ b/boost/geometry/strategies/spherical/distance_segment_box.hpp
@@ -1,7 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2018 Oracle and/or its affiliates.
+// Copyright (c) 2018-2019 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -12,6 +13,13 @@
#include <boost/geometry/algorithms/detail/distance/segment_to_box.hpp>
+#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/strategies/normalize.hpp>
+#include <boost/geometry/strategies/spherical/disjoint_box_box.hpp>
+#include <boost/geometry/strategies/spherical/distance_cross_track.hpp>
+#include <boost/geometry/strategies/spherical/point_in_point.hpp>
+#include <boost/geometry/strategies/cartesian/point_in_box.hpp> // spherical
+
namespace boost { namespace geometry
{
@@ -29,7 +37,10 @@ struct generic_segment_box
typename BoxPoint,
typename SegmentBoxStrategy,
typename AzimuthStrategy,
- typename EnvelopeSegmentStrategy
+ typename EnvelopeSegmentStrategy,
+ typename NormalizePointStrategy,
+ typename DisjointPointBoxStrategy,
+ typename DisjointBoxBoxStrategy
>
static inline ReturnType segment_below_of_box(
SegmentPoint const& p0,
@@ -39,8 +50,11 @@ struct generic_segment_box
BoxPoint const& bottom_left,
BoxPoint const& bottom_right,
SegmentBoxStrategy const& sb_strategy,
- AzimuthStrategy & az_strategy,
- EnvelopeSegmentStrategy & es_strategy)
+ AzimuthStrategy const& az_strategy,
+ EnvelopeSegmentStrategy const& es_strategy,
+ NormalizePointStrategy const& np_strategy,
+ DisjointPointBoxStrategy const& dpb_strategy,
+ DisjointBoxBoxStrategy const& dbb_strategy)
{
ReturnType result;
typename LessEqual::other less_equal;
@@ -66,7 +80,8 @@ struct generic_segment_box
SegmentPoint p_max;
disjoint_info_type disjoint_result = disjoint_sb::
- apply(seg, input_box, az_strategy, p_max);
+ apply(seg, input_box, p_max,
+ az_strategy, np_strategy, dpb_strategy, dbb_strategy);
if (disjoint_result == disjoint_info_type::intersect) //intersect
{
@@ -85,6 +100,12 @@ struct generic_segment_box
CT lon2 = geometry::get_as_radian<0>(p1);
CT lat2 = geometry::get_as_radian<1>(p1);
+ if (lon1 > lon2)
+ {
+ std::swap(lon1, lon2);
+ std::swap(lat1, lat2);
+ }
+
CT vertex_lat;
CT lat_sum = lat1 + lat2;
if (lat_sum > CT(0))
@@ -198,6 +219,13 @@ struct spherical_segment_box
return typename distance_ps_strategy::type();
}
+ typedef within::spherical_point_point equals_point_point_strategy_type;
+
+ static inline equals_point_point_strategy_type get_equals_point_point_strategy()
+ {
+ return equals_point_point_strategy_type();
+ }
+
// methods
template <typename LessEqual, typename ReturnType,
@@ -222,7 +250,10 @@ struct spherical_segment_box
ReturnType
>(p0,p1,top_left,top_right,bottom_left,bottom_right,
spherical_segment_box<CalculationType>(),
- az_strategy, es_strategy);
+ az_strategy, es_strategy,
+ normalize::spherical_point(),
+ covered_by::spherical_point_box(),
+ disjoint::spherical_box_box());
}
template <typename SPoint, typename BPoint>
diff --git a/boost/geometry/strategies/spherical/envelope.hpp b/boost/geometry/strategies/spherical/envelope.hpp
new file mode 100644
index 0000000000..4353f0180b
--- /dev/null
+++ b/boost/geometry/strategies/spherical/envelope.hpp
@@ -0,0 +1,146 @@
+// 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, 2016, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// 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_STRATEGIES_SPHERICAL_ENVELOPE_HPP
+#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_HPP
+
+#include <boost/geometry/algorithms/detail/envelope/initialize.hpp>
+#include <boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp>
+
+#include <boost/geometry/iterators/segment_iterator.hpp>
+
+#include <boost/geometry/strategies/spherical/envelope_box.hpp>
+#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
+#include <boost/geometry/strategies/spherical/expand_box.hpp>
+#include <boost/geometry/strategies/spherical/expand_segment.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace envelope
+{
+
+template <typename CalculationType = void>
+class spherical
+{
+public:
+ typedef spherical_segment<CalculationType> element_envelope_strategy_type;
+ static inline element_envelope_strategy_type get_element_envelope_strategy()
+ {
+ return element_envelope_strategy_type();
+ }
+
+ typedef expand::spherical_segment<CalculationType> element_expand_strategy_type;
+ static inline element_expand_strategy_type get_element_expand_strategy()
+ {
+ return element_expand_strategy_type();
+ }
+
+ typedef strategy::expand::spherical_box box_expand_strategy_type;
+ static inline box_expand_strategy_type get_box_expand_strategy()
+ {
+ return box_expand_strategy_type();
+ }
+
+ // Linestring, Ring, Polygon
+
+ template <typename Range>
+ static inline geometry::segment_iterator<Range const> begin(Range const& range)
+ {
+ return geometry::segments_begin(range);
+ }
+
+ template <typename Range>
+ static inline geometry::segment_iterator<Range const> end(Range const& range)
+ {
+ return geometry::segments_end(range);
+ }
+
+ // MultiLinestring, MultiPolygon
+
+ template <typename Box>
+ struct multi_state
+ {
+ void apply(Box const& single_box)
+ {
+ m_boxes.push_back(single_box);
+ }
+
+ void result(Box & box)
+ {
+ if (!m_boxes.empty())
+ {
+ geometry::detail::envelope::envelope_range_of_boxes::apply(m_boxes, box);
+ }
+ else
+ {
+ geometry::detail::envelope::initialize<Box, 0, dimension<Box>::value>::apply(box);
+ }
+ }
+
+ private:
+ std::vector<Box> m_boxes;
+ };
+
+ // Segment
+
+ template <typename Point1, typename Point2, typename Box>
+ static inline void apply(Point1 const& point1, Point2 const& point2,
+ Box& box)
+ {
+ spherical_segment<CalculationType>::apply(point1, point2, box);
+ }
+
+ // Box
+
+ template <typename BoxIn, typename Box>
+ static inline void apply(BoxIn const& box_in, Box& box)
+ {
+ spherical_box::apply(box_in, box);
+ }
+};
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+template <typename Tag, typename CalculationType>
+struct default_strategy<Tag, spherical_equatorial_tag, CalculationType>
+{
+ typedef strategy::envelope::spherical<CalculationType> type;
+};
+
+template <typename Tag, typename CalculationType>
+struct default_strategy<Tag, spherical_polar_tag, CalculationType>
+{
+ typedef strategy::envelope::spherical<CalculationType> type;
+};
+
+}
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::envelope
+
+}} //namepsace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_HPP
diff --git a/boost/geometry/strategies/spherical/envelope_box.hpp b/boost/geometry/strategies/spherical/envelope_box.hpp
new file mode 100644
index 0000000000..0a9436d123
--- /dev/null
+++ b/boost/geometry/strategies/spherical/envelope_box.hpp
@@ -0,0 +1,145 @@
+// 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-2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, 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_STRATEGIES_SPHERICAL_ENVELOPE_BOX_HPP
+#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_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>
+
+#include <boost/geometry/strategies/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+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);
+ }
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+
+namespace strategy { namespace envelope
+{
+
+
+struct spherical_box
+{
+ template <typename BoxIn, typename BoxOut>
+ static inline void apply(BoxIn const& box_in, BoxOut& mbr)
+ {
+ BoxIn box_in_normalized = box_in;
+
+ if (!is_inverse_spheroidal_coordinates(box_in))
+ {
+ strategy::normalize::spherical_box::apply(box_in, box_in_normalized);
+ }
+
+ geometry::detail::envelope::envelope_indexed_box_on_spheroid
+ <
+ min_corner, dimension<BoxIn>::value
+ >::apply(box_in_normalized, mbr);
+
+ geometry::detail::envelope::envelope_indexed_box_on_spheroid
+ <
+ max_corner, dimension<BoxIn>::value
+ >::apply(box_in_normalized, mbr);
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+template <typename CalculationType>
+struct default_strategy<box_tag, spherical_equatorial_tag, CalculationType>
+{
+ typedef strategy::envelope::spherical_box type;
+};
+
+template <typename CalculationType>
+struct default_strategy<box_tag, spherical_polar_tag, CalculationType>
+{
+ typedef strategy::envelope::spherical_box type;
+};
+
+template <typename CalculationType>
+struct default_strategy<box_tag, geographic_tag, CalculationType>
+{
+ typedef strategy::envelope::spherical_box type;
+};
+
+}
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::envelope
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_BOX_HPP
diff --git a/boost/geometry/strategies/spherical/envelope_multipoint.hpp b/boost/geometry/strategies/spherical/envelope_multipoint.hpp
new file mode 100644
index 0000000000..e7817370f1
--- /dev/null
+++ b/boost/geometry/strategies/spherical/envelope_multipoint.hpp
@@ -0,0 +1,379 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2015-2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, 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_STRATEGIES_SPHERICAL_ENVELOPE_MULTIPOINT_HPP
+#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_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/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/strategies/cartesian/envelope_point.hpp>
+#include <boost/geometry/strategies/normalize.hpp>
+#include <boost/geometry/strategies/spherical/envelope_box.hpp>
+#include <boost/geometry/strategies/spherical/envelope_point.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace envelope
+{
+
+class spherical_multipoint
+{
+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;
+ normalize::spherical_point::apply(*it, point);
+
+ 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 geometry::detail::cs_angular_units<MultiPoint>::type
+ > constants;
+
+ if (boost::empty(multipoint))
+ {
+ geometry::detail::envelope::initialize<Box, 0, dimension<Box>::value>::apply(mbr);
+ return;
+ }
+
+ geometry::detail::envelope::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, strategy::envelope::spherical_point());
+ }
+
+ // 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 geometry::detail::cs_angular_units<MultiPoint>::type
+ >::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)
+ geometry::detail::envelope::envelope_indexed_box_on_spheroid<min_corner, 2>::apply(helper_mbr, mbr);
+ geometry::detail::envelope::envelope_indexed_box_on_spheroid<max_corner, 2>::apply(helper_mbr, mbr);
+
+ // compute envelope for higher coordinates
+ iterator_type it = boost::begin(multipoint);
+ geometry::detail::envelope::envelope_one_point<2, dimension<Box>::value>::apply(*it, mbr);
+
+ for (++it; it != boost::end(multipoint); ++it)
+ {
+ strategy::expand::detail::point_loop
+ <
+ 2, dimension<Box>::value
+ >::apply(mbr, *it);
+ }
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+template <typename CalculationType>
+struct default_strategy<multi_point_tag, spherical_equatorial_tag, CalculationType>
+{
+ typedef strategy::envelope::spherical_multipoint type;
+};
+
+template <typename CalculationType>
+struct default_strategy<multi_point_tag, spherical_polar_tag, CalculationType>
+{
+ typedef strategy::envelope::spherical_multipoint type;
+};
+
+template <typename CalculationType>
+struct default_strategy<multi_point_tag, geographic_tag, CalculationType>
+{
+ typedef strategy::envelope::spherical_multipoint type;
+};
+
+} // namespace services
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::envelope
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_MULTIPOINT_HPP
diff --git a/boost/geometry/strategies/spherical/envelope_point.hpp b/boost/geometry/strategies/spherical/envelope_point.hpp
new file mode 100644
index 0000000000..8302d7e56f
--- /dev/null
+++ b/boost/geometry/strategies/spherical/envelope_point.hpp
@@ -0,0 +1,111 @@
+// 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, 2016, 2017, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, 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_STRATEGIES_SPHERICAL_ENVELOPE_POINT_HPP
+#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_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/strategies/cartesian/envelope_point.hpp>
+
+#include <boost/geometry/strategies/envelope.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace envelope
+{
+
+struct spherical_point
+{
+ template<typename Point, typename Box>
+ static inline void apply(Point const& point, Box& mbr)
+ {
+ Point normalized_point;
+ strategy::normalize::spherical_point::apply(point, normalized_point);
+
+ typename point_type<Box>::type box_point;
+
+ // transform units of input point to units of a box point
+ geometry::detail::envelope::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));
+
+ typedef geometry::detail::envelope::envelope_one_point
+ <
+ 2, dimension<Point>::value
+ > per_corner;
+ per_corner::template apply<min_corner>(normalized_point, mbr);
+ per_corner::template apply<max_corner>(normalized_point, mbr);
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+template <typename CalculationType>
+struct default_strategy<point_tag, spherical_equatorial_tag, CalculationType>
+{
+ typedef strategy::envelope::spherical_point type;
+};
+
+template <typename CalculationType>
+struct default_strategy<point_tag, spherical_polar_tag, CalculationType>
+{
+ typedef strategy::envelope::spherical_point type;
+};
+
+template <typename CalculationType>
+struct default_strategy<point_tag, geographic_tag, CalculationType>
+{
+ typedef strategy::envelope::spherical_point type;
+};
+
+
+}
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::envelope
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_POINT_HPP
diff --git a/boost/geometry/strategies/spherical/envelope_segment.hpp b/boost/geometry/strategies/spherical/envelope_segment.hpp
index 98f085fe73..646d6695e1 100644
--- a/boost/geometry/strategies/spherical/envelope_segment.hpp
+++ b/boost/geometry/strategies/spherical/envelope_segment.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2017 Oracle and/or its affiliates.
+// Copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -11,47 +11,406 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_SEGMENT_HPP
#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_SEGMENT_HPP
-#include <boost/geometry/algorithms/detail/envelope/segment.hpp>
-#include <boost/geometry/algorithms/detail/normalize.hpp>
+
+#include <cstddef>
+#include <utility>
+
+#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/algorithms/detail/envelope/transform_units.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/formulas/meridian_segment.hpp>
+#include <boost/geometry/formulas/vertex_latitude.hpp>
+
+#include <boost/geometry/geometries/helper_geometry.hpp>
+
+#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
#include <boost/geometry/strategies/envelope.hpp>
+#include <boost/geometry/strategies/normalize.hpp>
#include <boost/geometry/strategies/spherical/azimuth.hpp>
+#include <boost/geometry/strategies/spherical/expand_box.hpp>
+
+#include <boost/geometry/util/math.hpp>
-namespace boost { namespace geometry
+namespace boost { namespace geometry { namespace strategy { namespace envelope
{
-namespace strategy { namespace envelope
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
{
+template <typename CalculationType, typename CS_Tag>
+struct envelope_segment_call_vertex_latitude
+{
+ template <typename T1, typename T2, typename Strategy>
+ static inline CalculationType apply(T1 const& lat1,
+ T2 const& alp1,
+ Strategy const& )
+ {
+ return geometry::formula::vertex_latitude<CalculationType, CS_Tag>
+ ::apply(lat1, alp1);
+ }
+};
+
+template <typename CalculationType>
+struct envelope_segment_call_vertex_latitude<CalculationType, geographic_tag>
+{
+ template <typename T1, typename T2, typename Strategy>
+ static inline CalculationType apply(T1 const& lat1,
+ T2 const& alp1,
+ Strategy const& strategy)
+ {
+ return geometry::formula::vertex_latitude<CalculationType, geographic_tag>
+ ::apply(lat1, alp1, strategy.model());
+ }
+};
+
+template <typename Units, typename CS_Tag>
+struct envelope_segment_convert_polar
+{
+ template <typename T>
+ static inline void pre(T & , T & ) {}
+
+ template <typename T>
+ static inline void post(T & , T & ) {}
+};
+
+template <typename Units>
+struct envelope_segment_convert_polar<Units, spherical_polar_tag>
+{
+ template <typename T>
+ static inline void pre(T & lat1, T & lat2)
+ {
+ lat1 = math::latitude_convert_ep<Units>(lat1);
+ lat2 = math::latitude_convert_ep<Units>(lat2);
+ }
+
+ template <typename T>
+ static inline void post(T & lat1, T & lat2)
+ {
+ lat1 = math::latitude_convert_ep<Units>(lat1);
+ lat2 = math::latitude_convert_ep<Units>(lat2);
+ std::swap(lat1, lat2);
+ }
+};
+
+template <typename CS_Tag>
+class envelope_segment_impl
+{
+private:
+
+ // degrees or radians
+ template <typename CalculationType>
+ static inline void swap(CalculationType& lon1,
+ CalculationType& lat1,
+ CalculationType& lon2,
+ CalculationType& lat2)
+ {
+ std::swap(lon1, lon2);
+ std::swap(lat1, lat2);
+ }
+
+ // radians
+ 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);
+ }
+
+ // radians or degrees
+ template <typename Units, typename CoordinateType>
+ static inline bool crosses_antimeridian(CoordinateType const& lon1,
+ CoordinateType const& lon2)
+ {
+ typedef math::detail::constants_on_spheroid
+ <
+ CoordinateType, Units
+ > constants;
+
+ return math::abs(lon1 - lon2) > constants::half_period(); // > pi
+ }
+
+ // degrees or radians
+ template <typename Units, typename CalculationType, typename Strategy>
+ static inline void compute_box_corners(CalculationType& lon1,
+ CalculationType& lat1,
+ CalculationType& lon2,
+ CalculationType& lat2,
+ CalculationType a1,
+ CalculationType a2,
+ Strategy const& strategy)
+ {
+ // coordinates are assumed to be in radians
+ BOOST_GEOMETRY_ASSERT(lon1 <= lon2);
+ boost::ignore_unused(lon1, lon2);
+
+ CalculationType lat1_rad = math::as_radian<Units>(lat1);
+ CalculationType lat2_rad = math::as_radian<Units>(lat2);
+
+ if (math::equals(a1, a2))
+ {
+ // the segment must lie on the equator or is very short or is meridian
+ return;
+ }
+
+ if (lat1 > lat2)
+ {
+ std::swap(lat1, lat2);
+ std::swap(lat1_rad, lat2_rad);
+ std::swap(a1, a2);
+ }
+
+ if (contains_pi_half(a1, a2))
+ {
+ CalculationType p_max = envelope_segment_call_vertex_latitude
+ <CalculationType, CS_Tag>::apply(lat1_rad, a1, strategy);
+
+ CalculationType const mid_lat = lat1 + lat2;
+ if (mid_lat < 0)
+ {
+ // update using min latitude
+ CalculationType const lat_min_rad = -p_max;
+ CalculationType const lat_min
+ = math::from_radian<Units>(lat_min_rad);
+
+ if (lat1 > lat_min)
+ {
+ lat1 = lat_min;
+ }
+ }
+ else
+ {
+ // update using max latitude
+ CalculationType const lat_max_rad = p_max;
+ CalculationType const lat_max
+ = math::from_radian<Units>(lat_max_rad);
+
+ if (lat2 < lat_max)
+ {
+ lat2 = lat_max;
+ }
+ }
+ }
+ }
+
+ template <typename Units, typename CalculationType>
+ static inline void special_cases(CalculationType& lon1,
+ CalculationType& lat1,
+ CalculationType& lon2,
+ CalculationType& lat2)
+ {
+ typedef math::detail::constants_on_spheroid
+ <
+ CalculationType, Units
+ > constants;
+
+ bool is_pole1 = math::equals(math::abs(lat1), constants::max_latitude());
+ bool is_pole2 = math::equals(math::abs(lat2), constants::max_latitude());
+
+ if (is_pole1 && is_pole2)
+ {
+ // both points are poles; nothing more to do:
+ // longitudes are already normalized to 0
+ // but just in case
+ lon1 = 0;
+ lon2 = 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 (lon1 == lon2)
+ {
+ // segment lies on a meridian
+ if (lat1 > lat2)
+ {
+ std::swap(lat1, lat2);
+ }
+ return;
+ }
+
+ BOOST_GEOMETRY_ASSERT(!is_pole1 && !is_pole2);
+
+ if (lon1 > lon2)
+ {
+ swap(lon1, lat1, lon2, lat2);
+ }
+
+ if (crosses_antimeridian<Units>(lon1, lon2))
+ {
+ lon1 += constants::period();
+ swap(lon1, lat1, lon2, lat2);
+ }
+ }
+
+ template
+ <
+ typename Units,
+ typename CalculationType,
+ typename Box
+ >
+ static inline void create_box(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, Units
+ >::type helper_box_type;
+
+ helper_box_type helper_mbr;
+
+ geometry::set
+ <
+ min_corner, 0
+ >(helper_mbr, boost::numeric_cast<box_coordinate_type>(lon1));
+
+ geometry::set
+ <
+ min_corner, 1
+ >(helper_mbr, boost::numeric_cast<box_coordinate_type>(lat1));
+
+ geometry::set
+ <
+ max_corner, 0
+ >(helper_mbr, boost::numeric_cast<box_coordinate_type>(lon2));
+
+ geometry::set
+ <
+ max_corner, 1
+ >(helper_mbr, boost::numeric_cast<box_coordinate_type>(lat2));
+
+ geometry::detail::envelope::transform_units(helper_mbr, mbr);
+ }
+
+
+ template <typename Units, typename CalculationType, typename Strategy>
+ static inline void apply(CalculationType& lon1,
+ CalculationType& lat1,
+ CalculationType& lon2,
+ CalculationType& lat2,
+ Strategy const& strategy)
+ {
+ special_cases<Units>(lon1, lat1, lon2, lat2);
+
+ CalculationType lon1_rad = math::as_radian<Units>(lon1);
+ CalculationType lat1_rad = math::as_radian<Units>(lat1);
+ CalculationType lon2_rad = math::as_radian<Units>(lon2);
+ CalculationType lat2_rad = math::as_radian<Units>(lat2);
+ CalculationType alp1, alp2;
+ strategy.apply(lon1_rad, lat1_rad, lon2_rad, lat2_rad, alp1, alp2);
+
+ compute_box_corners<Units>(lon1, lat1, lon2, lat2, alp1, alp2, strategy);
+ }
+
+public:
+ template
+ <
+ typename Units,
+ typename CalculationType,
+ typename Box,
+ typename Strategy
+ >
+ static inline void apply(CalculationType lon1,
+ CalculationType lat1,
+ CalculationType lon2,
+ CalculationType lat2,
+ Box& mbr,
+ Strategy const& strategy)
+ {
+ typedef envelope_segment_convert_polar<Units, typename cs_tag<Box>::type> convert_polar;
+
+ convert_polar::pre(lat1, lat2);
+
+ apply<Units>(lon1, lat1, lon2, lat2, strategy);
+
+ convert_polar::post(lat1, lat2);
+
+ create_box<Units>(lon1, lat1, lon2, lat2, mbr);
+ }
+
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
template
<
typename CalculationType = void
>
class spherical_segment
{
-public :
-
- inline spherical_segment()
- {}
+public:
+ typedef strategy::expand::spherical_box box_expand_strategy_type;
+ static inline box_expand_strategy_type get_box_expand_strategy()
+ {
+ return box_expand_strategy_type();
+ }
- template <typename Point1, typename Point2, typename Box>
- inline void
- apply(Point1 const& point1, Point2 const& point2, Box& box) const
+ template <typename Point, typename Box>
+ static inline void apply(Point const& point1, Point const& point2,
+ Box& box)
{
- Point1 p1_normalized = detail::return_normalized<Point1>(point1);
- Point2 p2_normalized = detail::return_normalized<Point2>(point2);
+ Point p1_normalized, p2_normalized;
+ strategy::normalize::spherical_point::apply(point1, p1_normalized);
+ strategy::normalize::spherical_point::apply(point2, p2_normalized);
geometry::strategy::azimuth::spherical<CalculationType> azimuth_spherical;
- typedef typename coordinate_system<Point1>::type::units units_type;
+ typedef typename geometry::detail::cs_angular_units<Point>::type units_type;
- geometry::detail::envelope::envelope_segment_impl<spherical_equatorial_tag>
- ::template apply<units_type>(geometry::get<0>(p1_normalized),
- geometry::get<1>(p1_normalized),
- geometry::get<0>(p2_normalized),
- geometry::get<1>(p2_normalized),
- box,
- azimuth_spherical);
+ // first compute the envelope range for the first two coordinates
+ strategy::envelope::detail::envelope_segment_impl
+ <
+ spherical_equatorial_tag
+ >::template apply<units_type>(geometry::get<0>(p1_normalized),
+ geometry::get<1>(p1_normalized),
+ geometry::get<0>(p2_normalized),
+ geometry::get<1>(p2_normalized),
+ box,
+ azimuth_spherical);
+ // now compute the envelope range for coordinates of
+ // dimension 2 and higher
+ strategy::envelope::detail::envelope_one_segment
+ <
+ 2, dimension<Point>::value
+ >::apply(point1, point2, box);
}
};
@@ -61,14 +420,14 @@ namespace services
{
template <typename CalculationType>
-struct default_strategy<spherical_equatorial_tag, CalculationType>
+struct default_strategy<segment_tag, spherical_equatorial_tag, CalculationType>
{
typedef strategy::envelope::spherical_segment<CalculationType> type;
};
template <typename CalculationType>
-struct default_strategy<spherical_polar_tag, CalculationType>
+struct default_strategy<segment_tag, spherical_polar_tag, CalculationType>
{
typedef strategy::envelope::spherical_segment<CalculationType> type;
};
diff --git a/boost/geometry/strategies/spherical/expand_box.hpp b/boost/geometry/strategies/spherical/expand_box.hpp
new file mode 100644
index 0000000000..e3801861b2
--- /dev/null
+++ b/boost/geometry/strategies/spherical/expand_box.hpp
@@ -0,0 +1,98 @@
+// 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, 2016, 2017, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, 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_STRATEGIES_SPHERICAL_EXPAND_BOX_HPP
+#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_EXPAND_BOX_HPP
+
+#include <cstddef>
+#include <algorithm>
+
+#include <boost/geometry/algorithms/detail/envelope/box.hpp>
+#include <boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp>
+
+#include <boost/geometry/strategies/expand.hpp>
+#include <boost/geometry/strategies/spherical/envelope_box.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace expand
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+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];
+ strategy::envelope::spherical_box::apply(box_in, mbrs[0]);
+ strategy::envelope::spherical_box::apply(box_out, mbrs[1]);
+
+ // compute the envelope of the two boxes
+ geometry::detail::envelope::envelope_range_of_boxes::apply(mbrs, box_out);
+ }
+};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+struct spherical_box
+ : detail::box_on_spheroid
+{};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+template <typename CalculationType>
+struct default_strategy<box_tag, spherical_equatorial_tag, CalculationType>
+{
+ typedef spherical_box type;
+};
+
+template <typename CalculationType>
+struct default_strategy<box_tag, spherical_polar_tag, CalculationType>
+{
+ typedef spherical_box type;
+};
+
+template <typename CalculationType>
+struct default_strategy<box_tag, geographic_tag, CalculationType>
+{
+ typedef spherical_box type;
+};
+
+} // namespace services
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::expand
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_EXPAND_BOX_HPP
diff --git a/boost/geometry/strategies/spherical/expand_point.hpp b/boost/geometry/strategies/spherical/expand_point.hpp
new file mode 100644
index 0000000000..b2cff013ae
--- /dev/null
+++ b/boost/geometry/strategies/spherical/expand_point.hpp
@@ -0,0 +1,233 @@
+// 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-2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// 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_STRATEGIES_SPHERICAL_EXPAND_POINT_HPP
+#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_EXPAND_POINT_HPP
+
+#include <cstddef>
+#include <algorithm>
+#include <functional>
+
+#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/is_inverse_spheroidal_coordinates.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_coordinate_type.hpp>
+
+#include <boost/geometry/algorithms/detail/normalize.hpp>
+#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
+
+#include <boost/geometry/strategies/expand.hpp>
+#include <boost/geometry/strategies/cartesian/expand_point.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace expand
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+// implementation for the spherical and geographic coordinate systems
+template <std::size_t DimensionCount, bool IsEquatorial>
+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 typename geometry::detail::cs_angular_units<Box>::type units_type;
+
+ typedef math::detail::constants_on_spheroid
+ <
+ box_coordinate_type,
+ units_type
+ > constants;
+
+ // normalize input point and input box
+ Point p_normalized;
+ strategy::normalize::spherical_point::apply(point, p_normalized);
+
+ // transform input point to be of the same type as the box point
+ box_point_type box_point;
+ geometry::detail::envelope::transform_units(p_normalized, box_point);
+
+ if (is_inverse_spheroidal_coordinates(box))
+ {
+ geometry::set_from_radian<min_corner, 0>(box, geometry::get_as_radian<0>(p_normalized));
+ geometry::set_from_radian<min_corner, 1>(box, geometry::get_as_radian<1>(p_normalized));
+ geometry::set_from_radian<max_corner, 0>(box, geometry::get_as_radian<0>(p_normalized));
+ geometry::set_from_radian<max_corner, 1>(box, geometry::get_as_radian<1>(p_normalized));
+
+ } else {
+
+ strategy::normalize::spherical_box::apply(box, box);
+
+ 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::is_latitude_pole<units_type, IsEquatorial>(p_lat))
+ {
+ // 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::is_latitude_pole<units_type, IsEquatorial>(b_lat_min))
+ {
+ // 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
+ <
+ 2, DimensionCount
+ >::apply(box, point);
+ }
+};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+struct spherical_point
+{
+ template <typename Box, typename Point>
+ static void apply(Box & box, Point const& point)
+ {
+ expand::detail::point_loop_on_spheroid
+ <
+ dimension<Point>::value,
+ ! boost::is_same<typename cs_tag<Point>::type, spherical_polar_tag>::value
+ >::apply(box, point);
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+template <typename CalculationType>
+struct default_strategy<point_tag, spherical_equatorial_tag, CalculationType>
+{
+ typedef spherical_point type;
+};
+
+template <typename CalculationType>
+struct default_strategy<point_tag, spherical_polar_tag, CalculationType>
+{
+ typedef spherical_point type;
+};
+
+template <typename CalculationType>
+struct default_strategy<point_tag, geographic_tag, CalculationType>
+{
+ typedef spherical_point type;
+};
+
+
+} // namespace services
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::expand
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_EXPAND_POINT_HPP
diff --git a/boost/geometry/strategies/spherical/expand_segment.hpp b/boost/geometry/strategies/spherical/expand_segment.hpp
new file mode 100644
index 0000000000..75f4698ff0
--- /dev/null
+++ b/boost/geometry/strategies/spherical/expand_segment.hpp
@@ -0,0 +1,118 @@
+// 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, 2016, 2017, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, 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_STRATEGIES_SPHERICAL_EXPAND_SEGMENT_HPP
+#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_EXPAND_SEGMENT_HPP
+
+#include <cstddef>
+#include <functional>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/util/select_coordinate_type.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/strategies/expand.hpp>
+#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace expand
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+struct segment_on_spheroid
+{
+ template <typename Box, typename Segment, typename EnvelopeStrategy>
+ static inline void apply(Box& box, Segment const& segment, EnvelopeStrategy const& strategy)
+ {
+ Box mbrs[2];
+
+ // compute the envelope of the segment
+ typename point_type<Segment>::type p[2];
+ geometry::detail::assign_point_from_index<0>(segment, p[0]);
+ geometry::detail::assign_point_from_index<1>(segment, p[1]);
+ geometry::detail::envelope::envelope_segment
+ <
+ dimension<Segment>::value
+ >::apply(p[0], p[1], mbrs[0], strategy);
+
+ // normalize the box
+ strategy::envelope::spherical_box::apply(box, mbrs[1]);
+
+ // compute the envelope of the two boxes
+ geometry::detail::envelope::envelope_range_of_boxes::apply(mbrs, box);
+ }
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+template
+<
+ typename CalculationType = void
+>
+class spherical_segment
+{
+public:
+ template <typename Box, typename Segment>
+ static inline void apply(Box& box, Segment const& segment)
+ {
+ detail::segment_on_spheroid::apply(box, segment,
+ strategy::envelope::spherical_segment<CalculationType>());
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+template <typename CalculationType>
+struct default_strategy<segment_tag, spherical_equatorial_tag, CalculationType>
+{
+ typedef spherical_segment<CalculationType> type;
+};
+
+template <typename CalculationType>
+struct default_strategy<segment_tag, spherical_polar_tag, CalculationType>
+{
+ typedef spherical_segment<CalculationType> type;
+};
+
+} // namespace services
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::expand
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_EXPAND_SEGMENT_HPP
diff --git a/boost/geometry/strategies/spherical/intersection.hpp b/boost/geometry/strategies/spherical/intersection.hpp
index 2bdc8b51ab..4cf4fca113 100644
--- a/boost/geometry/strategies/spherical/intersection.hpp
+++ b/boost/geometry/strategies/spherical/intersection.hpp
@@ -2,7 +2,7 @@
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
-// Copyright (c) 2016-2018, Oracle and/or its affiliates.
+// Copyright (c) 2016-2019, 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,
@@ -41,8 +41,12 @@
#include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/strategies/side_info.hpp>
#include <boost/geometry/strategies/spherical/area.hpp>
+#include <boost/geometry/strategies/spherical/disjoint_box_box.hpp>
+#include <boost/geometry/strategies/spherical/disjoint_segment_box.hpp>
#include <boost/geometry/strategies/spherical/distance_haversine.hpp>
-#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
+#include <boost/geometry/strategies/spherical/envelope.hpp>
+#include <boost/geometry/strategies/spherical/expand_box.hpp>
+#include <boost/geometry/strategies/spherical/point_in_point.hpp>
#include <boost/geometry/strategies/spherical/point_in_poly_winding.hpp>
#include <boost/geometry/strategies/spherical/ssf.hpp>
#include <boost/geometry/strategies/within.hpp>
@@ -149,7 +153,7 @@ struct ecef_segments
return strategy_type();
}
- typedef envelope::spherical_segment<CalculationType>
+ typedef envelope::spherical<CalculationType>
envelope_strategy_type;
static inline envelope_strategy_type get_envelope_strategy()
@@ -157,6 +161,45 @@ struct ecef_segments
return envelope_strategy_type();
}
+ typedef expand::spherical_segment<CalculationType>
+ expand_strategy_type;
+
+ static inline expand_strategy_type get_expand_strategy()
+ {
+ return expand_strategy_type();
+ }
+
+ typedef within::spherical_point_point point_in_point_strategy_type;
+
+ static inline point_in_point_strategy_type get_point_in_point_strategy()
+ {
+ return point_in_point_strategy_type();
+ }
+
+ typedef within::spherical_point_point equals_point_point_strategy_type;
+
+ static inline equals_point_point_strategy_type get_equals_point_point_strategy()
+ {
+ return equals_point_point_strategy_type();
+ }
+
+ typedef disjoint::spherical_box_box disjoint_box_box_strategy_type;
+
+ static inline disjoint_box_box_strategy_type get_disjoint_box_box_strategy()
+ {
+ return disjoint_box_box_strategy_type();
+ }
+
+ typedef disjoint::segment_box_spherical disjoint_segment_box_strategy_type;
+
+ static inline disjoint_segment_box_strategy_type get_disjoint_segment_box_strategy()
+ {
+ return disjoint_segment_box_strategy_type();
+ }
+
+ typedef covered_by::spherical_point_box disjoint_point_box_strategy_type;
+ typedef expand::spherical_box expand_box_strategy_type;
+
enum intersection_point_flag { ipi_inters = 0, ipi_at_a1, ipi_at_a2, ipi_at_b1, ipi_at_b2 };
// segment_intersection_info cannot outlive relate_ecef_segments
@@ -252,7 +295,6 @@ struct ecef_segments
BOOST_CONCEPT_ASSERT( (concepts::ConstSegment<Segment2>) );
// TODO: check only 2 first coordinates here?
- using geometry::detail::equals::equals_point_point;
bool a_is_point = equals_point_point(a1, a2);
bool b_is_point = equals_point_point(b1, b2);
@@ -645,7 +687,6 @@ private:
}
// reassign the IP if some endpoints overlap
- using geometry::detail::equals::equals_point_point;
if (is_near_a1)
{
if (is_near_b1 && equals_point_point(a1, b1))
@@ -822,7 +863,6 @@ private:
P1 const& ai, P2 const& b1)
{
static CalcT const c0 = 0;
- using geometry::detail::equals::equals_point_point;
return is_near(dist) && (math::equals(dist, c0) || equals_point_point(ai, b1));
}
@@ -850,6 +890,13 @@ private:
: ca1 < cb2 ? 4
: 2 );
}
+
+ template <typename Point1, typename Point2>
+ static inline bool equals_point_point(Point1 const& point1, Point2 const& point2)
+ {
+ return detail::equals::equals_point_point(point1, point2,
+ point_in_point_strategy_type());
+ }
};
struct spherical_segments_calc_policy
@@ -921,7 +968,7 @@ struct spherical_segments_calc_policy
multiply_value(ip2, coord_t(-1));
return true;
- }
+ }
};
diff --git a/boost/geometry/strategies/spherical/line_interpolate.hpp b/boost/geometry/strategies/spherical/line_interpolate.hpp
new file mode 100644
index 0000000000..2d602c0e06
--- /dev/null
+++ b/boost/geometry/strategies/spherical/line_interpolate.hpp
@@ -0,0 +1,123 @@
+// Boost.Geometry
+
+// Copyright (c) 2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_LINE_INTERPOLATE_HPP
+#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_LINE_INTERPOLATE_HPP
+
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/formulas/interpolate_point_spherical.hpp>
+#include <boost/geometry/srs/spheroid.hpp>
+#include <boost/geometry/strategies/line_interpolate.hpp>
+#include <boost/geometry/strategies/spherical/distance_haversine.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace line_interpolate
+{
+
+
+/*!
+\brief Interpolate point on a spherical segment.
+\ingroup strategies
+\tparam CalculationType \tparam_calculation
+\tparam DistanceStrategy The underlying point-point distance strategy
+
+\qbk{
+[heading See also]
+\* [link geometry.reference.algorithms.line_interpolate.line_interpolate_4_with_strategy line_interpolate (with strategy)]
+}
+
+ */
+template
+<
+ typename CalculationType = void,
+ typename DistanceStrategy = distance::haversine<double, CalculationType>
+>
+class spherical
+{
+public:
+
+ typedef typename DistanceStrategy::radius_type radius_type;
+
+ inline spherical()
+ {}
+
+ explicit inline spherical(typename DistanceStrategy::radius_type const& r)
+ : m_strategy(r)
+ {}
+
+ inline spherical(DistanceStrategy const& s)
+ : m_strategy(s)
+ {}
+
+ // point-point strategy getters
+ struct distance_pp_strategy
+ {
+ typedef DistanceStrategy type;
+ };
+
+ inline typename distance_pp_strategy::type get_distance_pp_strategy() const
+ {
+ return m_strategy;
+ }
+
+ template <typename Point, typename Fraction, typename Distance>
+ inline void apply(Point const& p0,
+ Point const& p1,
+ Fraction const& fraction,
+ Point & p,
+ Distance const&) const
+ {
+ typedef typename select_calculation_type_alt
+ <
+ CalculationType,
+ Point
+ >::type calc_t;
+
+ formula::interpolate_point_spherical<calc_t> formula;
+
+ calc_t angle01;
+ formula.compute_angle(p0, p1, angle01);
+ formula.compute_axis(p0, angle01);
+
+ calc_t a = angle01 * fraction;
+ formula.compute_point(a, p);
+ }
+private :
+ DistanceStrategy m_strategy;
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <>
+struct default_strategy<spherical_equatorial_tag>
+{
+ typedef strategy::line_interpolate::spherical<> type;
+};
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::line_interpolate
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_LINE_INTERPOLATE_HPP
diff --git a/boost/geometry/strategies/spherical/point_in_point.hpp b/boost/geometry/strategies/spherical/point_in_point.hpp
new file mode 100644
index 0000000000..372e9cfaca
--- /dev/null
+++ b/boost/geometry/strategies/spherical/point_in_point.hpp
@@ -0,0 +1,172 @@
+// 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) 2013-2015 Adam Wulkiewicz, Lodz, Poland
+
+// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018.
+// Modifications copyright (c) 2013-2018, 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.
+
+// 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_STRATEGY_SPHERICAL_POINT_IN_POINT_HPP
+#define BOOST_GEOMETRY_STRATEGY_SPHERICAL_POINT_IN_POINT_HPP
+
+#include <cstddef>
+
+#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/algorithms/detail/normalize.hpp>
+#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
+#include <boost/geometry/algorithms/transform.hpp>
+
+#include <boost/geometry/geometries/helper_geometry.hpp>
+
+#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
+#include <boost/geometry/strategies/covered_by.hpp>
+#include <boost/geometry/strategies/strategy_transform.hpp>
+#include <boost/geometry/strategies/within.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace within
+{
+
+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;
+ strategy::normalize::spherical_point::apply(point1, point1_normalized);
+ helper_point_type2 point2_normalized;
+ strategy::normalize::spherical_point::apply(point2, point2_normalized);
+
+ 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 detail::cs_angular_units<Point1>::type,
+ typename detail::cs_angular_units<Point2>::type
+ >::value
+ >::apply(point1, point2);
+ }
+};
+
+}} // namespace detail::within
+#endif // DOXYGEN_NO_DETAIL
+
+
+namespace strategy { namespace within
+{
+
+struct spherical_point_point
+ : geometry::detail::within::point_point_on_spheroid
+{};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename PointLike1, typename PointLike2, typename Tag1, typename Tag2>
+struct default_strategy<PointLike1, PointLike2, Tag1, Tag2, pointlike_tag, pointlike_tag, spherical_tag, spherical_tag>
+{
+ typedef strategy::within::spherical_point_point type;
+};
+
+} // namespace services
+#endif
+
+
+}} // namespace strategy::within
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace strategy { namespace covered_by { namespace services
+{
+
+template <typename PointLike1, typename PointLike2, typename Tag1, typename Tag2>
+struct default_strategy<PointLike1, PointLike2, Tag1, Tag2, pointlike_tag, pointlike_tag, spherical_tag, spherical_tag>
+{
+ typedef strategy::within::spherical_point_point type;
+};
+
+}}} // namespace strategy::covered_by::services
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGY_SPHERICAL_POINT_IN_POINT_HPP
diff --git a/boost/geometry/strategies/spherical/point_in_poly_winding.hpp b/boost/geometry/strategies/spherical/point_in_poly_winding.hpp
index c942cbe460..c283b53335 100644
--- a/boost/geometry/strategies/spherical/point_in_poly_winding.hpp
+++ b/boost/geometry/strategies/spherical/point_in_poly_winding.hpp
@@ -3,8 +3,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2013-2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2013, 2014, 2016, 2017.
-// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2013, 2014, 2016, 2017, 2018.
+// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@@ -27,8 +27,10 @@
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
+#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
#include <boost/geometry/strategies/covered_by.hpp>
#include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/strategies/spherical/disjoint_box_box.hpp>
#include <boost/geometry/strategies/spherical/ssf.hpp>
#include <boost/geometry/strategies/within.hpp>
@@ -63,7 +65,7 @@ class spherical_winding_base
CalculationType
>::type calculation_type;
- typedef typename coordinate_system<Point>::type::units units_t;
+ typedef typename geometry::detail::cs_angular_units<Point>::type units_t;
typedef math::detail::constants_on_spheroid<calculation_type, units_t> constants;
/*! subclass to keep state */
@@ -140,6 +142,20 @@ public:
return m_side_strategy.get_disjoint_strategy();
}
+ typedef typename SideStrategy::equals_point_point_strategy_type equals_point_point_strategy_type;
+ inline equals_point_point_strategy_type get_equals_point_point_strategy() const
+ {
+ return m_side_strategy.get_equals_point_point_strategy();
+ }
+
+ typedef disjoint::spherical_box_box disjoint_box_box_strategy_type;
+ static inline disjoint_box_box_strategy_type get_disjoint_box_box_strategy()
+ {
+ return disjoint_box_box_strategy_type();
+ }
+
+ typedef covered_by::spherical_point_box disjoint_point_box_strategy_type;
+
spherical_winding_base()
{}
@@ -434,7 +450,7 @@ private:
count_info const& ci) const
{
typedef typename coordinate_type<PointOfSegment>::type scoord_t;
- typedef typename coordinate_system<PointOfSegment>::type::units units_t;
+ typedef typename geometry::detail::cs_angular_units<PointOfSegment>::type units_t;
if (math::equals(get<1>(point), get<1>(se)))
{
diff --git a/boost/geometry/strategies/spherical/ssf.hpp b/boost/geometry/strategies/spherical/ssf.hpp
index 03f5428ede..18c547ced8 100644
--- a/boost/geometry/strategies/spherical/ssf.hpp
+++ b/boost/geometry/strategies/spherical/ssf.hpp
@@ -2,8 +2,8 @@
// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2016.
-// Modifications copyright (c) 2016, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2016, 2018.
+// Modifications copyright (c) 2016-2018, 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,
@@ -24,8 +24,9 @@
#include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/strategies/spherical/disjoint_segment_box.hpp>
-#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
+#include <boost/geometry/strategies/spherical/envelope.hpp>
//#include <boost/geometry/strategies/concepts/side_concept.hpp>
+#include <boost/geometry/strategies/spherical/point_in_point.hpp>
namespace boost { namespace geometry
@@ -84,7 +85,7 @@ class spherical_side_formula
{
public :
- typedef strategy::envelope::spherical_segment<CalculationType> envelope_strategy_type;
+ typedef strategy::envelope::spherical<CalculationType> envelope_strategy_type;
static inline envelope_strategy_type get_envelope_strategy()
{
@@ -98,6 +99,12 @@ public :
return disjoint_strategy_type();
}
+ typedef strategy::within::spherical_point_point equals_point_point_strategy_type;
+ static inline equals_point_point_strategy_type get_equals_point_point_strategy()
+ {
+ return equals_point_point_strategy_type();
+ }
+
template <typename P1, typename P2, typename P>
static inline int apply(P1 const& p1, P2 const& p2, P const& p)
{
diff --git a/boost/geometry/strategies/strategies.hpp b/boost/geometry/strategies/strategies.hpp
index b6430692f4..026214173f 100644
--- a/boost/geometry/strategies/strategies.hpp
+++ b/boost/geometry/strategies/strategies.hpp
@@ -70,6 +70,7 @@
#include <boost/geometry/strategies/cartesian/point_in_poly_franklin.hpp>
#include <boost/geometry/strategies/cartesian/point_in_poly_crossings_multiply.hpp>
#include <boost/geometry/strategies/cartesian/point_in_poly_winding.hpp>
+#include <boost/geometry/strategies/cartesian/line_interpolate.hpp>
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategies/spherical/area.hpp>
@@ -85,10 +86,12 @@
#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
#include <boost/geometry/strategies/spherical/intersection.hpp>
#include <boost/geometry/strategies/spherical/point_in_poly_winding.hpp>
+#include <boost/geometry/strategies/spherical/line_interpolate.hpp>
#include <boost/geometry/strategies/spherical/ssf.hpp>
#include <boost/geometry/strategies/geographic/area.hpp>
#include <boost/geometry/strategies/geographic/azimuth.hpp>
+#include <boost/geometry/strategies/geographic/buffer_point_circle.hpp>
#include <boost/geometry/strategies/geographic/densify.hpp>
#include <boost/geometry/strategies/geographic/disjoint_segment_box.hpp>
#include <boost/geometry/strategies/geographic/distance.hpp>
@@ -103,6 +106,7 @@
#include <boost/geometry/strategies/geographic/intersection.hpp>
//#include <boost/geometry/strategies/geographic/intersection_elliptic.hpp>
#include <boost/geometry/strategies/geographic/point_in_poly_winding.hpp>
+#include <boost/geometry/strategies/geographic/line_interpolate.hpp>
#include <boost/geometry/strategies/geographic/side.hpp>
#include <boost/geometry/strategies/geographic/side_andoyer.hpp>
#include <boost/geometry/strategies/geographic/side_thomas.hpp>
diff --git a/boost/geometry/util/calculation_type.hpp b/boost/geometry/util/calculation_type.hpp
index 18eac4fbb7..cff4b9421e 100644
--- a/boost/geometry/util/calculation_type.hpp
+++ b/boost/geometry/util/calculation_type.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2012 Bruno Lalande, Paris, France.
// Copyright (c) 2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2018.
+// Modifications copyright (c) 2018, 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)
@@ -13,6 +18,7 @@
#include <boost/config.hpp>
#include <boost/mpl/if.hpp>
+#include <boost/static_assert.hpp>
#include <boost/type_traits/is_floating_point.hpp>
#include <boost/type_traits/is_fundamental.hpp>
#include <boost/type_traits/is_void.hpp>
diff --git a/boost/geometry/util/combine_if.hpp b/boost/geometry/util/combine_if.hpp
index 5d94c34461..11050e4e55 100644
--- a/boost/geometry/util/combine_if.hpp
+++ b/boost/geometry/util/combine_if.hpp
@@ -2,10 +2,11 @@
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2018.
+// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -17,13 +18,13 @@
#ifndef BOOST_GEOMETRY_UTIL_COMBINE_IF_HPP
#define BOOST_GEOMETRY_UTIL_COMBINE_IF_HPP
+#include <boost/mpl/bind.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/if.hpp>
-#include <boost/mpl/bind.hpp>
-#include <boost/mpl/set.hpp>
#include <boost/mpl/insert.hpp>
+#include <boost/mpl/pair.hpp>
#include <boost/mpl/placeholders.hpp>
-
+#include <boost/mpl/set.hpp>
namespace boost { namespace geometry
{
diff --git a/boost/geometry/util/is_inverse_spheroidal_coordinates.hpp b/boost/geometry/util/is_inverse_spheroidal_coordinates.hpp
index d67251254d..59746653a6 100644
--- a/boost/geometry/util/is_inverse_spheroidal_coordinates.hpp
+++ b/boost/geometry/util/is_inverse_spheroidal_coordinates.hpp
@@ -3,6 +3,7 @@
// Copyright (c) 2018 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -11,6 +12,10 @@
#ifndef BOOST_GEOMETRY_UTIL_IS_INVERSE_SPHEROIDAL_COORDINATES_HPP
#define BOOST_GEOMETRY_UTIL_IS_INVERSE_SPHEROIDAL_COORDINATES_HPP
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/point_type.hpp>
+
#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry
diff --git a/boost/geometry/util/series_expansion.hpp b/boost/geometry/util/series_expansion.hpp
index d0b5e36567..d279e218b4 100644
--- a/boost/geometry/util/series_expansion.hpp
+++ b/boost/geometry/util/series_expansion.hpp
@@ -633,18 +633,19 @@ namespace boost { namespace geometry { namespace series_expansion {
inline void evaluate_coeffs_C3(Coeffs1 &coeffs1, Coeffs2 &coeffs2, CT const& eps)
{
CT mult = 1;
- int offset = 1;
+ int offset = 0;
// l is the index of C3[l].
for (size_t l = 1; l < Coeffs1::static_size; ++l)
{
// Order of polynomial in eps.
- int m = Coeffs1::static_size - l - 1;
+ int m = Coeffs1::static_size - l;
mult *= eps;
- coeffs1[l] = mult * math::polyval(coeffs2.begin(), coeffs2.begin() + offset, eps);
+ coeffs1[l] = mult * math::horner_evaluate(eps, coeffs2.begin() + offset,
+ coeffs2.begin() + offset + m);
- offset += m + 1;
+ offset += m;
}
// Post condition: offset == coeffs_C3_size
}
diff --git a/boost/geometry/views/detail/boundary_view/implementation.hpp b/boost/geometry/views/detail/boundary_view/implementation.hpp
index 971a6fe002..fb5c119fbd 100644
--- a/boost/geometry/views/detail/boundary_view/implementation.hpp
+++ b/boost/geometry/views/detail/boundary_view/implementation.hpp
@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2015, Oracle and/or its affiliates.
+// Copyright (c) 2015, 2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -23,7 +24,6 @@
#include <boost/iterator/iterator_categories.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/if.hpp>
-#include <boost/range.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/remove_reference.hpp>
@@ -40,6 +40,7 @@
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/views/closeable_view.hpp>
+#include <boost/geometry/views/detail/boundary_view/interface.hpp>
#include <boost/geometry/algorithms/num_interior_rings.hpp>