diff --git a/doc/example_adapting_a_legacy_geometry_object_model.qbk b/doc/example_adapting_a_legacy_geometry_object_model.qbk index 8c3b9b3a2..cf3b4dff3 100644 --- a/doc/example_adapting_a_legacy_geometry_object_model.qbk +++ b/doc/example_adapting_a_legacy_geometry_object_model.qbk @@ -122,7 +122,7 @@ That's it! The methods of __boost_geometry__ can now be used directly on instanc { typedef point_tag type; }; template<> struct coordinate_type - { typedef QPoint::double type; }; + { typedef double type; }; template<> struct coordinate_system { typedef cs::cartesian type; }; diff --git a/doc/geometry.qbk b/doc/geometry.qbk index 442604534..6c30c833a 100644 --- a/doc/geometry.qbk +++ b/doc/geometry.qbk @@ -1,9 +1,10 @@ [/============================================================================ Boost.Geometry (aka GGL, Generic Geometry Library) - Copyright (c) 2009-2015 Barend Gehrels, Amsterdam, the Netherlands. - Copyright (c) 2009-2015 Mateusz Loskot, London, UK. - Copyright (c) 2009-2015 Bruno Lalande, Paris, France. + Copyright (c) 2009-2017 Barend Gehrels, Amsterdam, the Netherlands. + Copyright (c) 2009-2017 Mateusz Loskot, London, UK. + Copyright (c) 2009-2017 Bruno Lalande, Paris, France. + Copyright (c) 2011-2017 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 @@ -12,8 +13,8 @@ [library Geometry [quickbook 1.5] - [authors [Gehrels, Barend], [Lalande, Bruno], [Loskot, Mateusz], [Wulkiewicz, Adam], [Karavelas, Menelaos]] - [copyright 2009-2015 Barend Gehrels, Bruno Lalande, Mateusz Loskot, Adam Wulkiewicz, Oracle and/or its affiliates] + [authors [Gehrels, Barend], [Lalande, Bruno], [Loskot, Mateusz], [Wulkiewicz, Adam], [Karavelas, Menelaos], [Fisikopoulos, Vissarion]] + [copyright 2009-2017 Barend Gehrels, Bruno Lalande, Mateusz Loskot, Adam Wulkiewicz, Oracle and/or its affiliates] [purpose Documentation of Boost.Geometry library] [license Distributed under the Boost Software License, Version 1.0. diff --git a/doc/html/index.html b/doc/html/index.html index 841fbf5b1..d8afcf098 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -37,8 +37,12 @@

Menelaos Karavelas

-
+

+Vissarion Fisikopoulos +

+
- +

Last revised: July 17, 2014 at 20:45:09 GMT

Last revised: February 26, 2017 at 00:30:21 GMT


diff --git a/doc/make_qbk.py b/doc/make_qbk.py index a37d97c4d..db6cc0ab9 100755 --- a/doc/make_qbk.py +++ b/doc/make_qbk.py @@ -135,7 +135,7 @@ strategies = ["distance::pythagoras", "distance::pythagoras_box_box" , "side::side_by_triangle", "side::side_by_cross_track", "side::spherical_side_formula" , "transform::inverse_transformer", "transform::map_transformer" , "transform::rotate_transformer", "transform::scale_transformer" - , "transform::translate_transformer", "transform::ublas_transformer" + , "transform::translate_transformer", "transform::matrix_transformer" ] views = ["box_view", "segment_view" diff --git a/doc/quickref.xml b/doc/quickref.xml index fd41ee4ec..5b095811a 100644 --- a/doc/quickref.xml +++ b/doc/quickref.xml @@ -521,7 +521,7 @@ Area strategy::area::surveyor - strategy::area::huiller + @@ -586,7 +586,7 @@ strategy::transform::inverse_transformer strategy::transform::map_transformer - strategy::transform::ublas_transformer + strategy::transform::matrix_transformer strategy::transform::translate_transformer strategy::transform::scale_transformer strategy::transform::rotate_transformer diff --git a/doc/reference.qbk b/doc/reference.qbk index d1dac073a..f73060181 100644 --- a/doc/reference.qbk +++ b/doc/reference.qbk @@ -1,15 +1,16 @@ [/============================================================================ Boost.Geometry (aka GGL, Generic Geometry Library) - Copyright (c) 2009-2014 Barend Gehrels, Amsterdam, the Netherlands. - Copyright (c) 2009-2014 Mateusz Loskot, London, UK. - Copyright (c) 2009-2014 Bruno Lalande, Paris, France. - Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland. + Copyright (c) 2009-2017 Barend Gehrels, Amsterdam, the Netherlands. + Copyright (c) 2009-2017 Mateusz Loskot, London, UK. + Copyright (c) 2009-2017 Bruno Lalande, Paris, France. + Copyright (c) 2013-2017 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, 2017. + Modifications copyright (c) 2014-2017, Oracle and/or its affiliates. Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle Use, modification and distribution is subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -94,10 +95,15 @@ [include generated/covered_by.qbk] [endsect] +[section:crosses crosses] [include generated/crosses.qbk] +[endsect] [include generated/difference.qbk] + +[section:disjoint disjoint] [include generated/disjoint.qbk] +[endsect] [section:distance distance] [include generated/distance.qbk] @@ -107,8 +113,13 @@ [include generated/envelope.qbk] [endsect] +[section:equals equals] [include generated/equals.qbk] +[endsect] + +[section:expand expand] [include generated/expand.qbk] +[endsect] [section:for_each for_each] [include generated/for_each.qbk] @@ -143,16 +154,21 @@ [include generated/num_points.qbk] [include generated/num_segments.qbk] - +[section:overlaps overlaps] [include generated/overlaps.qbk] +[endsect] [section:perimeter perimeter] [include generated/perimeter.qbk] [endsect] +[section:relate relate] [include generated/relate.qbk] +[endsect] +[section:relation relation] [include generated/relation.qbk] +[endsect] [include generated/reverse.qbk] @@ -317,7 +333,7 @@ [include generated/distance_cross_track.qbk] [include generated/distance_cross_track_point_box.qbk] [include generated/area_surveyor.qbk] -[include generated/area_huiller.qbk] +[/include generated/area_huiller.qbk] [include generated/buffer_join_round.qbk] [include generated/buffer_join_miter.qbk] [include generated/buffer_end_round.qbk] @@ -339,7 +355,7 @@ [include generated/transform_rotate_transformer.qbk] [include generated/transform_scale_transformer.qbk] [include generated/transform_translate_transformer.qbk] -[include generated/transform_ublas_transformer.qbk] +[include generated/transform_matrix_transformer.qbk] [include generated/within_winding.qbk] [include generated/within_franklin.qbk] [include generated/within_crossings_multiply.qbk] diff --git a/doc/release_notes.qbk b/doc/release_notes.qbk index 3c1800664..95d580be1 100644 --- a/doc/release_notes.qbk +++ b/doc/release_notes.qbk @@ -1,13 +1,13 @@ [/============================================================================ Boost.Geometry (aka GGL, Generic Geometry Library) - Copyright (c) 2009-2016 Barend Gehrels, Geodan, Amsterdam, the Netherlands. - Copyright (c) 2009-2016 Bruno Lalande, Paris, France. - Copyright (c) 2009-2016 Mateusz Loskot , London, UK. - Copyright (c) 2011-2016 Adam Wulkiewicz, Lodz, Poland. + Copyright (c) 2009-2017 Barend Gehrels, Geodan, Amsterdam, the Netherlands. + Copyright (c) 2009-2017 Bruno Lalande, Paris, France. + Copyright (c) 2009-2017 Mateusz Loskot , London, UK. + Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland. - This file was modified by Oracle on 2015, 2016. - Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. + This file was modified by Oracle on 2015, 2017. + Modifications copyright (c) 2015-2017, Oracle and/or its affiliates. Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -18,6 +18,28 @@ [section:release_notes Release Notes] +[/=================] +[heading Boost 1.64] +[/=================] + +[*Improvements] + +* matrix transformation is now based on Boost.QVM instead of Boost.Ublas + +[*Breaking changes] + +* ublas_transformer is renamed to matrix_transformer + +[*Solved issues] + +* [@https://github.com/boostorg/geometry/issues/363 363] Missing includes in geometry/index/parameters.hpp +* [@https://github.com/boostorg/geometry/issues/364 364] within(Linear, Areal) compilation error when arguments use different point types + +[*Solved tickets] + +* [@https://svn.boost.org/trac/boost/ticket/12566 12566] Ambiguous template instantiation in equal_to<> when pair value contains raw pointer +* [@https://svn.boost.org/trac/boost/ticket/12861 12566] Segmentation fault in stdlibc++ (gcc 4.8.2) affecting rtree + [/=================] [heading Boost 1.63] [/=================] @@ -44,8 +66,11 @@ * Rename namespace concept to concepts to avoid conflicts with the newest compilers * New spherical intersection strategy used in relational and set operations for spherical and geographic Geometries (previously cartesian intersection strategy was used for all coordinate systems). -* [@https://svn.boost.org/trac/boost/ticket/12189 12189] Relational operations not compiling when point types of inputs are different +[*Solved tickets] + +* [@https://svn.boost.org/trac/boost/ticket/12189 12189] Relational operations not compiling when point types of inputs are different (cartesian, affecting rtree) * [@https://svn.boost.org/trac/boost/ticket/12287 12287] Invalid result of rtree.query() for contains() predicate +* [@https://svn.boost.org/trac/boost/ticket/12342 12342] Relational operations not compiling when point types of inputs are different (geographic, affecting rtree) [/=================] [heading Boost 1.61] diff --git a/example/06_b_transformation_example.cpp b/example/06_b_transformation_example.cpp index b8de5b5f5..ad7f75b33 100644 --- a/example/06_b_transformation_example.cpp +++ b/example/06_b_transformation_example.cpp @@ -144,9 +144,7 @@ int main() // Compose matrix for the two transformation // Create transformer attached to the transformation matrix - ublas_transformer - combined(boost::numeric::ublas::prod(rotate.matrix(), translate.matrix())); - //combined(rotate.matrix()); + matrix_transformer combined(rotate.matrix() * translate.matrix()); // Apply transformation to subject geometry point-by-point model::polygon g4; diff --git a/include/boost/geometry/algorithms/buffer.hpp b/include/boost/geometry/algorithms/buffer.hpp index e1d3c20e4..fd6f0fbe6 100644 --- a/include/boost/geometry/algorithms/buffer.hpp +++ b/include/boost/geometry/algorithms/buffer.hpp @@ -4,6 +4,10 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 2017. +// Modifications copyright (c) 2017 Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -274,6 +278,11 @@ inline void buffer(GeometryIn const& geometry_in, geometry::envelope(geometry_in, box); geometry::buffer(box, box, distance_strategy.max_distance(join_strategy, end_strategy)); + typename strategy::intersection::services::default_strategy + < + typename cs_tag::type + >::type intersection_strategy; + rescale_policy_type rescale_policy = boost::geometry::get_rescale_policy(box); @@ -283,6 +292,7 @@ inline void buffer(GeometryIn const& geometry_in, join_strategy, end_strategy, point_strategy, + intersection_strategy, rescale_policy); } diff --git a/include/boost/geometry/algorithms/covered_by.hpp b/include/boost/geometry/algorithms/covered_by.hpp index 2001d5810..f9d9dcc48 100644 --- a/include/boost/geometry/algorithms/covered_by.hpp +++ b/include/boost/geometry/algorithms/covered_by.hpp @@ -4,8 +4,10 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2013, 2014. -// Modifications copyright (c) 2013, 2014 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2017. +// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -14,8 +16,6 @@ // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle - #ifndef BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP #define BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP @@ -51,9 +51,13 @@ struct use_point_in_geometry struct use_relate { template - static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& /*strategy*/) + static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy) { - return Strategy::apply(geometry1, geometry2); + typedef typename detail::de9im::static_mask_covered_by_type + < + Geometry1, Geometry2 + >::type covered_by_mask; + return geometry::relate(geometry1, geometry2, covered_by_mask(), strategy); } }; @@ -281,23 +285,8 @@ struct covered_by Geometry2 const& geometry2, default_strategy) { - typedef typename point_type::type point_type1; - typedef typename point_type::type point_type2; - typedef typename strategy::covered_by::services::default_strategy < - typename tag::type, - typename tag::type, - typename tag::type, - typename tag_cast::type, areal_tag>::type, - typename tag_cast - < - typename cs_tag::type, spherical_tag - >::type, - typename tag_cast - < - typename cs_tag::type, spherical_tag - >::type, Geometry1, Geometry2 >::type strategy_type; diff --git a/include/boost/geometry/algorithms/crosses.hpp b/include/boost/geometry/algorithms/crosses.hpp index 73d86ef52..c9e3651ab 100644 --- a/include/boost/geometry/algorithms/crosses.hpp +++ b/include/boost/geometry/algorithms/crosses.hpp @@ -5,8 +5,10 @@ // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // Copyright (c) 2014 Samuel Debionne, Grenoble, France. -// This file was modified by Oracle on 2014. -// Modifications copyright (c) 2014 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2017. +// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -15,8 +17,6 @@ // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle - #ifndef BOOST_GEOMETRY_ALGORITHMS_CROSSES_HPP #define BOOST_GEOMETRY_ALGORITHMS_CROSSES_HPP @@ -26,12 +26,12 @@ #include #include -#include - -#include - #include #include +#include +#include +#include + namespace boost { namespace geometry { @@ -62,20 +62,51 @@ struct crosses #endif // DOXYGEN_NO_DISPATCH +namespace resolve_strategy +{ + +struct crosses +{ + template + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) + { + concepts::check(); + concepts::check(); + + return dispatch::crosses::apply(geometry1, geometry2, strategy); + } + + template + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + default_strategy) + { + typedef typename strategy::relate::services::default_strategy + < + Geometry1, + Geometry2 + >::type strategy_type; + + return apply(geometry1, geometry2, strategy_type()); + } +}; + +} // namespace resolve_strategy + + namespace resolve_variant { template struct crosses { - static inline bool - apply( - const Geometry1& geometry1, - const Geometry2& geometry2) + template + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) { - concepts::check(); - concepts::check(); - - return dispatch::crosses::apply(geometry1, geometry2); + return resolve_strategy::crosses::apply(geometry1, geometry2, strategy); } }; @@ -83,12 +114,15 @@ namespace resolve_variant template struct crosses, Geometry2> { + template struct visitor: static_visitor { Geometry2 const& m_geometry2; + Strategy const& m_strategy; - visitor(Geometry2 const& geometry2) + visitor(Geometry2 const& geometry2, Strategy const& strategy) : m_geometry2(geometry2) + , m_strategy(strategy) {} template @@ -98,15 +132,16 @@ namespace resolve_variant < Geometry1, Geometry2 - >::apply(geometry1, m_geometry2); + >::apply(geometry1, m_geometry2, m_strategy); } }; - static inline bool - apply(variant const& geometry1, - Geometry2 const& geometry2) + template + static inline bool apply(variant const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) { - return boost::apply_visitor(visitor(geometry2), geometry1); + return boost::apply_visitor(visitor(geometry2, strategy), geometry1); } }; @@ -114,12 +149,15 @@ namespace resolve_variant template struct crosses > { + template struct visitor: static_visitor { Geometry1 const& m_geometry1; + Strategy const& m_strategy; - visitor(Geometry1 const& geometry1) + visitor(Geometry1 const& geometry1, Strategy const& strategy) : m_geometry1(geometry1) + , m_strategy(strategy) {} template @@ -129,15 +167,16 @@ namespace resolve_variant < Geometry1, Geometry2 - >::apply(m_geometry1, geometry2); + >::apply(m_geometry1, geometry2, m_strategy); } }; - static inline bool - apply(Geometry1 const& geometry1, - const variant& geometry2) + template + static inline bool apply(Geometry1 const& geometry1, + variant const& geometry2, + Strategy const& strategy) { - return boost::apply_visitor(visitor(geometry1), geometry2); + return boost::apply_visitor(visitor(geometry1, strategy), geometry2); } }; @@ -145,8 +184,15 @@ namespace resolve_variant template struct crosses, variant > { + template struct visitor: static_visitor { + Strategy const& m_strategy; + + visitor(Strategy const& strategy) + : m_strategy(strategy) + {} + template result_type operator()(Geometry1 const& geometry1, Geometry2 const& geometry2) const @@ -155,21 +201,47 @@ namespace resolve_variant < Geometry1, Geometry2 - >::apply(geometry1, geometry2); + >::apply(geometry1, geometry2, m_strategy); } }; - static inline bool - apply(const variant& geometry1, - const variant& geometry2) + template + static inline bool apply(variant const& geometry1, + variant const& geometry2, + Strategy const& strategy) { - return boost::apply_visitor(visitor(), geometry1, geometry2); + return boost::apply_visitor(visitor(strategy), geometry1, geometry2); } }; } // namespace resolve_variant +/*! +\brief \brief_check2{crosses} +\ingroup crosses +\tparam Geometry1 \tparam_geometry +\tparam Geometry2 \tparam_geometry +\tparam Strategy \tparam_strategy{Crosses} +\param geometry1 \param_geometry +\param geometry2 \param_geometry +\param strategy \param_strategy{crosses} +\return \return_check2{crosses} + +\qbk{distinguish,with strategy} +\qbk{[include reference/algorithms/crosses.qbk]} +*/ +template +inline bool crosses(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) +{ + return resolve_variant::crosses + < + Geometry1, Geometry2 + >::apply(geometry1, geometry2, strategy); +} + /*! \brief \brief_check2{crosses} \ingroup crosses @@ -184,7 +256,10 @@ namespace resolve_variant template inline bool crosses(Geometry1 const& geometry1, Geometry2 const& geometry2) { - return resolve_variant::crosses::apply(geometry1, geometry2); + return resolve_variant::crosses + < + Geometry1, Geometry2 + >::apply(geometry1, geometry2, default_strategy()); } }} // namespace boost::geometry diff --git a/include/boost/geometry/algorithms/detail/azimuth.hpp b/include/boost/geometry/algorithms/detail/azimuth.hpp index 7e0d1691e..a5863d7d2 100644 --- a/include/boost/geometry/algorithms/detail/azimuth.hpp +++ b/include/boost/geometry/algorithms/detail/azimuth.hpp @@ -2,9 +2,10 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2014, 2016. -// Modifications copyright (c) 2014-2016, Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2016, 2017. +// Modifications copyright (c) 2014-2017, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -23,6 +24,7 @@ #include +#include #include namespace boost { namespace geometry @@ -69,22 +71,9 @@ struct azimuth template static inline ReturnType apply(P1 const& p1, P2 const& p2, Sphere const& /*unused*/) { - // http://williams.best.vwh.net/avform.htm#Crs - ReturnType dlon = get_as_radian<0>(p2) - get_as_radian<0>(p1); - ReturnType cos_p2lat = cos(get_as_radian<1>(p2)); - - // An optimization which should kick in often for Boxes - //if ( math::equals(dlon, ReturnType(0)) ) - //if ( get<0>(p1) == get<0>(p2) ) - //{ - // return - sin(get_as_radian<1>(p1)) * cos_p2lat); - //} - - // "An alternative formula, not requiring the pre-computation of d" - // In the formula below dlon is used as "d" - return atan2(sin(dlon) * cos_p2lat, - cos(get_as_radian<1>(p1)) * sin(get_as_radian<1>(p2)) - - sin(get_as_radian<1>(p1)) * cos_p2lat * cos(dlon)); + return geometry::formula::spherical_azimuth + ( get_as_radian<0>(p1), get_as_radian<1>(p1), + get_as_radian<0>(p2), get_as_radian<1>(p2)).azimuth; } template diff --git a/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp b/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp index 8447532a6..ce55a2bfb 100644 --- a/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp @@ -2,6 +2,10 @@ // Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2017. +// Modifications copyright (c) 2017 Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -854,6 +858,7 @@ template typename JoinStrategy, typename EndStrategy, typename PointStrategy, + typename IntersectionStrategy, typename RobustPolicy, typename VisitPiecesPolicy > @@ -863,6 +868,7 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator JoinStrategy const& join_strategy, EndStrategy const& end_strategy, PointStrategy const& point_strategy, + IntersectionStrategy const& intersection_strategy, RobustPolicy const& robust_policy, VisitPiecesPolicy& visit_pieces_policy ) @@ -872,9 +878,10 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator typedef detail::buffer::buffered_piece_collection < typename geometry::ring_type::type, + IntersectionStrategy, RobustPolicy > collection_type; - collection_type collection(robust_policy); + collection_type collection(intersection_strategy, robust_policy); collection_type const& const_collection = collection; bool const areal = boost::is_same @@ -961,6 +968,7 @@ template typename JoinStrategy, typename EndStrategy, typename PointStrategy, + typename IntersectionStrategy, typename RobustPolicy > inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator out, @@ -969,13 +977,14 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator JoinStrategy const& join_strategy, EndStrategy const& end_strategy, PointStrategy const& point_strategy, + IntersectionStrategy const& intersection_strategy, RobustPolicy const& robust_policy) { detail::buffer::visit_pieces_default_policy visitor; buffer_inserter(geometry_input, out, distance_strategy, side_strategy, join_strategy, end_strategy, point_strategy, - robust_policy, visitor); + intersection_strategy, robust_policy, visitor); } #endif // DOXYGEN_NO_DETAIL diff --git a/include/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp b/include/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp index c1f04f93b..92dcdcc7b 100644 --- a/include/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp @@ -2,6 +2,10 @@ // Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2017. +// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -52,6 +56,7 @@ public : typename Rings, typename Turns, typename Geometry, + typename Strategy, typename RobustPolicy, typename Visitor > @@ -63,6 +68,7 @@ public : detail::overlay::traverse_error_type /*traverse_error*/, Geometry const& , Geometry const& , + Strategy const& , RobustPolicy const& , state_type& state, Visitor& /*visitor*/ diff --git a/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp b/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp index e7214428e..7fbbb790b 100644 --- a/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2016. -// Modifications copyright (c) 2016 Oracle and/or its affiliates. +// This file was modified by Oracle on 2016-2017. +// Modifications copyright (c) 2016-2017 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -117,10 +117,13 @@ enum segment_relation_code */ -template +template struct buffered_piece_collection { - typedef buffered_piece_collection this_type; + typedef buffered_piece_collection + < + Ring, IntersectionStrategy, RobustPolicy + > this_type; typedef typename geometry::point_type::type point_type; typedef typename geometry::coordinate_type::type coordinate_type; @@ -303,7 +306,7 @@ struct buffered_piece_collection cluster_type m_clusters; - + IntersectionStrategy const& m_intersection_strategy; RobustPolicy const& m_robust_policy; struct redundant_turn @@ -314,8 +317,10 @@ struct buffered_piece_collection } }; - buffered_piece_collection(RobustPolicy const& robust_policy) + buffered_piece_collection(IntersectionStrategy const& intersection_strategy, + RobustPolicy const& robust_policy) : m_first_piece_index(-1) + , m_intersection_strategy(intersection_strategy) , m_robust_policy(robust_policy) {} @@ -512,10 +517,11 @@ struct buffered_piece_collection geometry::partition < robust_box_type, - turn_get_box, turn_in_original_ovelaps_box, - original_get_box, original_ovelaps_box, - include_turn_policy, detail::partition::include_all_policy - >::apply(m_turns, robust_originals, visitor); + include_turn_policy, + detail::partition::include_all_policy + >::apply(m_turns, robust_originals, visitor, + turn_get_box(), turn_in_original_ovelaps_box(), + original_get_box(), original_ovelaps_box()); bool const deflate = distance_strategy.negative(); @@ -767,15 +773,17 @@ struct buffered_piece_collection piece_vector_type, buffered_ring_collection >, turn_vector_type, + IntersectionStrategy, RobustPolicy - > visitor(m_pieces, offsetted_rings, m_turns, m_robust_policy); + > visitor(m_pieces, offsetted_rings, m_turns, + m_intersection_strategy, m_robust_policy); geometry::partition < - robust_box_type, - detail::section::get_section_box, - detail::section::overlaps_section_box - >::apply(monotonic_sections, visitor); + robust_box_type + >::apply(monotonic_sections, visitor, + detail::section::get_section_box(), + detail::section::overlaps_section_box()); } insert_rescaled_piece_turns(); @@ -795,10 +803,10 @@ struct buffered_piece_collection geometry::partition < - robust_box_type, - turn_get_box, turn_ovelaps_box, - piece_get_box, piece_ovelaps_box - >::apply(m_turns, m_pieces, visitor); + robust_box_type + >::apply(m_turns, m_pieces, visitor, + turn_get_box(), turn_ovelaps_box(), + piece_get_box(), piece_ovelaps_box()); } } @@ -1354,7 +1362,8 @@ struct buffered_piece_collection traversed_rings.clear(); buffer_overlay_visitor visitor; traverser::apply(offsetted_rings, offsetted_rings, - m_robust_policy, m_turns, traversed_rings, + m_intersection_strategy, m_robust_policy, + m_turns, traversed_rings, m_clusters, visitor); } diff --git a/include/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp b/include/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp index 3425ee6ff..178c7bcaf 100644 --- a/include/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp @@ -2,6 +2,10 @@ // Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2017. +// Modifications copyright (c) 2017 Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -62,6 +66,7 @@ template typename Pieces, typename Rings, typename Turns, + typename IntersectionStrategy, typename RobustPolicy > class piece_turn_visitor @@ -69,6 +74,7 @@ class piece_turn_visitor Pieces const& m_pieces; Rings const& m_rings; Turns& m_turns; + IntersectionStrategy const& m_intersection_strategy; RobustPolicy const& m_robust_policy; template @@ -243,7 +249,9 @@ class piece_turn_visitor turn_policy::apply(*prev1, *it1, *next1, *prev2, *it2, *next2, false, false, false, false, - the_model, m_robust_policy, + the_model, + m_intersection_strategy, + m_robust_policy, std::back_inserter(m_turns)); } } @@ -254,10 +262,12 @@ public: piece_turn_visitor(Pieces const& pieces, Rings const& ring_collection, Turns& turns, + IntersectionStrategy const& intersection_strategy, RobustPolicy const& robust_policy) : m_pieces(pieces) , m_rings(ring_collection) , m_turns(turns) + , m_intersection_strategy(intersection_strategy) , m_robust_policy(robust_policy) {} diff --git a/include/boost/geometry/algorithms/detail/calculate_sum.hpp b/include/boost/geometry/algorithms/detail/calculate_sum.hpp index b23e70171..732a2f575 100644 --- a/include/boost/geometry/algorithms/detail/calculate_sum.hpp +++ b/include/boost/geometry/algorithms/detail/calculate_sum.hpp @@ -8,6 +8,10 @@ // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2016. +// Modifications copyright (c) 2016 Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -30,7 +34,7 @@ class calculate_polygon_sum template static inline ReturnType sum_interior_rings(Rings const& rings, Strategy const& strategy) { - ReturnType sum = ReturnType(); + ReturnType sum = ReturnType(0); for (typename boost::range_iterator::type it = boost::begin(rings); it != boost::end(rings); ++it) { diff --git a/include/boost/geometry/algorithms/detail/disjoint/areal_areal.hpp b/include/boost/geometry/algorithms/detail/disjoint/areal_areal.hpp index 284858a13..664c99538 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/areal_areal.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/areal_areal.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2014 Mateusz Loskot, London, UK. // Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2013-2014. -// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013-2017. +// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -39,15 +39,45 @@ namespace detail { namespace disjoint { -template +template ::type> +struct check_each_ring_for_within_call_covered_by +{ + /*! + \tparam Strategy point_in_geometry strategy + */ + template + static inline bool apply(Point const& p, Geometry const& g, Strategy const& strategy) + { + return geometry::covered_by(p, g, strategy); + } +}; + +template +struct check_each_ring_for_within_call_covered_by +{ + template + static inline bool apply(Point const& p, Geometry const& g, Strategy const& ) + { + return geometry::covered_by(p, g); + } +}; + + +/*! +\tparam Strategy point_in_geometry strategy +*/ +template struct check_each_ring_for_within { bool not_disjoint; Geometry const& m_geometry; + Strategy const& m_strategy; - inline check_each_ring_for_within(Geometry const& g) + inline check_each_ring_for_within(Geometry const& g, + Strategy const& strategy) : not_disjoint(false) , m_geometry(g) + , m_strategy(strategy) {} template @@ -56,17 +86,26 @@ struct check_each_ring_for_within typename point_type::type pt; not_disjoint = not_disjoint || ( geometry::point_on_border(pt, range) - && geometry::covered_by(pt, m_geometry) ); + && check_each_ring_for_within_call_covered_by + < + Geometry + >::apply(pt, m_geometry, m_strategy) ); } }; - -template +/*! +\tparam Strategy point_in_geometry strategy +*/ +template inline bool rings_containing(FirstGeometry const& geometry1, - SecondGeometry const& geometry2) + SecondGeometry const& geometry2, + Strategy const& strategy) { - check_each_ring_for_within checker(geometry1); + check_each_ring_for_within + < + FirstGeometry, Strategy + > checker(geometry1, strategy); geometry::detail::for_each_range(geometry2, checker); return checker.not_disjoint; } @@ -76,10 +115,15 @@ inline bool rings_containing(FirstGeometry const& geometry1, template struct general_areal { - static inline - bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2) + /*! + \tparam Strategy relate (segments intersection) strategy + */ + template + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) { - if ( ! disjoint_linear::apply(geometry1, geometry2) ) + if ( ! disjoint_linear::apply(geometry1, geometry2, strategy) ) { return false; } @@ -90,8 +134,10 @@ struct general_areal // We check that using a point on the border (external boundary), // and see if that is contained in the other geometry. And vice versa. - if ( rings_containing(geometry1, geometry2) - || rings_containing(geometry2, geometry1) ) + if ( rings_containing(geometry1, geometry2, + strategy.template get_point_in_geometry_strategy()) + || rings_containing(geometry2, geometry1, + strategy.template get_point_in_geometry_strategy()) ) { return false; } diff --git a/include/boost/geometry/algorithms/detail/disjoint/box_box.hpp b/include/boost/geometry/algorithms/detail/disjoint/box_box.hpp index 3b81755e2..f830f8161 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/box_box.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/box_box.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2013-2016. -// Modifications copyright (c) 2013-2016, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013-2017. +// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -52,6 +52,12 @@ template > struct box_box { + template + 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(box1) < get(box2)) @@ -84,6 +90,12 @@ struct box_box template struct box_box { + template + static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const&) + { + return apply(box1, box2); + } + static inline bool apply(Box1 const& box1, Box2 const& box2) { typedef typename geometry::select_most_precise diff --git a/include/boost/geometry/algorithms/detail/disjoint/interface.hpp b/include/boost/geometry/algorithms/detail/disjoint/interface.hpp index ce7fe6d45..64898e35f 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/interface.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/interface.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2014 Mateusz Loskot, London, UK. // Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2013-2014. -// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013-2017. +// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -27,43 +27,51 @@ #include #include +#include +#include + #include -#include +#include namespace boost { namespace geometry { - -#ifndef DOXYGEN_NO_DISPATCH -namespace dispatch +namespace resolve_strategy { - -// If reversal is needed, perform it -template -< - typename Geometry1, typename Geometry2, - std::size_t DimensionCount, - typename Tag1, typename Tag2 -> -struct disjoint +struct disjoint { - static inline bool apply(Geometry1 const& g1, Geometry2 const& g2) + template + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) { - return disjoint + return dispatch::disjoint + < + Geometry1, Geometry2 + >::apply(geometry1, geometry2, strategy); + } + + template + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + default_strategy) + { + typedef typename strategy::disjoint::services::default_strategy < - Geometry2, Geometry1, - DimensionCount, - Tag2, Tag1 - >::apply(g2, g1); + Geometry1, Geometry2 + >::type strategy_type; + + return dispatch::disjoint + < + Geometry1, Geometry2 + >::apply(geometry1, geometry2, strategy_type()); } }; - -} // namespace dispatch -#endif // DOXYGEN_NO_DISPATCH +} // namespace resolve_strategy namespace resolve_variant { @@ -71,7 +79,8 @@ namespace resolve_variant { template struct disjoint { - static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2) + template + static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy) { concepts::check_concepts_and_equal_dimensions < @@ -79,88 +88,135 @@ struct disjoint Geometry2 const >(); - return dispatch::disjoint::apply(geometry1, geometry2); + return resolve_strategy::disjoint::apply(geometry1, geometry2, strategy); } }; template struct disjoint, Geometry2> { + template struct visitor: boost::static_visitor { Geometry2 const& m_geometry2; + Strategy const& m_strategy; - visitor(Geometry2 const& geometry2): m_geometry2(geometry2) {} + visitor(Geometry2 const& geometry2, Strategy const& strategy) + : m_geometry2(geometry2) + , m_strategy(strategy) + {} template bool operator()(Geometry1 const& geometry1) const { - return disjoint::apply(geometry1, m_geometry2); + return disjoint::apply(geometry1, m_geometry2, m_strategy); } }; - static inline bool - apply(boost::variant const& geometry1, - Geometry2 const& geometry2) + template + static inline bool apply(boost::variant const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) { - return boost::apply_visitor(visitor(geometry2), geometry1); + return boost::apply_visitor(visitor(geometry2, strategy), geometry1); } }; template struct disjoint > { + template struct visitor: boost::static_visitor { Geometry1 const& m_geometry1; + Strategy const& m_strategy; - visitor(Geometry1 const& geometry1): m_geometry1(geometry1) {} + visitor(Geometry1 const& geometry1, Strategy const& strategy) + : m_geometry1(geometry1) + , m_strategy(strategy) + {} template bool operator()(Geometry2 const& geometry2) const { - return disjoint::apply(m_geometry1, geometry2); + return disjoint::apply(m_geometry1, geometry2, m_strategy); } }; - static inline bool - apply(Geometry1 const& geometry1, - boost::variant const& geometry2) + template + static inline bool apply(Geometry1 const& geometry1, + boost::variant const& geometry2, + Strategy const& strategy) { - return boost::apply_visitor(visitor(geometry1), geometry2); + return boost::apply_visitor(visitor(geometry1, strategy), geometry2); } }; -template < +template +< BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2) > -struct disjoint< - boost::variant, - boost::variant -> +struct disjoint + < + boost::variant, + boost::variant + > { + template struct visitor: boost::static_visitor { + Strategy const& m_strategy; + + visitor(Strategy const& strategy) + : m_strategy(strategy) + {} + template bool operator()(Geometry1 const& geometry1, Geometry2 const& geometry2) const { - return disjoint::apply(geometry1, geometry2); + return disjoint::apply(geometry1, geometry2, m_strategy); } }; - static inline bool - apply(boost::variant const& geometry1, - boost::variant const& geometry2) + template + static inline bool apply(boost::variant const& geometry1, + boost::variant const& geometry2, + Strategy const& strategy) { - return boost::apply_visitor(visitor(), geometry1, geometry2); + return boost::apply_visitor(visitor(strategy), geometry1, geometry2); } }; } // namespace resolve_variant +/*! +\brief \brief_check2{are disjoint} +\ingroup disjoint +\tparam Geometry1 \tparam_geometry +\tparam Geometry2 \tparam_geometry +\tparam Strategy \tparam_strategy{Disjoint} +\param geometry1 \param_geometry +\param geometry2 \param_geometry +\param strategy \param_strategy{disjoint} +\return \return_check2{are disjoint} + +\qbk{distinguish,with strategy} +\qbk{[include reference/algorithms/disjoint.qbk]} +*/ +template +inline bool disjoint(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) +{ + return resolve_variant::disjoint + < + Geometry1, Geometry2 + >::apply(geometry1, geometry2, strategy); +} + /*! \brief \brief_check2{are disjoint} @@ -177,7 +233,10 @@ template inline bool disjoint(Geometry1 const& geometry1, Geometry2 const& geometry2) { - return resolve_variant::disjoint::apply(geometry1, geometry2); + return resolve_variant::disjoint + < + Geometry1, Geometry2 + >::apply(geometry1, geometry2, default_strategy()); } diff --git a/include/boost/geometry/algorithms/detail/disjoint/linear_areal.hpp b/include/boost/geometry/algorithms/detail/disjoint/linear_areal.hpp index 6a48b684a..e6077d3e7 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/linear_areal.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/linear_areal.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2014 Mateusz Loskot, London, UK. // Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2013-2015. -// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013-2017. +// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -61,19 +61,28 @@ template ::type> struct disjoint_no_intersections_policy { - static inline bool apply(Geometry1 const& g1, Geometry2 const& g2) + /*! + \tparam Strategy point_in_geometry strategy + */ + template + static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy) { typedef typename point_type::type point1_type; point1_type p; geometry::point_on_border(p, g1); - return !geometry::covered_by(p, g2); + + return !geometry::covered_by(p, g2, strategy); } }; template struct disjoint_no_intersections_policy { - static inline bool apply(Geometry1 const& g1, Geometry2 const& g2) + /*! + \tparam Strategy point_in_geometry strategy + */ + template + static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy) { // TODO: use partition or rtree on g2 typedef typename boost::range_iterator::type iterator; @@ -81,7 +90,7 @@ struct disjoint_no_intersections_policy { typedef typename boost::range_value::type value_type; if ( ! disjoint_no_intersections_policy - ::apply(*it, g2) ) + ::apply(*it, g2, strategy) ) { return false; } @@ -96,15 +105,21 @@ template > struct disjoint_linear_areal { - static inline bool apply(Geometry1 const& g1, Geometry2 const& g2) + /*! + \tparam Strategy relate (segments intersection) strategy + */ + template + static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy) { // if there are intersections - return false - if ( !disjoint_linear::apply(g1, g2) ) + if ( !disjoint_linear::apply(g1, g2, strategy) ) { return false; } - return NoIntersectionsPolicy::apply(g1, g2); + return NoIntersectionsPolicy + ::apply(g1, g2, + strategy.template get_point_in_geometry_strategy()); } }; @@ -126,16 +141,18 @@ template class disjoint_segment_areal { private: - template + template static inline bool check_interior_rings(InteriorRings const& interior_rings, - Segment const& segment) + Segment const& segment, + Strategy const& strategy) { typedef typename boost::range_value::type ring_type; typedef unary_disjoint_geometry_to_query_geometry < Segment, + Strategy, disjoint_range_segment_or_box < ring_type, closure::value, Segment @@ -147,24 +164,27 @@ private: unary_predicate_type >::apply(boost::begin(interior_rings), boost::end(interior_rings), - unary_predicate_type(segment)); + unary_predicate_type(segment, strategy)); } public: - static inline bool apply(Segment const& segment, Polygon const& polygon) + template + static inline bool apply(Segment const& segment, + Polygon const& polygon, + IntersectionStrategy const& strategy) { typedef typename geometry::ring_type::type ring; if ( !disjoint_range_segment_or_box < ring, closure::value, Segment - >::apply(geometry::exterior_ring(polygon), segment) ) + >::apply(geometry::exterior_ring(polygon), segment, strategy) ) { return false; } - if ( !check_interior_rings(geometry::interior_rings(polygon), segment) ) + if ( !check_interior_rings(geometry::interior_rings(polygon), segment, strategy) ) { return false; } @@ -172,7 +192,8 @@ public: typename point_type::type p; detail::assign_point_from_index<0>(segment, p); - return !geometry::covered_by(p, polygon); + return !geometry::covered_by(p, polygon, + strategy.template get_point_in_geometry_strategy()); } }; @@ -180,13 +201,14 @@ public: template struct disjoint_segment_areal { - static inline - bool apply(Segment const& segment, MultiPolygon const& multipolygon) + template + static inline bool apply(Segment const& segment, MultiPolygon const& multipolygon, + IntersectionStrategy const& strategy) { return multirange_constant_size_geometry < MultiPolygon, Segment - >::apply(multipolygon, segment); + >::apply(multipolygon, segment, strategy); } }; @@ -194,20 +216,24 @@ struct disjoint_segment_areal template struct disjoint_segment_areal { - static inline bool apply(Segment const& segment, Ring const& ring) + template + static inline bool apply(Segment const& segment, + Ring const& ring, + IntersectionStrategy const& strategy) { if ( !disjoint_range_segment_or_box < Ring, closure::value, Segment - >::apply(ring, segment) ) + >::apply(ring, segment, strategy) ) { return false; } typename point_type::type p; detail::assign_point_from_index<0>(segment, p); - - return !geometry::covered_by(p, ring); + + return !geometry::covered_by(p, ring, + strategy.template get_point_in_geometry_strategy()); } }; @@ -231,14 +257,15 @@ struct disjoint template struct disjoint -{ - static inline - bool apply(Areal const& areal, Linear const& linear) +{ + template + static inline bool apply(Areal const& areal, Linear const& linear, + Strategy const& strategy) { return detail::disjoint::disjoint_linear_areal < Linear, Areal - >::apply(linear, areal); + >::apply(linear, areal, strategy); } }; @@ -246,12 +273,14 @@ struct disjoint template struct disjoint { - static inline bool apply(Areal const& g1, Segment const& g2) + template + static inline bool apply(Areal const& g1, Segment const& g2, + Strategy const& strategy) { return detail::disjoint::disjoint_segment_areal < Segment, Areal - >::apply(g2, g1); + >::apply(g2, g1, strategy); } }; diff --git a/include/boost/geometry/algorithms/detail/disjoint/linear_linear.hpp b/include/boost/geometry/algorithms/detail/disjoint/linear_linear.hpp index 91f985edb..989b8df24 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/linear_linear.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/linear_linear.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2014 Mateusz Loskot, London, UK. // Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2013-2014. -// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013-2017. +// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -53,7 +53,9 @@ namespace detail { namespace disjoint template struct disjoint_segment { - static inline bool apply(Segment1 const& segment1, Segment2 const& segment2) + template + static inline bool apply(Segment1 const& segment1, Segment2 const& segment2, + Strategy const& strategy) { typedef typename point_type::type point_type; @@ -62,23 +64,23 @@ struct disjoint_segment rescale_policy_type robust_policy; typedef segment_intersection_points - < - point_type, - typename segment_ratio_type + < + point_type, + typename segment_ratio_type < point_type, rescale_policy_type >::type - > intersection_return_type; + > intersection_return_type; - intersection_return_type is - = strategy::intersection::relate_cartesian_segments + typedef policies::relate::segments_intersection_points < - policies::relate::segments_intersection_points - < - intersection_return_type - > - >::apply(segment1, segment2, robust_policy); + intersection_return_type + > intersection_policy; + + intersection_return_type is = strategy.apply(segment1, segment2, + intersection_policy(), + robust_policy); return is.count == 0; } @@ -109,8 +111,10 @@ struct assign_disjoint_policy template struct disjoint_linear { - static inline - bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2) + template + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) { typedef typename geometry::point_type::type point_type; typedef detail::no_rescale_policy rescale_policy_type; @@ -147,7 +151,7 @@ struct disjoint_linear Geometry1, Geometry2, assign_disjoint_policy > >::apply(0, geometry1, 1, geometry2, - rescale_policy_type(), turns, interrupt_policy); + strategy, rescale_policy_type(), turns, interrupt_policy); return !interrupt_policy.has_intersections; } diff --git a/include/boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp b/include/boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp index 8d82f7c91..b4c71c8f3 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp @@ -53,8 +53,10 @@ template > struct disjoint_range_segment_or_box { - static inline - bool apply(Range const& range, SegmentOrBox const& segment_or_box) + template + static inline bool apply(Range const& range, + SegmentOrBox const& segment_or_box, + Strategy const& strategy) { typedef typename closeable_view::type view_type; @@ -85,7 +87,8 @@ struct disjoint_range_segment_or_box < point_type, SegmentOrBox >::apply(geometry::range::front(view), - segment_or_box); + segment_or_box, + strategy.template get_point_in_geometry_strategy()); } else { @@ -99,7 +102,7 @@ struct disjoint_range_segment_or_box if ( !dispatch::disjoint < range_segment, SegmentOrBox - >::apply(rng_segment, segment_or_box) ) + >::apply(rng_segment, segment_or_box, strategy) ) { return false; } diff --git a/include/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp b/include/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp index 29e438e54..7c1a93cdb 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp @@ -1,8 +1,9 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2015, Oracle and/or its affiliates. +// Copyright (c) 2014-2017, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html @@ -14,8 +15,10 @@ #include #include +#include #include +#include #include #include @@ -105,36 +108,74 @@ template class multipoint_linear { private: - // structs for partition -- start - struct expand_box + struct expand_box_point { - template - static inline void apply(Box& total, Geometry const& geometry) + template + static inline void apply(Box& total, Point const& point) { - geometry::expand(total, geometry::return_envelope(geometry)); - } - - }; - - struct overlaps_box - { - template - static inline bool apply(Box const& box, Geometry const& geometry) - { - return ! dispatch::disjoint::apply(geometry, box); + geometry::expand(total, point); } }; + // TODO: After adding non-cartesian Segment envelope to the library + // this policy should be modified to take envelope strategy. + struct expand_box_segment + { + template + static inline void apply(Box& total, Segment const& segment) + { + geometry::expand(total, geometry::return_envelope(segment)); + } + }; + + struct overlaps_box_point + { + template + static inline bool apply(Box const& box, Point const& point) + { + // The default strategy is enough in this case + typedef typename strategy::disjoint::services::default_strategy + < + Point, Box + >::type strategy_type; + return ! dispatch::disjoint::apply(point, box, strategy_type()); + } + }; + + // TODO: After implementing disjoint Segment/Box for non-cartesian geometries + // this strategy should be passed here. + // TODO: This Segment/Box strategy should somehow be derived from Point/Segment strategy + // which by default is winding containing CS-specific side strategy + // TODO: disjoint Segment/Box will be called in this case which may take + // quite long in non-cartesian CS. So we should consider passing range of bounding boxes + // of segments after calculating them once. + struct overlaps_box_segment + { + template + static inline bool apply(Box const& box, Segment const& segment) + { + typedef typename strategy::disjoint::services::default_strategy + < + Segment, Box + >::type strategy_type; + return ! dispatch::disjoint::apply(segment, box, strategy_type()); + } + }; + + template class item_visitor_type { public: - item_visitor_type() : m_intersection_found(false) {} + item_visitor_type(PtSegStrategy const& strategy) + : m_intersection_found(false) + , m_strategy(strategy) + {} template inline void apply(Item1 const& item1, Item2 const& item2) { if (! m_intersection_found - && ! dispatch::disjoint::apply(item1, item2)) + && ! dispatch::disjoint::apply(item1, item2, m_strategy)) { m_intersection_found = true; } @@ -144,6 +185,7 @@ private: private: bool m_intersection_found; + PtSegStrategy const& m_strategy; }; // structs for partition -- end @@ -172,23 +214,25 @@ private: }; public: - static inline bool apply(MultiPoint const& multipoint, Linear const& linear) + template + static inline bool apply(MultiPoint const& multipoint, Linear const& linear, Strategy const& strategy) { - item_visitor_type visitor; + item_visitor_type visitor(strategy); geometry::partition < - geometry::model::box::type>, - expand_box, - overlaps_box - >::apply(multipoint, segment_range(linear), visitor); + geometry::model::box::type> + >::apply(multipoint, segment_range(linear), visitor, + expand_box_point(), overlaps_box_point(), + expand_box_segment(), overlaps_box_segment()); return ! visitor.intersection_found(); } - static inline bool apply(Linear const& linear, MultiPoint const& multipoint) + template + static inline bool apply(Linear const& linear, MultiPoint const& multipoint, Strategy const& strategy) { - return apply(multipoint, linear); + return apply(multipoint, linear, strategy); } }; @@ -240,8 +284,10 @@ struct disjoint multi_point_tag, multi_point_tag, false > { + template static inline bool apply(MultiPoint1 const& multipoint1, - MultiPoint2 const& multipoint2) + MultiPoint2 const& multipoint2, + Strategy const& ) { if ( boost::size(multipoint2) < boost::size(multipoint1) ) { diff --git a/include/boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp b/include/boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp index 78a683e46..53fb1642a 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp @@ -1,8 +1,9 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014, Oracle and/or its affiliates. +// Copyright (c) 2014-2017, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html @@ -25,34 +26,40 @@ namespace detail { namespace disjoint { -template +template class unary_disjoint_geometry_to_query_geometry { public: - unary_disjoint_geometry_to_query_geometry(Geometry const& geometry) + unary_disjoint_geometry_to_query_geometry(Geometry const& geometry, + Strategy const& strategy) : m_geometry(geometry) + , m_strategy(strategy) {} template inline bool apply(QueryGeometry const& query_geometry) const { - return BinaryPredicate::apply(query_geometry, m_geometry); + return BinaryPredicate::apply(query_geometry, m_geometry, m_strategy); } private: Geometry const& m_geometry; + Strategy const& m_strategy; }; template struct multirange_constant_size_geometry { + template static inline bool apply(MultiRange const& multirange, - ConstantSizeGeometry const& constant_size_geometry) + ConstantSizeGeometry const& constant_size_geometry, + Strategy const& strategy) { typedef unary_disjoint_geometry_to_query_geometry < ConstantSizeGeometry, + Strategy, dispatch::disjoint < typename boost::range_value::type, @@ -64,13 +71,15 @@ struct multirange_constant_size_geometry < unary_predicate_type >::apply(boost::begin(multirange), boost::end(multirange), - unary_predicate_type(constant_size_geometry)); + unary_predicate_type(constant_size_geometry, strategy)); } + template static inline bool apply(ConstantSizeGeometry const& constant_size_geometry, - MultiRange const& multirange) + MultiRange const& multirange, + Strategy const& strategy) { - return apply(multirange, constant_size_geometry); + return apply(multirange, constant_size_geometry, strategy); } }; diff --git a/include/boost/geometry/algorithms/detail/disjoint/point_box.hpp b/include/boost/geometry/algorithms/detail/disjoint/point_box.hpp index 2f1085ada..2e6773d22 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/point_box.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/point_box.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland -// This file was modified by Oracle on 2013-2016. -// Modifications copyright (c) 2013-2016, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013-2017. +// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -28,7 +28,7 @@ #include #include -#include +#include namespace boost { namespace geometry { @@ -44,13 +44,13 @@ namespace detail { namespace disjoint template inline bool disjoint_point_box(Point const& point, Box const& box) { + typedef typename strategy::disjoint::services::default_strategy + < + Point, Box + >::type strategy_type; + // ! covered_by(point, box) - return ! strategy::within::relate_point_box_loop - < - strategy::within::covered_by_range, - Point, Box, - 0, dimension::type::value - >::apply(point, box); + return ! strategy_type::apply(point, box); } @@ -66,15 +66,11 @@ namespace dispatch template struct disjoint { - static inline bool apply(Point const& point, Box const& box) + template + static inline bool apply(Point const& point, Box const& box, Strategy const& ) { // ! covered_by(point, box) - return ! strategy::within::relate_point_box_loop - < - strategy::within::covered_by_range, - Point, Box, - 0, DimensionCount - >::apply(point, box); + return ! Strategy::apply(point, box); } }; diff --git a/include/boost/geometry/algorithms/detail/disjoint/point_geometry.hpp b/include/boost/geometry/algorithms/detail/disjoint/point_geometry.hpp index 9ae43f73d..66bd7c26c 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/point_geometry.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/point_geometry.hpp @@ -39,11 +39,12 @@ namespace detail { namespace disjoint struct reverse_covered_by { - template - static inline - bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2) + template + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) { - return ! geometry::covered_by(geometry1, geometry2); + return ! geometry::covered_by(geometry1, geometry2, strategy); } }; diff --git a/include/boost/geometry/algorithms/detail/disjoint/point_point.hpp b/include/boost/geometry/algorithms/detail/disjoint/point_point.hpp index 7580b7287..13ac34d71 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/point_point.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/point_point.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland -// This file was modified by Oracle on 2013, 2014, 2015. -// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017. +// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -59,6 +59,12 @@ namespace detail { namespace disjoint template struct point_point_generic { + template + static inline bool apply(Point1 const& p1, Point2 const& p2, Strategy const& ) + { + return apply(p1, p2); + } + template static inline bool apply(Point1 const& p1, Point2 const& p2) { @@ -75,7 +81,7 @@ template struct point_point_generic { template - static inline bool apply(Point1 const&, Point2 const&) + static inline bool apply(Point1 const&, Point2 const& ) { return false; } @@ -135,6 +141,12 @@ private: }; public: + template + static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& ) + { + return apply(point1, point2); + } + template static inline bool apply(Point1 const& point1, Point2 const& point2) { diff --git a/include/boost/geometry/algorithms/detail/disjoint/segment_box.hpp b/include/boost/geometry/algorithms/detail/disjoint/segment_box.hpp index cc0c7949e..c2741ce72 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/segment_box.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/segment_box.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2014 Mateusz Loskot, London, UK. // Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2013-2014. -// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013-2017. +// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -22,19 +22,8 @@ #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_SEGMENT_BOX_HPP #include -#include -#include - -#include -#include - -#include #include -#include -#include - -#include #include @@ -47,236 +36,19 @@ namespace boost { namespace geometry namespace detail { namespace disjoint { - -template -struct compute_tmin_tmax_per_dim -{ - template - static inline void apply(SegmentPoint const& p0, - SegmentPoint const& p1, - Box const& box, - RelativeDistance& ti_min, - RelativeDistance& ti_max, - RelativeDistance& diff) - { - typedef typename coordinate_type::type box_coordinate_type; - typedef typename coordinate_type - < - SegmentPoint - >::type point_coordinate_type; - - RelativeDistance c_p0 = boost::numeric_cast - < - point_coordinate_type - >( geometry::get(p0) ); - - RelativeDistance c_p1 = boost::numeric_cast - < - point_coordinate_type - >( geometry::get(p1) ); - - RelativeDistance c_b_min = boost::numeric_cast - < - box_coordinate_type - >( geometry::get(box) ); - - RelativeDistance c_b_max = boost::numeric_cast - < - box_coordinate_type - >( geometry::get(box) ); - - if ( geometry::get(p1) >= geometry::get(p0) ) - { - diff = c_p1 - c_p0; - ti_min = c_b_min - c_p0; - ti_max = c_b_max - c_p0; - } - else - { - diff = c_p0 - c_p1; - ti_min = c_p0 - c_b_max; - ti_max = c_p0 - c_b_min; - } - } -}; - - -template -< - typename RelativeDistance, - typename SegmentPoint, - typename Box, - std::size_t I, - std::size_t Dimension -> -struct disjoint_segment_box_impl -{ - template - static inline bool apply(SegmentPoint const& p0, - SegmentPoint const& p1, - Box const& box, - RelativeDistancePair& t_min, - RelativeDistancePair& t_max) - { - RelativeDistance ti_min, ti_max, diff; - - compute_tmin_tmax_per_dim::apply(p0, p1, box, ti_min, ti_max, diff); - - if ( geometry::math::equals(diff, 0) ) - { - if ( (geometry::math::equals(t_min.second, 0) - && t_min.first > ti_max) - || - (geometry::math::equals(t_max.second, 0) - && t_max.first < ti_min) - || - (math::sign(ti_min) * math::sign(ti_max) > 0) ) - { - return true; - } - } - - RelativeDistance t_min_x_diff = t_min.first * diff; - RelativeDistance t_max_x_diff = t_max.first * diff; - - if ( t_min_x_diff > ti_max * t_min.second - || t_max_x_diff < ti_min * t_max.second ) - { - return true; - } - - if ( ti_min * t_min.second > t_min_x_diff ) - { - t_min.first = ti_min; - t_min.second = diff; - } - if ( ti_max * t_max.second < t_max_x_diff ) - { - t_max.first = ti_max; - t_max.second = diff; - } - - if ( t_min.first > t_min.second || t_max.first < 0 ) - { - return true; - } - - return disjoint_segment_box_impl - < - RelativeDistance, - SegmentPoint, - Box, - I + 1, - Dimension - >::apply(p0, p1, box, t_min, t_max); - } -}; - - -template -< - typename RelativeDistance, - typename SegmentPoint, - typename Box, - std::size_t Dimension -> -struct disjoint_segment_box_impl - < - RelativeDistance, SegmentPoint, Box, 0, Dimension - > -{ - static inline bool apply(SegmentPoint const& p0, - SegmentPoint const& p1, - Box const& box) - { - std::pair t_min, t_max; - RelativeDistance diff; - - compute_tmin_tmax_per_dim<0>::apply(p0, p1, box, - t_min.first, t_max.first, diff); - - if ( geometry::math::equals(diff, 0) ) - { - if ( geometry::math::equals(t_min.first, 0) ) { t_min.first = -1; } - if ( geometry::math::equals(t_max.first, 0) ) { t_max.first = 1; } - - if (math::sign(t_min.first) * math::sign(t_max.first) > 0) - { - return true; - } - } - - if ( t_min.first > diff || t_max.first < 0 ) - { - return true; - } - - t_min.second = t_max.second = diff; - - return disjoint_segment_box_impl - < - RelativeDistance, SegmentPoint, Box, 1, Dimension - >::apply(p0, p1, box, t_min, t_max); - } -}; - - -template -< - typename RelativeDistance, - typename SegmentPoint, - typename Box, - std::size_t Dimension -> -struct disjoint_segment_box_impl - < - RelativeDistance, SegmentPoint, Box, Dimension, Dimension - > -{ - template - static inline bool apply(SegmentPoint const&, SegmentPoint const&, - Box const&, - RelativeDistancePair&, RelativeDistancePair&) - { - return false; - } -}; - - -//========================================================================= - - -template struct disjoint_segment_box -{ - static inline bool apply(Segment const& segment, Box const& box) +{ + template + static inline bool apply(Segment const& segment, Box const& box, Strategy const& strategy) { - assert_dimension_equal(); - - typedef typename util::calculation_type::geometric::binary - < - Segment, Box, void - >::type relative_distance_type; - - typedef typename point_type::type segment_point_type; - segment_point_type p0, p1; - geometry::detail::assign_point_from_index<0>(segment, p0); - geometry::detail::assign_point_from_index<1>(segment, p1); - - return disjoint_segment_box_impl - < - relative_distance_type, segment_point_type, Box, - 0, dimension::value - >::apply(p0, p1, box); + return strategy.apply(segment, box); } }; - }} // namespace detail::disjoint #endif // DOXYGEN_NO_DETAIL - #ifndef DOXYGEN_NO_DISPATCH namespace dispatch { @@ -284,7 +56,7 @@ namespace dispatch template struct disjoint - : detail::disjoint::disjoint_segment_box + : detail::disjoint::disjoint_segment_box {}; diff --git a/include/boost/geometry/algorithms/detail/envelope/box.hpp b/include/boost/geometry/algorithms/detail/envelope/box.hpp index 379026294..795f51392 100644 --- a/include/boost/geometry/algorithms/detail/envelope/box.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/box.hpp @@ -4,9 +4,10 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2015. -// Modifications copyright (c) 2015, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2016. +// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Distributed under the Boost Software License, Version 1.0. @@ -97,8 +98,10 @@ struct envelope_indexed_box_on_spheroid struct envelope_box { - template - static inline void apply(BoxIn const& box_in, BoxOut& mbr) + template + static inline void apply(BoxIn const& box_in, + BoxOut& mbr, + Strategy const&) { envelope_indexed_box < @@ -115,8 +118,10 @@ struct envelope_box struct envelope_box_on_spheroid { - template - static inline void apply(BoxIn const& box_in, BoxOut& mbr) + template + static inline void apply(BoxIn const& box_in, + BoxOut& mbr, + Strategy const&) { BoxIn box_in_normalized = detail::return_normalized(box_in); diff --git a/include/boost/geometry/algorithms/detail/envelope/implementation.hpp b/include/boost/geometry/algorithms/detail/envelope/implementation.hpp index c1dbf8e58..d54970079 100644 --- a/include/boost/geometry/algorithms/detail/envelope/implementation.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/implementation.hpp @@ -4,9 +4,10 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2015. -// Modifications copyright (c) 2015, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2016. +// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -45,8 +46,8 @@ namespace detail { namespace envelope struct envelope_polygon { - template - static inline void apply(Polygon const& polygon, Box& mbr) + template + static inline void apply(Polygon const& polygon, Box& mbr, Strategy const& strategy) { typename ring_return_type::type ext_ring = exterior_ring(polygon); @@ -57,12 +58,12 @@ struct envelope_polygon envelope_multi_range < envelope_range - >::apply(interior_rings(polygon), mbr); + >::apply(interior_rings(polygon), mbr, strategy); } else { // otherwise, consider only the exterior ring - envelope_range::apply(ext_ring, mbr); + envelope_range::apply(ext_ring, mbr, strategy); } } }; diff --git a/include/boost/geometry/algorithms/detail/envelope/interface.hpp b/include/boost/geometry/algorithms/detail/envelope/interface.hpp index befe4e42d..8e9c35b39 100644 --- a/include/boost/geometry/algorithms/detail/envelope/interface.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/interface.hpp @@ -4,10 +4,12 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2015. -// Modifications copyright (c) 2015, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2016, 2017. +// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -27,54 +29,124 @@ #include +#include +#include +#include +#include +#include namespace boost { namespace geometry { +namespace resolve_strategy +{ + +template +struct envelope +{ + template + static inline void apply(Geometry const& geometry, + Box& box, + Strategy const& strategy) + { + dispatch::envelope::apply(geometry, box, strategy); + } + + template + static inline void apply(Geometry const& geometry, + Box& box, + default_strategy) + { + typedef typename point_type::type point_type; + typedef typename coordinate_type::type coordinate_type; + + typedef typename strategy::envelope::services::default_strategy + < + typename cs_tag::type, + coordinate_type + >::type strategy_type; + + dispatch::envelope::apply(geometry, box, strategy_type()); + } +}; + +} // namespace resolve_strategy + namespace resolve_variant { template struct envelope { - template - static inline void apply(Geometry const& geometry, Box& box) + template + static inline void apply(Geometry const& geometry, + Box& box, + Strategy const& strategy) { concepts::check(); concepts::check(); - dispatch::envelope::apply(geometry, box); + resolve_strategy::envelope::apply(geometry, box, strategy); } }; + template struct envelope > { - template + template struct visitor: boost::static_visitor { Box& m_box; + Strategy const& m_strategy; - visitor(Box& box): m_box(box) {} + visitor(Box& box, Strategy const& strategy) + : m_box(box) + , m_strategy(strategy) + {} template void operator()(Geometry const& geometry) const { - envelope::apply(geometry, m_box); + envelope::apply(geometry, m_box, m_strategy); } }; - template + template static inline void apply(boost::variant const& geometry, - Box& box) + Box& box, + Strategy const& strategy) { - boost::apply_visitor(visitor(box), geometry); + boost::apply_visitor(visitor(box, strategy), geometry); } }; } // namespace resolve_variant +/*! +\brief \brief_calc{envelope (with strategy)} +\ingroup envelope +\details \details_calc{envelope,\det_envelope}. +\tparam Geometry \tparam_geometry +\tparam Box \tparam_box +\tparam Strategy \tparam_strategy{Envelope} +\param geometry \param_geometry +\param mbr \param_box \param_set{envelope} +\param strategy \param_strategy{envelope} + +\qbk{distinguish,with strategy} +\qbk{[include reference/algorithms/envelope.qbk]} +\qbk{ +[heading Example] +[envelope] [envelope_output] +} +*/ +template +inline void envelope(Geometry const& geometry, Box& mbr, Strategy const& strategy) +{ + resolve_variant::envelope::apply(geometry, mbr, strategy); +} /*! \brief \brief_calc{envelope} @@ -94,10 +166,36 @@ struct envelope > template inline void envelope(Geometry const& geometry, Box& mbr) { - resolve_variant::envelope::apply(geometry, mbr); + resolve_variant::envelope::apply(geometry, mbr, default_strategy()); } +/*! +\brief \brief_calc{envelope} +\ingroup envelope +\details \details_calc{return_envelope,\det_envelope}. \details_return{envelope} +\tparam Box \tparam_box +\tparam Geometry \tparam_geometry +\tparam Strategy \tparam_strategy{Envelope} +\param geometry \param_geometry +\param strategy \param_strategy{envelope} +\return \return_calc{envelope} + +\qbk{distinguish,with strategy} +\qbk{[include reference/algorithms/envelope.qbk]} +\qbk{ +[heading Example] +[return_envelope] [return_envelope_output] +} +*/ +template +inline Box return_envelope(Geometry const& geometry, Strategy const& strategy) +{ + Box mbr; + resolve_variant::envelope::apply(geometry, mbr, strategy); + return mbr; +} + /*! \brief \brief_calc{envelope} \ingroup envelope @@ -117,7 +215,7 @@ template inline Box return_envelope(Geometry const& geometry) { Box mbr; - resolve_variant::envelope::apply(geometry, mbr); + resolve_variant::envelope::apply(geometry, mbr, default_strategy()); return mbr; } diff --git a/include/boost/geometry/algorithms/detail/envelope/linear.hpp b/include/boost/geometry/algorithms/detail/envelope/linear.hpp index 49c3cf313..09d8a76da 100644 --- a/include/boost/geometry/algorithms/detail/envelope/linear.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/linear.hpp @@ -4,9 +4,10 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2015. -// Modifications copyright (c) 2015, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2016. +// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Distributed under the Boost Software License, Version 1.0. @@ -36,12 +37,15 @@ namespace detail { namespace envelope struct envelope_linestring_on_spheroid { - template - static inline void apply(Linestring const& linestring, Box& mbr) + template + static inline void apply(Linestring const& linestring, + Box& mbr, + Strategy const& strategy) { envelope_range::apply(geometry::segments_begin(linestring), geometry::segments_end(linestring), - mbr); + mbr, + strategy); } }; @@ -65,6 +69,11 @@ struct envelope : detail::envelope::envelope_linestring_on_spheroid {}; +template +struct envelope + : detail::envelope::envelope_linestring_on_spheroid +{}; + template struct envelope @@ -86,6 +95,15 @@ struct envelope > {}; +template +struct envelope + < + MultiLinestring, multi_linestring_tag, geographic_tag + > : detail::envelope::envelope_multi_range_on_spheroid + < + detail::envelope::envelope_linestring_on_spheroid + > +{}; } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH diff --git a/include/boost/geometry/algorithms/detail/envelope/multipoint.hpp b/include/boost/geometry/algorithms/detail/envelope/multipoint.hpp index 210debfdb..efee4701c 100644 --- a/include/boost/geometry/algorithms/detail/envelope/multipoint.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/multipoint.hpp @@ -1,7 +1,8 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2015, Oracle and/or its affiliates. +// Copyright (c) 2015-2016, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Distributed under the Boost Software License, Version 1.0. @@ -226,8 +227,8 @@ private: } public: - template - static inline void apply(MultiPoint const& multipoint, Box& mbr) + template + static inline void apply(MultiPoint const& multipoint, Box& mbr, Strategy const& strategy) { typedef typename point_type::type point_type; typedef typename coordinate_type::type coordinate_type; @@ -255,7 +256,7 @@ public: return dispatch::envelope < typename boost::range_value::type - >::apply(range::front(multipoint), mbr); + >::apply(range::front(multipoint), mbr, strategy); } // analyze the points and put the non-pole ones in the @@ -329,7 +330,7 @@ public: // compute envelope for higher coordinates iterator_type it = boost::begin(multipoint); - envelope_one_point<2, dimension::value>::apply(*it, mbr); + envelope_one_point<2, dimension::value>::apply(*it, mbr, strategy); for (++it; it != boost::end(multipoint); ++it) { @@ -338,7 +339,7 @@ public: strategy::compare::default_strategy, strategy::compare::default_strategy, 2, dimension::value - >::apply(mbr, *it); + >::apply(mbr, *it, strategy); } } }; diff --git a/include/boost/geometry/algorithms/detail/envelope/point.hpp b/include/boost/geometry/algorithms/detail/envelope/point.hpp index e914e7e8a..ee0559bf5 100644 --- a/include/boost/geometry/algorithms/detail/envelope/point.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/point.hpp @@ -4,9 +4,10 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2015. -// Modifications copyright (c) 2015, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2016. +// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Distributed under the Boost Software License, Version 1.0. @@ -58,8 +59,8 @@ struct envelope_one_point >::apply(point, box_corner); } - template - static inline void apply(Point const& point, Box& mbr) + template + static inline void apply(Point const& point, Box& mbr, Strategy const&) { apply(point, mbr); apply(point, mbr); @@ -69,8 +70,8 @@ struct envelope_one_point struct envelope_point_on_spheroid { - template - static inline void apply(Point const& point, Box& mbr) + template + static inline void apply(Point const& point, Box& mbr, Strategy const& strategy) { Point normalized_point = detail::return_normalized(point); @@ -88,7 +89,7 @@ struct envelope_point_on_spheroid envelope_one_point < 2, dimension::value - >::apply(normalized_point, mbr); + >::apply(normalized_point, mbr, strategy); } }; diff --git a/include/boost/geometry/algorithms/detail/envelope/range.hpp b/include/boost/geometry/algorithms/detail/envelope/range.hpp index 63b518114..b5591f61a 100644 --- a/include/boost/geometry/algorithms/detail/envelope/range.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/range.hpp @@ -4,9 +4,10 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2015. -// Modifications copyright (c) 2015, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2016. +// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -51,8 +52,11 @@ namespace detail { namespace envelope // implementation for simple ranges struct envelope_range { - template - static inline void apply(Iterator first, Iterator last, Box& mbr) + template + static inline void apply(Iterator first, + Iterator last, + Box& mbr, + Strategy const& strategy) { typedef typename std::iterator_traits::value_type value_type; @@ -63,20 +67,20 @@ struct envelope_range if (it != last) { // initialize box with first element in range - dispatch::envelope::apply(*it, mbr); + dispatch::envelope::apply(*it, mbr, strategy); // consider now the remaining elements in the range (if any) for (++it; it != last; ++it) { - dispatch::expand::apply(mbr, *it); + dispatch::expand::apply(mbr, *it, strategy); } } } - template - static inline void apply(Range const& range, Box& mbr) + template + static inline void apply(Range const& range, Box& mbr, Strategy const& strategy) { - return apply(boost::begin(range), boost::end(range), mbr); + return apply(boost::begin(range), boost::end(range), mbr, strategy); } }; @@ -85,8 +89,10 @@ struct envelope_range template struct envelope_multi_range { - template - static inline void apply(MultiRange const& multirange, Box& mbr) + template + static inline void apply(MultiRange const& multirange, + Box& mbr, + Strategy const& strategy) { typedef typename boost::range_iterator < @@ -103,14 +109,14 @@ struct envelope_multi_range if (initialized) { Box helper_mbr; - EnvelopePolicy::apply(*it, helper_mbr); + EnvelopePolicy::apply(*it, helper_mbr, strategy); - dispatch::expand::apply(mbr, helper_mbr); + dispatch::expand::apply(mbr, helper_mbr, strategy); } else { // compute the initial envelope - EnvelopePolicy::apply(*it, mbr); + EnvelopePolicy::apply(*it, mbr, strategy); initialized = true; } } @@ -129,8 +135,10 @@ struct envelope_multi_range template struct envelope_multi_range_on_spheroid { - template - static inline void apply(MultiRange const& multirange, Box& mbr) + template + static inline void apply(MultiRange const& multirange, + Box& mbr, + Strategy const& strategy) { typedef typename boost::range_iterator < @@ -147,7 +155,7 @@ struct envelope_multi_range_on_spheroid if (! geometry::is_empty(*it)) { Box helper_box; - EnvelopePolicy::apply(*it, helper_box); + EnvelopePolicy::apply(*it, helper_box, strategy); boxes.push_back(helper_box); } } @@ -159,7 +167,7 @@ struct envelope_multi_range_on_spheroid // and the MBR is simply initialized if (! boxes.empty()) { - envelope_range_of_boxes::apply(boxes, mbr); + envelope_range_of_boxes::apply(boxes, mbr, strategy); } else { diff --git a/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp b/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp index 64bdb9b9c..f61fc422d 100644 --- a/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp @@ -1,7 +1,8 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2015, Oracle and/or its affiliates. +// Copyright (c) 2015-2016, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Distributed under the Boost Software License, Version 1.0. @@ -149,8 +150,10 @@ struct envelope_range_of_longitudes template struct envelope_range_of_boxes_by_expansion { - template - static inline void apply(RangeOfBoxes const& range_of_boxes, Box& mbr) + template + static inline void apply(RangeOfBoxes const& range_of_boxes, + Box& mbr, + Strategy const& strategy) { typedef typename boost::range_value::type box_type; @@ -196,7 +199,7 @@ struct envelope_range_of_boxes_by_expansion min_corner, Dimension, DimensionCount - >::apply(mbr, *it); + >::apply(mbr, *it, strategy); detail::expand::indexed_loop < @@ -205,7 +208,7 @@ struct envelope_range_of_boxes_by_expansion max_corner, Dimension, DimensionCount - >::apply(mbr, *it); + >::apply(mbr, *it, strategy); } } @@ -225,8 +228,10 @@ struct envelope_range_of_boxes } }; - template - static inline void apply(RangeOfBoxes const& range_of_boxes, Box& mbr) + template + static inline void apply(RangeOfBoxes const& range_of_boxes, + Box& mbr, + Strategy const& strategy) { // boxes in the range are assumed to be normalized already @@ -313,7 +318,7 @@ struct envelope_range_of_boxes envelope_range_of_boxes_by_expansion < 2, dimension::value - >::apply(range_of_boxes, mbr); + >::apply(range_of_boxes, mbr, strategy); } }; diff --git a/include/boost/geometry/algorithms/detail/envelope/segment.hpp b/include/boost/geometry/algorithms/detail/envelope/segment.hpp index 6186e72a3..7631e8488 100644 --- a/include/boost/geometry/algorithms/detail/envelope/segment.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/segment.hpp @@ -4,9 +4,10 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2015, 2016. -// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015-2017. +// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -26,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -34,10 +36,9 @@ #include -#include +#include #include -#include #include #include @@ -46,7 +47,6 @@ #include - namespace boost { namespace geometry { @@ -54,63 +54,36 @@ namespace boost { namespace geometry namespace detail { namespace envelope { - -template -struct envelope_one_segment +template +struct envelope_segment_call_vertex_latitude { - template - static inline void apply(Point const& p1, Point const& p2, Box& mbr) + template + static inline CalculationType apply(T1 const& lat1, + T2 const& alp1, + Strategy const& ) { - envelope_one_point::apply(p1, mbr); - detail::expand::point_loop - < - strategy::compare::default_strategy, - strategy::compare::default_strategy, - Dimension, - DimensionCount - >::apply(mbr, p2); + return geometry::formula::vertex_latitude + ::apply(lat1, alp1); } }; +template +struct envelope_segment_call_vertex_latitude +{ + template + static inline CalculationType apply(T1 const& lat1, + T2 const& alp1, + Strategy const& strategy) + { + return geometry::formula::vertex_latitude + ::apply(lat1, alp1, strategy.model()); + } +}; -// Computes the MBR of a segment given by (lon1, lat1) and (lon2, -// lat2), and with azimuths a1 and a2 at the two endpoints of the -// segment. -// It is assumed that the spherical coordinates of the segment are -// normalized and in radians. -// The longitudes and latitudes of the endpoints are overridden by -// those of the box. -class compute_mbr_of_segment +template +class envelope_segment_impl { private: - // computes the azimuths of the segment with endpoints (lon1, lat1) - // and (lon2, lat2) - // radians - template - static inline void azimuths(CalculationType const& lon1, - CalculationType const& lat1, - CalculationType const& lon2, - CalculationType const& lat2, - CalculationType& a1, - CalculationType& a2) - { - BOOST_GEOMETRY_ASSERT(lon1 <= lon2); - - CalculationType dlon = lon2 - lon1; - CalculationType sin_dlon = sin(dlon); - CalculationType cos_dlon = cos(dlon); - CalculationType cos_lat1 = cos(lat1); - CalculationType cos_lat2 = cos(lat2); - CalculationType sin_lat1 = sin(lat1); - CalculationType sin_lat2 = sin(lat2); - - a1 = atan2(sin_dlon * cos_lat2, - cos_lat1 * sin_lat2 - sin_lat1 * cos_lat2 * cos_dlon); - - a2 = atan2(-sin_dlon * cos_lat1, - cos_lat2 * sin_lat1 - sin_lat2 * cos_lat1 * cos_dlon); - a2 += math::pi(); - } // degrees or radians template @@ -134,8 +107,8 @@ private: static CalculationType const pi_half = math::half_pi(); return (a1 < a2) - ? (a1 < pi_half && pi_half < a2) - : (a1 > pi_half && pi_half > a2); + ? (a1 < pi_half && pi_half < a2) + : (a1 > pi_half && pi_half > a2); } // radians or degrees @@ -151,21 +124,13 @@ private: return math::abs(lon1 - lon2) > constants::half_period(); // > pi } - // radians - template - static inline CalculationType max_latitude(CalculationType const& azimuth, - CalculationType const& latitude) - { - // azimuth and latitude are assumed to be in radians - return acos( math::abs(cos(latitude) * sin(azimuth)) ); - } - // degrees or radians - template + template static inline void compute_box_corners(CalculationType& lon1, CalculationType& lat1, CalculationType& lon2, - CalculationType& lat2) + CalculationType& lat2, + Strategy const& strategy) { // coordinates are assumed to be in radians BOOST_GEOMETRY_ASSERT(lon1 <= lon2); @@ -175,13 +140,14 @@ private: CalculationType lon2_rad = math::as_radian(lon2); CalculationType lat2_rad = math::as_radian(lat2); - CalculationType a1 = 0, a2 = 0; - azimuths(lon1_rad, lat1_rad, lon2_rad, lat2_rad, a1, a2); + CalculationType a1, a2; + strategy.apply(lon1_rad, lat1_rad, lon2_rad, lat2_rad, a1, a2); if (lat1 > lat2) { std::swap(lat1, lat2); std::swap(lat1_rad, lat2_rad); + std::swap(a1, a2); } if (math::equals(a1, a2)) @@ -192,12 +158,16 @@ private: if (contains_pi_half(a1, a2)) { + CalculationType p_max = envelope_segment_call_vertex_latitude + ::apply(lat1_rad, a1, strategy); + CalculationType const mid_lat = lat1 + lat2; if (mid_lat < 0) { // update using min latitude - CalculationType const lat_min_rad = -max_latitude(a1, lat1_rad); - CalculationType const lat_min = math::from_radian(lat_min_rad); + CalculationType const lat_min_rad = -p_max; + CalculationType const lat_min + = math::from_radian(lat_min_rad); if (lat1 > lat_min) { @@ -207,8 +177,9 @@ private: else if (mid_lat > 0) { // update using max latitude - CalculationType const lat_max_rad = max_latitude(a1, lat1_rad); - CalculationType const lat_max = math::from_radian(lat_max_rad); + CalculationType const lat_max_rad = p_max; + CalculationType const lat_max + = math::from_radian(lat_max_rad); if (lat2 < lat_max) { @@ -218,11 +189,12 @@ private: } } - template + template static inline void apply(CalculationType& lon1, CalculationType& lat1, CalculationType& lon2, - CalculationType& lat2) + CalculationType& lat2, + Strategy const& strategy) { typedef math::detail::constants_on_spheroid < @@ -278,16 +250,22 @@ private: swap(lon1, lat1, lon2, lat2); } - compute_box_corners(lon1, lat1, lon2, lat2); + compute_box_corners(lon1, lat1, lon2, lat2, strategy); } public: - template + template < + typename Units, + typename CalculationType, + typename Box, + typename Strategy + > static inline void apply(CalculationType lon1, CalculationType lat1, CalculationType lon2, CalculationType lat2, - Box& mbr) + Box& mbr, + Strategy const& strategy) { typedef typename coordinate_type::type box_coordinate_type; @@ -298,7 +276,7 @@ public: helper_box_type radian_mbr; - apply(lon1, lat1, lon2, lat2); + apply(lon1, lat1, lon2, lat2, strategy); geometry::set < @@ -324,29 +302,42 @@ public: } }; +template +struct envelope_one_segment +{ + template + static inline void apply(Point const& p1, + Point const& p2, + Box& mbr, + Strategy const& strategy) + { + envelope_one_point::apply(p1, mbr, strategy); + detail::expand::point_loop + < + strategy::compare::default_strategy, + strategy::compare::default_strategy, + Dimension, + DimensionCount + >::apply(mbr, p2, strategy); + } +}; + template -struct envelope_segment_on_sphere +struct envelope_segment { - template - static inline void apply(Point const& p1, Point const& p2, Box& mbr) + template + static inline void apply(Point const& p1, + Point const& p2, + Box& mbr, + Strategy const& strategy) { // first compute the envelope range for the first two coordinates - Point p1_normalized = detail::return_normalized(p1); - Point p2_normalized = detail::return_normalized(p2); - - typedef typename coordinate_system::type::units units_type; - - compute_mbr_of_segment::template apply( - geometry::get<0>(p1_normalized), - geometry::get<1>(p1_normalized), - geometry::get<0>(p2_normalized), - geometry::get<1>(p2_normalized), - mbr); + strategy.apply(p1, p2, mbr); // now compute the envelope range for coordinates of // dimension 2 and higher - envelope_one_segment<2, DimensionCount>::apply(p1, p2, mbr); + envelope_one_segment<2, DimensionCount>::apply(p1, p2, mbr, strategy); } template @@ -359,21 +350,6 @@ struct envelope_segment_on_sphere } }; - - -template -struct envelope_segment - : envelope_one_segment<0, DimensionCount> -{}; - - -template -struct envelope_segment - : envelope_segment_on_sphere -{}; - - - }} // namespace detail::envelope #endif // DOXYGEN_NO_DETAIL @@ -383,23 +359,24 @@ namespace dispatch { -template -struct envelope +template +struct envelope { - template - static inline void apply(Segment const& segment, Box& mbr) + template + static inline void apply(Segment const& segment, + Box& mbr, + Strategy const& strategy) { typename point_type::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::value, CS_Tag - >::apply(p[0], p[1], mbr); + dimension::value + >::apply(p[0], p[1], mbr, strategy); } }; - } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH diff --git a/include/boost/geometry/algorithms/detail/equals/collect_vectors.hpp b/include/boost/geometry/algorithms/detail/equals/collect_vectors.hpp index eab73ea68..e62b93914 100644 --- a/include/boost/geometry/algorithms/detail/equals/collect_vectors.hpp +++ b/include/boost/geometry/algorithms/detail/equals/collect_vectors.hpp @@ -5,6 +5,11 @@ // Copyright (c) 2009-2014 Mateusz Loskot, London, UK. // Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland. +// This file was modified by Oracle on 2017. +// Modifications copyright (c) 2017 Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -20,6 +25,7 @@ #include #include +#include #include #include @@ -32,21 +38,35 @@ #include #include +#include +#include + namespace boost { namespace geometry { +// TODO: dispatch only by SideStrategy instead of Geometry/CSTag? + // Since these vectors (though ray would be a better name) are used in the // implementation of equals() for Areal geometries the internal representation -// should be consistent with the default side strategy for CS because currently -// it's used in other relops. - -template < +// should be consistent with the side strategy. +template +< typename T, typename Geometry, + typename SideStrategy, typename CSTag = typename cs_tag::type > struct collected_vector + : nyi::not_implemented_tag +{}; + +// compatible with side_by_triangle cartesian strategy +template +struct collected_vector + < + T, Geometry, strategy::side::side_by_triangle, CSTag + > { typedef T type; @@ -136,8 +156,13 @@ private: //T dx_0, dy_0; }; -template -struct collected_vector +// Compatible with spherical_side_formula which currently +// is the default spherical and geographical strategy +template +struct collected_vector + < + T, Geometry, strategy::side::spherical_side_formula, CSTag + > { typedef T type; @@ -232,11 +257,27 @@ private: vector_type next; // used for collinearity check }; -template -struct collected_vector - : public collected_vector +// Specialization for spherical polar +template +struct collected_vector + < + T, Geometry, + strategy::side::spherical_side_formula, + spherical_polar_tag + > + : public collected_vector + < + T, Geometry, + strategy::side::spherical_side_formula, + spherical_equatorial_tag + > { - typedef collected_vector base_type; + typedef collected_vector + < + T, Geometry, + strategy::side::spherical_side_formula, + spherical_equatorial_tag + > base_type; collected_vector() {} @@ -265,24 +306,6 @@ private: } }; -// This is consistent with the currently used default geographic side -// and intersection strategies. Spherical strategies are used by default. -// When default strategies are changed in the future this specialization -// should be changed too. -template -struct collected_vector - : public collected_vector -{ - typedef collected_vector base_type; - - collected_vector() {} - - template - collected_vector(Point const& p1, Point const& p2) - : base_type(p1, p2) - {} -}; - #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace collect_vectors diff --git a/include/boost/geometry/algorithms/detail/expand/box.hpp b/include/boost/geometry/algorithms/detail/expand/box.hpp index 4c89e6f1d..3edb23f5a 100644 --- a/include/boost/geometry/algorithms/detail/expand/box.hpp +++ b/include/boost/geometry/algorithms/detail/expand/box.hpp @@ -5,9 +5,10 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France. -// This file was modified by Oracle on 2015. -// Modifications copyright (c) 2015, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2016. +// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Distributed under the Boost Software License, Version 1.0. @@ -44,16 +45,18 @@ namespace detail { namespace expand struct box_on_spheroid { - template - static inline void apply(BoxOut& box_out, BoxIn const& box_in) + template + static inline void apply(BoxOut& box_out, + BoxIn const& box_in, + Strategy const& strategy) { // normalize both boxes and convert box-in to be of type of box-out BoxOut mbrs[2]; - detail::envelope::envelope_box_on_spheroid::apply(box_in, mbrs[0]); - detail::envelope::envelope_box_on_spheroid::apply(box_out, mbrs[1]); + detail::envelope::envelope_box_on_spheroid::apply(box_in, mbrs[0], strategy); + detail::envelope::envelope_box_on_spheroid::apply(box_out, mbrs[1], strategy); // compute the envelope of the two boxes - detail::envelope::envelope_range_of_boxes::apply(mbrs, box_out); + detail::envelope::envelope_range_of_boxes::apply(mbrs, box_out, strategy); } }; diff --git a/include/boost/geometry/algorithms/detail/expand/indexed.hpp b/include/boost/geometry/algorithms/detail/expand/indexed.hpp index bdd6eb450..28cf0e2e4 100644 --- a/include/boost/geometry/algorithms/detail/expand/indexed.hpp +++ b/include/boost/geometry/algorithms/detail/expand/indexed.hpp @@ -5,9 +5,10 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France. -// This file was modified by Oracle on 2015. -// Modifications copyright (c) 2015, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2016. +// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -49,8 +50,8 @@ template > struct indexed_loop { - template - static inline void apply(Box& box, Geometry const& source) + template + static inline void apply(Box& box, Geometry const& source, Strategy const& strategy) { typedef typename strategy::compare::detail::select_strategy < @@ -87,7 +88,7 @@ struct indexed_loop < StrategyLess, StrategyGreater, Index, Dimension + 1, DimensionCount - >::apply(box, source); + >::apply(box, source, strategy); } }; @@ -103,8 +104,8 @@ struct indexed_loop Index, DimensionCount, DimensionCount > { - template - static inline void apply(Box&, Geometry const&) {} + template + static inline void apply(Box&, Geometry const&, Strategy const&) {} }; @@ -117,20 +118,22 @@ template > struct expand_indexed { - template - static inline void apply(Box& box, Geometry const& geometry) + template + static inline void apply(Box& box, + Geometry const& geometry, + Strategy const& strategy) { indexed_loop < StrategyLess, StrategyGreater, 0, Dimension, DimensionCount - >::apply(box, geometry); + >::apply(box, geometry, strategy); indexed_loop < StrategyLess, StrategyGreater, 1, Dimension, DimensionCount - >::apply(box, geometry); + >::apply(box, geometry, strategy); } }; diff --git a/include/boost/geometry/algorithms/detail/expand/interface.hpp b/include/boost/geometry/algorithms/detail/expand/interface.hpp index 140754af4..5aacd8e72 100644 --- a/include/boost/geometry/algorithms/detail/expand/interface.hpp +++ b/include/boost/geometry/algorithms/detail/expand/interface.hpp @@ -5,9 +5,10 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France. -// This file was modified by Oracle on 2015. -// Modifications copyright (c) 2015, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2016. +// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -28,10 +29,50 @@ #include +#include + +#include +#include +#include +#include namespace boost { namespace geometry { +namespace resolve_strategy +{ + +template +struct expand +{ + template + static inline void apply(Box& box, + Geometry const& geometry, + Strategy const& strategy) + { + dispatch::expand::apply(box, geometry, strategy); + } + + template + static inline void apply(Box& box, + Geometry const& geometry, + default_strategy) + { + typedef typename point_type::type point_type; + typedef typename coordinate_type::type coordinate_type; + + typedef typename strategy::envelope::services::default_strategy + < + typename cs_tag::type, + coordinate_type + >::type strategy_type; + + dispatch::expand::apply(box, geometry, strategy_type()); + } +}; + +} //namespace resolve_strategy + namespace resolve_variant { @@ -39,40 +80,48 @@ namespace resolve_variant template struct expand { - template - static inline void apply(Box& box, Geometry const& geometry) + template + static inline void apply(Box& box, + Geometry const& geometry, + Strategy const& strategy) { concepts::check(); concepts::check(); concepts::check_concepts_and_equal_dimensions(); - dispatch::expand::apply(box, geometry); + resolve_strategy::expand::apply(box, geometry, strategy); } }; template struct expand > { - template + template struct visitor: boost::static_visitor { Box& m_box; + Strategy const& m_strategy; - visitor(Box& box) : m_box(box) {} + visitor(Box& box, Strategy const& strategy) + : m_box(box) + , m_strategy(strategy) + {} template void operator()(Geometry const& geometry) const { - return expand::apply(m_box, geometry); + return expand::apply(m_box, geometry, m_strategy); } }; - template + template static inline void apply(Box& box, - boost::variant const& geometry) + boost::variant const& geometry, + Strategy const& strategy) { - return boost::apply_visitor(visitor(box), geometry); + return boost::apply_visitor(visitor(box, strategy), + geometry); } }; @@ -106,21 +155,43 @@ inline void expand(Box& box, Geometry const& geometry, } ***/ +/*! +\brief Expands (with strategy) +\ingroup expand +\tparam Box type of the box +\tparam Geometry \tparam_geometry +\tparam Strategy \tparam_strategy{expand} +\param box box to be expanded using another geometry, mutable +\param geometry \param_geometry geometry which envelope (bounding box) +\param strategy \param_strategy{expand} +will be added to the box + +\qbk{distinguish,with strategy} +\qbk{[include reference/algorithms/expand.qbk]} + */ +template +inline void expand(Box& box, Geometry const& geometry, Strategy const& strategy) +{ + + resolve_variant::expand::apply(box, geometry, strategy); +} /*! -\brief Expands a box using the bounding box (envelope) of another geometry (box, point) +\brief Expands a box using the bounding box (envelope) of another geometry +(box, point) \ingroup expand \tparam Box type of the box \tparam Geometry \tparam_geometry \param box box to be expanded using another geometry, mutable -\param geometry \param_geometry geometry which envelope (bounding box) will be added to the box +\param geometry \param_geometry geometry which envelope (bounding box) will be +added to the box \qbk{[include reference/algorithms/expand.qbk]} */ template inline void expand(Box& box, Geometry const& geometry) { - resolve_variant::expand::apply(box, geometry); + resolve_variant::expand::apply(box, geometry, default_strategy()); } }} // namespace boost::geometry diff --git a/include/boost/geometry/algorithms/detail/expand/point.hpp b/include/boost/geometry/algorithms/detail/expand/point.hpp index 56b7f1c73..f0cbd1db0 100644 --- a/include/boost/geometry/algorithms/detail/expand/point.hpp +++ b/include/boost/geometry/algorithms/detail/expand/point.hpp @@ -5,9 +5,10 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France. -// This file was modified by Oracle on 2015. -// Modifications copyright (c) 2015, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2016. +// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -59,8 +60,8 @@ template > struct point_loop { - template - static inline void apply(Box& box, Point const& source) + template + static inline void apply(Box& box, Point const& source, Strategy const& strategy) { typedef typename strategy::compare::detail::select_strategy < @@ -95,22 +96,24 @@ struct point_loop point_loop < StrategyLess, StrategyGreater, Dimension + 1, DimensionCount - >::apply(box, source); + >::apply(box, source, strategy); } }; template < - typename StrategyLess, typename StrategyGreater, std::size_t DimensionCount + typename StrategyLess, + typename StrategyGreater, + std::size_t DimensionCount > struct point_loop < StrategyLess, StrategyGreater, DimensionCount, DimensionCount > { - template - static inline void apply(Box&, Point const&) {} + template + static inline void apply(Box&, Point const&, Strategy const&) {} }; @@ -123,8 +126,10 @@ template > struct point_loop_on_spheroid { - template - static inline void apply(Box& box, Point const& point) + template + static inline void apply(Box& box, + Point const& point, + Strategy const& strategy) { typedef typename point_type::type box_point_type; typedef typename coordinate_type::type box_coordinate_type; @@ -224,7 +229,7 @@ struct point_loop_on_spheroid point_loop < StrategyLess, StrategyGreater, 2, DimensionCount - >::apply(box, point); + >::apply(box, point, strategy); } }; diff --git a/include/boost/geometry/algorithms/detail/expand/segment.hpp b/include/boost/geometry/algorithms/detail/expand/segment.hpp index 041c1e175..0570e944d 100644 --- a/include/boost/geometry/algorithms/detail/expand/segment.hpp +++ b/include/boost/geometry/algorithms/detail/expand/segment.hpp @@ -5,9 +5,10 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France. -// This file was modified by Oracle on 2015. -// Modifications copyright (c) 2015, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2016. +// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Distributed under the Boost Software License, Version 1.0. @@ -39,25 +40,29 @@ namespace boost { namespace geometry namespace detail { namespace expand { - -struct segment_on_sphere +struct segment { - template - static inline void apply(Box& box, Segment const& segment) + template + static inline void apply(Box& box, + Segment const& segment, + Strategy const& strategy) { Box mbrs[2]; // compute the envelope of the segment - detail::envelope::envelope_segment_on_sphere + typename point_type::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::value - >::apply(segment, mbrs[0]); + >::apply(p[0], p[1], mbrs[0], strategy); // normalize the box - detail::envelope::envelope_box_on_spheroid::apply(box, mbrs[1]); + detail::envelope::envelope_box_on_spheroid::apply(box, mbrs[1], strategy); // compute the envelope of the two boxes - detail::envelope::envelope_range_of_boxes::apply(mbrs, box); + detail::envelope::envelope_range_of_boxes::apply(mbrs, box, strategy); } }; @@ -69,7 +74,6 @@ struct segment_on_sphere namespace dispatch { - template < typename Box, typename Segment, @@ -103,13 +107,27 @@ struct expand StrategyLess, StrategyGreater, box_tag, segment_tag, spherical_equatorial_tag, spherical_equatorial_tag - > : detail::expand::segment_on_sphere + > : detail::expand::segment {}; +template +< + typename Box, typename Segment, + typename StrategyLess, typename StrategyGreater +> +struct expand + < + Box, Segment, + StrategyLess, StrategyGreater, + box_tag, segment_tag, + geographic_tag, geographic_tag + > : detail::expand::segment +{}; } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH }} // namespace boost::geometry + #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_SEGMENT_HPP diff --git a/include/boost/geometry/algorithms/detail/has_self_intersections.hpp b/include/boost/geometry/algorithms/detail/has_self_intersections.hpp index 24746ac62..2ebf17c96 100644 --- a/include/boost/geometry/algorithms/detail/has_self_intersections.hpp +++ b/include/boost/geometry/algorithms/detail/has_self_intersections.hpp @@ -2,6 +2,10 @@ // Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2017. +// Modifications copyright (c) 2017 Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -59,8 +63,9 @@ namespace detail { namespace overlay { -template +template inline bool has_self_intersections(Geometry const& geometry, + Strategy const& strategy, RobustPolicy const& robust_policy, bool throw_on_self_intersection = true) { @@ -73,7 +78,7 @@ inline bool has_self_intersections(Geometry const& geometry, std::deque turns; detail::disjoint::disjoint_interrupt_policy policy; - geometry::self_turns(geometry, robust_policy, turns, policy); + geometry::self_turns(geometry, strategy, robust_policy, turns, policy); #ifdef BOOST_GEOMETRY_DEBUG_HAS_SELF_INTERSECTIONS bool first = true; @@ -132,11 +137,16 @@ inline bool has_self_intersections(Geometry const& geometry, typedef typename geometry::rescale_policy_type::type rescale_policy_type; + typename strategy::intersection::services::default_strategy + < + typename cs_tag::type + >::type strategy; + rescale_policy_type robust_policy = geometry::get_rescale_policy(geometry); - return has_self_intersections(geometry, robust_policy, - throw_on_self_intersection); + return has_self_intersections(geometry, strategy, robust_policy, + throw_on_self_intersection); } diff --git a/include/boost/geometry/algorithms/detail/intersection/interface.hpp b/include/boost/geometry/algorithms/detail/intersection/interface.hpp index e0955de3d..ddf49ad03 100644 --- a/include/boost/geometry/algorithms/detail/intersection/interface.hpp +++ b/include/boost/geometry/algorithms/detail/intersection/interface.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2014. -// Modifications copyright (c) 2014, Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2017. +// Modifications copyright (c) 2014-2017, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -51,10 +51,11 @@ struct intersection typedef typename boost::range_value::type OneOut; intersection_insert - < - Geometry1, Geometry2, OneOut, - overlay_intersection - >::apply(geometry1, geometry2, robust_policy, range::back_inserter(geometry_out), strategy); + < + Geometry1, Geometry2, OneOut, + overlay_intersection + >::apply(geometry1, geometry2, robust_policy, + range::back_inserter(geometry_out), strategy); return true; } @@ -84,11 +85,12 @@ struct intersection GeometryOut& out, Strategy const& strategy) { - return intersection< - Geometry2, Geometry1, - Tag2, Tag1, - false - >::apply(g2, g1, robust_policy, out, strategy); + return intersection + < + Geometry2, Geometry1, + Tag2, Tag1, + false + >::apply(g2, g1, robust_policy, out, strategy); } }; @@ -114,29 +116,26 @@ struct intersection concepts::check(); typedef typename geometry::rescale_overlay_policy_type - < - Geometry1, - Geometry2 - >::type rescale_policy_type; + < + Geometry1, + Geometry2 + >::type rescale_policy_type; rescale_policy_type robust_policy = geometry::get_rescale_policy(geometry1, geometry2); - typedef intersection_strategies - < - typename cs_tag::type, - Geometry1, - Geometry2, - typename geometry::point_type::type, - rescale_policy_type - > strategy; + typedef typename strategy::relate::services::default_strategy + < + Geometry1, Geometry2 + >::type strategy_type; return dispatch::intersection - < - Geometry1, - Geometry2 - >::apply(geometry1, geometry2, robust_policy, geometry_out, strategy()); + < + Geometry1, + Geometry2 + >::apply(geometry1, geometry2, robust_policy, geometry_out, + strategy_type()); } }; diff --git a/include/boost/geometry/algorithms/detail/is_simple/linear.hpp b/include/boost/geometry/algorithms/detail/is_simple/linear.hpp index 16d7b3a80..6c469f07f 100644 --- a/include/boost/geometry/algorithms/detail/is_simple/linear.hpp +++ b/include/boost/geometry/algorithms/detail/is_simple/linear.hpp @@ -1,8 +1,9 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2015, Oracle and/or its affiliates. +// Copyright (c) 2014-2017, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html @@ -48,6 +49,8 @@ #include +#include + namespace boost { namespace geometry { @@ -214,10 +217,16 @@ inline bool has_self_intersections(Linear const& linear) is_acceptable_turn > interrupt_policy(predicate); + typedef typename strategy::intersection::services::default_strategy + < + typename cs_tag::type + >::type strategy_type; + detail::self_get_turn_points::get_turns < turn_policy >::apply(linear, + strategy_type(), detail::no_rescale_policy(), turns, interrupt_policy); diff --git a/include/boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp b/include/boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp index 0a8121374..9f278ac04 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp @@ -1,8 +1,9 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2015, Oracle and/or its affiliates. +// Copyright (c) 2014-2017, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html @@ -47,6 +48,11 @@ class has_valid_self_turns private: typedef typename point_type::type point_type; + typedef typename strategy::intersection::services::default_strategy + < + typename cs_tag::type + >::type intersection_strategy_type; + typedef typename geometry::rescale_policy_type < point_type @@ -76,6 +82,8 @@ public: { boost::ignore_unused(visitor); + intersection_strategy_type intersection_strategy; + rescale_policy_type robust_policy = geometry::get_rescale_policy(geometry); @@ -85,6 +93,7 @@ public: > interrupt_policy; geometry::self_turns(geometry, + intersection_strategy, robust_policy, turns, interrupt_policy); diff --git a/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp b/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp index 0025445c2..eafe07841 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2015, Oracle and/or its affiliates. +// Copyright (c) 2014-2017, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -43,6 +43,8 @@ #include +#include + namespace boost { namespace geometry { @@ -109,10 +111,10 @@ private: geometry::partition < - geometry::model::box::type>, - typename base::expand_box, - typename base::overlaps_box - >::apply(polygon_iterators, item_visitor); + geometry::model::box::type> + >::apply(polygon_iterators, item_visitor, + typename base::expand_box(), + typename base::overlaps_box()); if (item_visitor.items_overlap) { diff --git a/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp b/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp index bbe8e8fc3..182571c56 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp @@ -246,10 +246,8 @@ protected: geometry::partition < - geometry::model::box::type>, - expand_box, - overlaps_box - >::apply(ring_iterators, item_visitor); + geometry::model::box::type> + >::apply(ring_iterators, item_visitor, expand_box(), overlaps_box()); if (item_visitor.items_overlap) { diff --git a/include/boost/geometry/algorithms/detail/not.hpp b/include/boost/geometry/algorithms/detail/not.hpp index 43e71e2e3..95cdfa24e 100644 --- a/include/boost/geometry/algorithms/detail/not.hpp +++ b/include/boost/geometry/algorithms/detail/not.hpp @@ -4,10 +4,11 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2015. -// Modifications copyright (c) 2015, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2017. +// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -46,6 +47,14 @@ struct not_ { return ! Policy::apply(geometry1, geometry2); } + + template + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) + { + return ! Policy::apply(geometry1, geometry2, strategy); + } }; diff --git a/include/boost/geometry/algorithms/detail/overlay/assign_parents.hpp b/include/boost/geometry/algorithms/detail/overlay/assign_parents.hpp index 047eb4993..2408b4b68 100644 --- a/include/boost/geometry/algorithms/detail/overlay/assign_parents.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/assign_parents.hpp @@ -2,6 +2,10 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2017. +// Modifications copyright (c) 2017 Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -258,8 +262,9 @@ inline void assign_parents(Geometry1 const& geometry1, geometry::partition < - box_type, ring_info_helper_get_box, ring_info_helper_ovelaps_box - >::apply(vector, visitor); + box_type + >::apply(vector, visitor, ring_info_helper_get_box(), + ring_info_helper_ovelaps_box()); } if (check_for_orientation) diff --git a/include/boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp b/include/boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp index a8171e148..9beb8ad64 100644 --- a/include/boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp @@ -2,6 +2,10 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2017. +// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -106,19 +110,27 @@ class backtrack_check_self_intersections public : typedef state state_type; - template + template + < + typename Operation, + typename Rings, typename Ring, typename Turns, + typename Strategy, + typename RobustPolicy, + typename Visitor + > static inline void apply(std::size_t size_at_start, - Rings& rings, Ring& ring, - Turns& turns, - typename boost::range_value::type const& turn, - Operation& operation, - traverse_error_type traverse_error, - Geometry1 const& geometry1, - Geometry2 const& geometry2, - RobustPolicy const& robust_policy, - state_type& state, - Visitor& visitor - ) + Rings& rings, + Ring& ring, + Turns& turns, + typename boost::range_value::type const& turn, + Operation& operation, + traverse_error_type traverse_error, + Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy, + RobustPolicy const& robust_policy, + state_type& state, + Visitor& visitor) { visitor.visit_traverse_reject(turns, turn, operation, traverse_error); @@ -128,8 +140,8 @@ public : if (! state.m_checked) { state.m_checked = true; - has_self_intersections(geometry1, robust_policy); - has_self_intersections(geometry2, robust_policy); + has_self_intersections(geometry1, strategy, robust_policy); + has_self_intersections(geometry2, strategy, robust_policy); } // Make bad output clean diff --git a/include/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp b/include/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp index 99281eaec..94667d0ed 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp @@ -2,6 +2,11 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2017. +// Modifications copyright (c) 2017 Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -39,29 +44,33 @@ template > struct get_turn_without_info { - template + template static inline OutputIterator apply( Point1 const& pi, Point1 const& pj, Point1 const& /*pk*/, Point2 const& qi, Point2 const& qj, Point2 const& /*qk*/, bool /*is_p_first*/, bool /*is_p_last*/, bool /*is_q_first*/, bool /*is_q_last*/, TurnInfo const& , + Strategy const& strategy, RobustPolicy const& robust_policy, OutputIterator out) { - typedef intersection_strategies - < - typename cs_tag::type, - Point1, - Point2, - typename TurnInfo::point_type, - RobustPolicy - > si; + typedef typename TurnInfo::point_type turn_point_type; - typedef typename si::segment_intersection_strategy_type strategy; + typedef policies::relate::segments_intersection_points + < + segment_intersection_points + < + turn_point_type, + typename geometry::segment_ratio_type + < + turn_point_type, RobustPolicy + >::type + > + > policy_type; typedef model::referring_segment segment_type1; - typedef model::referring_segment segment_type2; + typedef model::referring_segment segment_type2; segment_type1 p1(pi, pj); segment_type2 q1(qi, qj); @@ -75,15 +84,14 @@ struct get_turn_without_info geometry::recalculate(pj_rob, pj, robust_policy); geometry::recalculate(qi_rob, qi, robust_policy); geometry::recalculate(qj_rob, qj, robust_policy); - typename strategy::return_type result - = strategy::apply(p1, q1, robust_policy, - pi_rob, pj_rob, qi_rob, qj_rob); + typename policy_type::return_type result + = strategy.apply(p1, q1, policy_type(), robust_policy, + pi_rob, pj_rob, qi_rob, qj_rob); - for (std::size_t i = 0; i < result.template get<0>().count; i++) + for (std::size_t i = 0; i < result.count; i++) { - TurnInfo tp; - geometry::convert(result.template get<0>().intersections[i], tp.point); + geometry::convert(result.intersections[i], tp.point); *out++ = tp; } @@ -102,12 +110,14 @@ template typename Geometry1, typename Geometry2, typename RobustPolicy, - typename Turns + typename Turns, + typename Strategy > inline void get_intersection_points(Geometry1 const& geometry1, Geometry2 const& geometry2, RobustPolicy const& robust_policy, - Turns& turns) + Turns& turns, + Strategy const& strategy) { concepts::check_concepts_and_equal_dimensions(); @@ -142,6 +152,7 @@ inline void get_intersection_points(Geometry1 const& geometry1, >::type::apply( 0, geometry1, 1, geometry2, + strategy, robust_policy, turns, interrupt_policy); } diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp index a4cce3fd3..832acc078 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2015. -// Modifications copyright (c) 2015 Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2017. +// Modifications copyright (c) 2015-2017 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -930,6 +929,7 @@ struct get_turn_info typename Point1, typename Point2, typename TurnInfo, + typename IntersectionStrategy, typename RobustPolicy, typename OutputIterator > @@ -939,13 +939,19 @@ struct get_turn_info bool /*is_p_first*/, bool /*is_p_last*/, bool /*is_q_first*/, bool /*is_q_last*/, TurnInfo const& tp_model, + IntersectionStrategy const& intersection_strategy, RobustPolicy const& robust_policy, OutputIterator out) { - typedef intersection_info - inters_info; + typedef intersection_info + < + Point1, Point2, + typename TurnInfo::point_type, + IntersectionStrategy, + RobustPolicy + > inters_info; - inters_info inters(pi, pj, pk, qi, qj, qk, robust_policy); + inters_info inters(pi, pj, pk, qi, qj, qk, intersection_strategy, robust_policy); char const method = inters.d_info().how; @@ -991,9 +997,12 @@ struct get_turn_info < typename inters_info::cs_tag, typename inters_info::robust_point2_type, - typename inters_info::robust_point1_type + typename inters_info::robust_point1_type, + typename inters_info::side_strategy_type > swapped_side_calc(inters.rqi(), inters.rqj(), inters.rqk(), - inters.rpi(), inters.rpj(), inters.rpk()); + inters.rpi(), inters.rpj(), inters.rpk(), + inters.get_side_strategy()); + policy::template apply<1>(qi, qj, qk, pi, pj, pk, tp, inters.i_info(), inters.d_info(), swapped_side_calc); diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp index 85cdfbc02..48716634c 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp @@ -2,15 +2,15 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014. -// Modifications copyright (c) 2013-2014 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2017. +// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle - #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_FOR_ENDPOINT_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_FOR_ENDPOINT_HPP @@ -427,8 +427,11 @@ struct get_turn_info_for_endpoint } else if ( ip_j2 ) { - side_calculator - side_calc(ri2, ri1, rj1, ri2, rj2, rk2); + side_calculator + side_calc(ri2, ri1, rj1, ri2, rj2, rk2, inters.get_side_strategy()); std::pair operations = operations_of_equal(side_calc); @@ -478,8 +481,10 @@ struct get_turn_info_for_endpoint } else if ( ip_j2 ) { - side_calculator - side_calc(ri2, rj1, ri1, ri2, rj2, rk2); + side_calculator + side_calc(ri2, rj1, ri1, ri2, rj2, rk2, inters.get_side_strategy()); std::pair operations = operations_of_equal(side_calc); diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp index 3e7da1d79..5f2cb07fa 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp @@ -2,15 +2,15 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014, 2015. -// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017. +// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle - #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HELPERS_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HELPERS_HPP @@ -37,32 +37,27 @@ struct turn_operation_linear }; template struct side_calculator { - // This strategy should be the same as side strategy defined in - // intersection_strategies<> which is used in various places - // of the library - typedef typename strategy::side::services::default_strategy - < - TurnPointCSTag - >::type side; - inline side_calculator(Pi const& pi, Pj const& pj, Pk const& pk, - Qi const& qi, Qj const& qj, Qk const& qk) + Qi const& qi, Qj const& qj, Qk const& qk, + SideStrategy const& side_strategy) : m_pi(pi), m_pj(pj), m_pk(pk) , m_qi(qi), m_qj(qj), m_qk(qk) + , m_side_strategy(side_strategy) {} - inline int pk_wrt_p1() const { return side::apply(m_pi, m_pj, m_pk); } - inline int pk_wrt_q1() const { return side::apply(m_qi, m_qj, m_pk); } - inline int qk_wrt_p1() const { return side::apply(m_pi, m_pj, m_qk); } - inline int qk_wrt_q1() const { return side::apply(m_qi, m_qj, m_qk); } + inline int pk_wrt_p1() const { return m_side_strategy.apply(m_pi, m_pj, m_pk); } + inline int pk_wrt_q1() const { return m_side_strategy.apply(m_qi, m_qj, m_pk); } + inline int qk_wrt_p1() const { return m_side_strategy.apply(m_pi, m_pj, m_qk); } + inline int qk_wrt_q1() const { return m_side_strategy.apply(m_qi, m_qj, m_qk); } - inline int pk_wrt_q2() const { return side::apply(m_qj, m_qk, m_pk); } - inline int qk_wrt_p2() const { return side::apply(m_pj, m_pk, m_qk); } + inline int pk_wrt_q2() const { return m_side_strategy.apply(m_qj, m_qk, m_pk); } + inline int qk_wrt_p2() const { return m_side_strategy.apply(m_pj, m_pk, m_qk); } Pi const& m_pi; Pj const& m_pj; @@ -70,6 +65,8 @@ struct side_calculator Qi const& m_qi; Qj const& m_qj; Qk const& m_qk; + + SideStrategy const& m_side_strategy; }; template @@ -99,7 +96,7 @@ struct robust_points robust_point2_type m_rqi, m_rqj, m_rqk; }; -template +template class intersection_info_base : private robust_points { @@ -114,14 +111,17 @@ public: typedef typename cs_tag::type cs_tag; - typedef side_calculator side_calculator_type; + typedef typename IntersectionStrategy::side_strategy_type side_strategy_type; + typedef side_calculator side_calculator_type; intersection_info_base(Point1 const& pi, Point1 const& pj, Point1 const& pk, Point2 const& qi, Point2 const& qj, Point2 const& qk, + IntersectionStrategy const& intersection_strategy, RobustPolicy const& robust_policy) : base(pi, pj, pk, qi, qj, qk, robust_policy) , m_side_calc(base::m_rpi, base::m_rpj, base::m_rpk, - base::m_rqi, base::m_rqj, base::m_rqk) + base::m_rqi, base::m_rqj, base::m_rqk, + intersection_strategy.get_side_strategy()) , m_pi(pi), m_pj(pj), m_pk(pk) , m_qi(qi), m_qj(qj), m_qk(qk) {} @@ -155,8 +155,8 @@ private: point2_type const& m_qk; }; -template -class intersection_info_base +template +class intersection_info_base { public: typedef Point1 point1_type; @@ -167,12 +167,15 @@ public: typedef typename cs_tag::type cs_tag; - typedef side_calculator side_calculator_type; + typedef typename IntersectionStrategy::side_strategy_type side_strategy_type; + typedef side_calculator side_calculator_type; intersection_info_base(Point1 const& pi, Point1 const& pj, Point1 const& pk, Point2 const& qi, Point2 const& qj, Point2 const& qk, + IntersectionStrategy const& intersection_strategy, no_rescale_policy const& /*robust_policy*/) - : m_side_calc(pi, pj, pk, qi, qj, qk) + : m_side_calc(pi, pj, pk, qi, qj, qk, + intersection_strategy.get_side_strategy()) {} inline Point1 const& pi() const { return m_side_calc.m_pi; } @@ -203,40 +206,58 @@ template typename Point1, typename Point2, typename TurnPoint, + typename IntersectionStrategy, typename RobustPolicy > class intersection_info - : public intersection_info_base + : public intersection_info_base { - typedef intersection_info_base base; - - typedef typename intersection_strategies - < - typename base::cs_tag, - Point1, - Point2, - TurnPoint, - RobustPolicy - >::segment_intersection_strategy_type strategy; + typedef intersection_info_base base; public: + typedef segment_intersection_points + < + TurnPoint, + typename geometry::segment_ratio_type + < + TurnPoint, RobustPolicy + >::type + > intersection_point_type; + + // NOTE: formerly defined in intersection_strategies + typedef policies::relate::segments_tupled + < + policies::relate::segments_intersection_points + < + intersection_point_type + >, + policies::relate::segments_direction + > intersection_policy_type; + + typedef IntersectionStrategy intersection_strategy_type; + typedef typename IntersectionStrategy::side_strategy_type side_strategy_type; + typedef model::referring_segment segment_type1; typedef model::referring_segment segment_type2; typedef typename base::side_calculator_type side_calculator_type; - typedef typename strategy::return_type result_type; + typedef typename intersection_policy_type::return_type result_type; typedef typename boost::tuples::element<0, result_type>::type i_info_type; // intersection_info typedef typename boost::tuples::element<1, result_type>::type d_info_type; // dir_info intersection_info(Point1 const& pi, Point1 const& pj, Point1 const& pk, Point2 const& qi, Point2 const& qj, Point2 const& qk, + IntersectionStrategy const& intersection_strategy, RobustPolicy const& robust_policy) - : base(pi, pj, pk, qi, qj, qk, robust_policy) - , m_result(strategy::apply(segment_type1(pi, pj), - segment_type2(qi, qj), - robust_policy, - base::rpi(), base::rpj(), - base::rqi(), base::rqj())) + : base(pi, pj, pk, qi, qj, qk, intersection_strategy, robust_policy) + , m_result(intersection_strategy.apply( + segment_type1(pi, pj), + segment_type2(qi, qj), + intersection_policy_type(), + robust_policy, + base::rpi(), base::rpj(), + base::rqi(), base::rqj())) + , m_intersection_strategy(intersection_strategy) , m_robust_policy(robust_policy) {} @@ -244,6 +265,16 @@ public: inline i_info_type const& i_info() const { return m_result.template get<0>(); } inline d_info_type const& d_info() const { return m_result.template get<1>(); } + inline intersection_strategy_type const& get_intersection_strategy() const + { + return m_intersection_strategy; + } + + inline side_strategy_type get_side_strategy() const + { + return m_intersection_strategy.get_side_strategy(); + } + // TODO: it's more like is_spike_ip_p inline bool is_spike_p() const { @@ -307,17 +338,18 @@ private: { typedef model::referring_segment seg; - typedef intersection_strategies - < - typename base::cs_tag, Point, Point, Point, RobustPolicy - > si; + // 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); - typedef typename si::segment_intersection_strategy_type strategy; - - typename strategy::return_type result - = strategy::apply(seg(i, j), seg(j, k), m_robust_policy); - - return result.template get<0>().count == 2; + return result.count == 2; } template @@ -344,6 +376,7 @@ private: } result_type m_result; + IntersectionStrategy const& m_intersection_strategy; RobustPolicy const& m_robust_policy; }; diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp index 121728d82..76f87a5de 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014, 2015. -// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017. +// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -41,6 +41,7 @@ struct get_turn_info_linear_areal typename Point1, typename Point2, typename TurnInfo, + typename IntersectionStrategy, typename RobustPolicy, typename OutputIterator > @@ -50,13 +51,19 @@ struct get_turn_info_linear_areal bool is_p_first, bool is_p_last, bool is_q_first, bool is_q_last, TurnInfo const& tp_model, + IntersectionStrategy const& intersection_strategy, RobustPolicy const& robust_policy, OutputIterator out) { - typedef intersection_info - inters_info; + typedef intersection_info + < + Point1, Point2, + typename TurnInfo::point_type, + IntersectionStrategy, + RobustPolicy + > inters_info; - inters_info inters(pi, pj, pk, qi, qj, qk, robust_policy); + inters_info inters(pi, pj, pk, qi, qj, qk, intersection_strategy, robust_policy); char const method = inters.d_info().how; @@ -108,9 +115,11 @@ struct get_turn_info_linear_areal < typename inters_info::cs_tag, typename inters_info::robust_point2_type, - typename inters_info::robust_point1_type + typename inters_info::robust_point1_type, + typename inters_info::side_strategy_type > swapped_side_calc(inters.rqi(), inters.rqj(), inters.rqk(), - inters.rpi(), inters.rpj(), inters.rpk()); + inters.rpi(), inters.rpj(), inters.rpk(), + inters.get_side_strategy()); policy::template apply<1>(qi, qj, qk, pi, pj, pk, tp, inters.i_info(), inters.d_info(), swapped_side_calc); @@ -747,6 +756,9 @@ struct get_turn_info_linear_areal } else { + typedef typename IntersectionInfo::robust_point1_type rp1_type; + typedef typename IntersectionInfo::robust_point2_type rp2_type; + method_type replaced_method = method_touch_interior; if ( ip0.is_qj ) @@ -754,11 +766,12 @@ struct get_turn_info_linear_areal side_calculator < typename IntersectionInfo::cs_tag, - typename IntersectionInfo::robust_point1_type, - typename IntersectionInfo::robust_point2_type, - typename IntersectionInfo::robust_point2_type + rp1_type, rp2_type, + typename IntersectionInfo::side_strategy_type, + rp2_type > side_calc(inters.rqi(), inters.rpi(), inters.rpj(), - inters.rqi(), inters.rqj(), inters.rqk()); + inters.rqi(), inters.rqj(), inters.rqk(), + inters.get_side_strategy()); std::pair operations = get_info_e::operations_of_equal(side_calc); @@ -773,16 +786,13 @@ struct get_turn_info_linear_areal side_calculator < typename IntersectionInfo::cs_tag, - typename IntersectionInfo::robust_point1_type, - typename IntersectionInfo::robust_point2_type, - typename IntersectionInfo::robust_point2_type, - typename IntersectionInfo::robust_point1_type, - typename IntersectionInfo::robust_point1_type, - typename IntersectionInfo::robust_point2_type, - typename IntersectionInfo::robust_point1_type, - typename IntersectionInfo::robust_point2_type + rp1_type, rp2_type, + typename IntersectionInfo::side_strategy_type, + rp2_type, rp1_type, rp1_type, + rp2_type, rp1_type, rp2_type > side_calc(inters.rqi(), inters.rpi(), inters.rpj(), - inters.rqi(), inters.rpi(), inters.rqj()); + inters.rqi(), inters.rpi(), inters.rqj(), + inters.get_side_strategy()); std::pair operations = get_info_e::operations_of_equal(side_calc); @@ -832,9 +842,11 @@ struct get_turn_info_linear_areal typename IntersectionInfo::cs_tag, typename IntersectionInfo::robust_point1_type, typename IntersectionInfo::robust_point2_type, + typename IntersectionInfo::side_strategy_type, typename IntersectionInfo::robust_point2_type > side_calc(inters.rqi(), inters.rpj(), inters.rpi(), - inters.rqi(), inters.rqj(), inters.rqk()); + inters.rqi(), inters.rqj(), inters.rqk(), + inters.get_side_strategy()); std::pair operations = get_info_e::operations_of_equal(side_calc); diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp index 6bb3a74bb..9d1f10787 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp @@ -2,15 +2,15 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014, 2015. -// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017. +// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle - #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_LL_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_LL_HPP @@ -36,6 +36,7 @@ struct get_turn_info_linear_linear typename Point1, typename Point2, typename TurnInfo, + typename IntersectionStrategy, typename RobustPolicy, typename OutputIterator > @@ -45,13 +46,19 @@ struct get_turn_info_linear_linear bool is_p_first, bool is_p_last, bool is_q_first, bool is_q_last, TurnInfo const& tp_model, + IntersectionStrategy const& strategy, RobustPolicy const& robust_policy, OutputIterator out) { - typedef intersection_info - inters_info; + typedef intersection_info + < + Point1, Point2, + typename TurnInfo::point_type, + IntersectionStrategy, + RobustPolicy + > inters_info; - inters_info inters(pi, pj, pk, qi, qj, qk, robust_policy); + inters_info inters(pi, pj, pk, qi, qj, qk, strategy, robust_policy); char const method = inters.d_info().how; @@ -103,9 +110,11 @@ struct get_turn_info_linear_linear < typename inters_info::cs_tag, typename inters_info::robust_point2_type, - typename inters_info::robust_point1_type + typename inters_info::robust_point1_type, + typename inters_info::side_strategy_type > swapped_side_calc(inters.rqi(), inters.rqj(), inters.rqk(), - inters.rpi(), inters.rpj(), inters.rpk()); + inters.rpi(), inters.rpj(), inters.rpk(), + inters.get_side_strategy()); policy::template apply<1>(qi, qj, qk, pi, pj, pk, tp, inters.i_info(), inters.d_info(), diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp index 1eb18b74d..a2e597d91 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp @@ -3,15 +3,15 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2014, 2016. -// Modifications copyright (c) 2014, 2016 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2016, 2017. +// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle - #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP @@ -174,11 +174,12 @@ class get_turns_in_sections public : // Returns true if terminated, false if interrupted - template + template static inline bool apply( int source_id1, Geometry1 const& geometry1, Section1 const& sec1, int source_id2, Geometry2 const& geometry2, Section2 const& sec2, bool skip_larger, + IntersectionStrategy const& intersection_strategy, RobustPolicy const& robust_policy, Turns& turns, InterruptPolicy& interrupt_policy) @@ -295,7 +296,8 @@ public : TurnPolicy::apply(*prev1, *it1, *nd_next1, *prev2, *it2, *nd_next2, is_1_first, is_1_last, is_2_first, is_2_last, - ti, robust_policy, std::back_inserter(turns)); + ti, intersection_strategy, robust_policy, + std::back_inserter(turns)); if (InterruptPolicy::enabled) { @@ -381,9 +383,10 @@ template < typename Geometry1, typename Geometry2, bool Reverse1, bool Reverse2, - typename Turns, typename TurnPolicy, + typename IntersectionStrategy, typename RobustPolicy, + typename Turns, typename InterruptPolicy > struct section_visitor @@ -392,16 +395,20 @@ struct section_visitor Geometry1 const& m_geometry1; int m_source_id2; Geometry2 const& m_geometry2; + IntersectionStrategy const& m_intersection_strategy; RobustPolicy const& m_rescale_policy; Turns& m_turns; InterruptPolicy& m_interrupt_policy; section_visitor(int id1, Geometry1 const& g1, - int id2, Geometry2 const& g2, - RobustPolicy const& robust_policy, - Turns& turns, InterruptPolicy& ip) + int id2, Geometry2 const& g2, + IntersectionStrategy const& intersection_strategy, + RobustPolicy const& robust_policy, + Turns& turns, + InterruptPolicy& ip) : m_source_id1(id1), m_geometry1(g1) , m_source_id2(id2), m_geometry2(g2) + , m_intersection_strategy(intersection_strategy) , m_rescale_policy(robust_policy) , m_turns(turns) , m_interrupt_policy(ip) @@ -423,6 +430,7 @@ struct section_visitor m_source_id1, m_geometry1, sec1, m_source_id2, m_geometry2, sec2, false, + m_intersection_strategy, m_rescale_policy, m_turns, m_interrupt_policy); } @@ -441,10 +449,11 @@ class get_turns_generic { public: - template + template static inline void apply( int source_id1, Geometry1 const& geometry1, int source_id2, Geometry2 const& geometry2, + IntersectionStrategy const& intersection_strategy, RobustPolicy const& robust_policy, Turns& turns, InterruptPolicy& interrupt_policy) @@ -475,15 +484,19 @@ public: < Geometry1, Geometry2, Reverse1, Reverse2, - Turns, TurnPolicy, RobustPolicy, InterruptPolicy - > visitor(source_id1, geometry1, source_id2, geometry2, robust_policy, turns, interrupt_policy); + TurnPolicy, + IntersectionStrategy, RobustPolicy, + Turns, InterruptPolicy + > visitor(source_id1, geometry1, source_id2, geometry2, + intersection_strategy, robust_policy, + turns, interrupt_policy); geometry::partition < - box_type, - detail::section::get_section_box, - detail::section::overlaps_section_box - >::apply(sec1, sec2, visitor); + box_type + >::apply(sec1, sec2, visitor, + detail::section::get_section_box(), + detail::section::overlaps_section_box()); } }; @@ -518,10 +531,11 @@ struct get_turns_cs >::type iterator_type; - template + template static inline void apply( int source_id1, Range const& range, int source_id2, Box const& box, + IntersectionStrategy const& intersection_strategy, RobustPolicy const& robust_policy, Turns& turns, InterruptPolicy& interrupt_policy, @@ -593,8 +607,10 @@ struct get_turns_cs // NOTE: some dummy values could be passed below since this would be called only for Polygons and Boxes index == 0, size_type(index) == segments_count1, + intersection_strategy, robust_policy, - turns, interrupt_policy); + turns, + interrupt_policy); // Future performance enhancement: // return if told by the interrupt policy } @@ -622,7 +638,7 @@ private: else return 0; } - template + template static inline void get_turns_with_box(segment_identifier const& seg_id, int source_id2, // Points from a range: point_type const& rp0, @@ -635,6 +651,7 @@ private: box_point_type const& bp3, bool const is_range_first, bool const is_range_last, + IntersectionStrategy const& intersection_strategy, RobustPolicy const& robust_policy, // Output Turns& turns, @@ -653,25 +670,29 @@ private: TurnPolicy::apply(rp0, rp1, rp2, bp0, bp1, bp2, is_range_first, is_range_last, true, false, - ti, robust_policy, std::back_inserter(turns)); + ti, intersection_strategy, robust_policy, + std::back_inserter(turns)); ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 1); TurnPolicy::apply(rp0, rp1, rp2, bp1, bp2, bp3, is_range_first, is_range_last, false, false, - ti, robust_policy, std::back_inserter(turns)); + ti, intersection_strategy, robust_policy, + std::back_inserter(turns)); ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 2); TurnPolicy::apply(rp0, rp1, rp2, bp2, bp3, bp0, is_range_first, is_range_last, false, false, - ti, robust_policy, std::back_inserter(turns)); + ti, intersection_strategy, robust_policy, + std::back_inserter(turns)); ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 3); TurnPolicy::apply(rp0, rp1, rp2, bp3, bp0, bp1, is_range_first, is_range_last, false, true, - ti, robust_policy, std::back_inserter(turns)); + ti, intersection_strategy, robust_policy, + std::back_inserter(turns)); if (InterruptPolicy::enabled) { @@ -691,12 +712,14 @@ template > struct get_turns_polygon_cs { - template + template static inline void apply( int source_id1, Polygon const& polygon, int source_id2, Box const& box, + IntersectionStrategy const& intersection_strategy, RobustPolicy const& robust_policy, - Turns& turns, InterruptPolicy& interrupt_policy, + Turns& turns, + InterruptPolicy& interrupt_policy, signed_size_type multi_index = -1) { typedef typename geometry::ring_type::type ring_type; @@ -711,8 +734,10 @@ struct get_turns_polygon_cs intersector_type::apply( source_id1, geometry::exterior_ring(polygon), source_id2, box, + intersection_strategy, robust_policy, - turns, interrupt_policy, + turns, + interrupt_policy, multi_index, -1); signed_size_type i = 0; @@ -725,6 +750,7 @@ struct get_turns_polygon_cs intersector_type::apply( source_id1, *it, source_id2, box, + intersection_strategy, robust_policy, turns, interrupt_policy, multi_index, i); @@ -742,12 +768,14 @@ template > struct get_turns_multi_polygon_cs { - template + template static inline void apply( int source_id1, Multi const& multi, int source_id2, Box const& box, + IntersectionStrategy const& intersection_strategy, RobustPolicy const& robust_policy, - Turns& turns, InterruptPolicy& interrupt_policy) + Turns& turns, + InterruptPolicy& interrupt_policy) { typedef typename boost::range_iterator < @@ -766,7 +794,8 @@ struct get_turns_multi_polygon_cs Reverse, ReverseBox, TurnPolicy >::apply(source_id1, *it, source_id2, box, - robust_policy, turns, interrupt_policy, i); + intersection_strategy, robust_policy, + turns, interrupt_policy, i); } } }; @@ -918,13 +947,13 @@ template > struct get_turns_reversed { - template - static inline void apply( - int source_id1, Geometry1 const& g1, - int source_id2, Geometry2 const& g2, - RobustPolicy const& robust_policy, - Turns& turns, - InterruptPolicy& interrupt_policy) + template + static inline void apply(int source_id1, Geometry1 const& g1, + int source_id2, Geometry2 const& g2, + IntersectionStrategy const& intersection_strategy, + RobustPolicy const& robust_policy, + Turns& turns, + InterruptPolicy& interrupt_policy) { get_turns < @@ -932,8 +961,9 @@ struct get_turns_reversed Geometry2, Geometry1, Reverse2, Reverse1, TurnPolicy - >::apply(source_id2, g2, source_id1, g1, robust_policy, - turns, interrupt_policy); + >::apply(source_id2, g2, source_id1, g1, + intersection_strategy, robust_policy, + turns, interrupt_policy); } }; @@ -951,6 +981,7 @@ struct get_turns_reversed \tparam Turns type of turn-container (e.g. vector of "intersection/turn point"'s) \param geometry1 \param_geometry \param geometry2 \param_geometry +\param intersection_strategy segments intersection strategy \param robust_policy policy to handle robustness issues \param turns container which will contain turn points \param interrupt_policy policy determining if process is stopped @@ -962,15 +993,17 @@ template typename AssignPolicy, typename Geometry1, typename Geometry2, + typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy > inline void get_turns(Geometry1 const& geometry1, - Geometry2 const& geometry2, - RobustPolicy const& robust_policy, - Turns& turns, - InterruptPolicy& interrupt_policy) + Geometry2 const& geometry2, + IntersectionStrategy const& intersection_strategy, + RobustPolicy const& robust_policy, + Turns& turns, + InterruptPolicy& interrupt_policy) { concepts::check_concepts_and_equal_dimensions(); @@ -996,11 +1029,11 @@ inline void get_turns(Geometry1 const& geometry1, Reverse1, Reverse2, TurnPolicy > - >::type::apply( - 0, geometry1, - 1, geometry2, - robust_policy, - turns, interrupt_policy); + >::type::apply(0, geometry1, + 1, geometry2, + intersection_strategy, + robust_policy, + turns, interrupt_policy); } #if defined(_MSC_VER) diff --git a/include/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp b/include/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp index bb82003a2..3244480f4 100644 --- a/include/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp @@ -2,10 +2,11 @@ // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2014, 2015. -// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2015, 2017. +// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -71,7 +72,7 @@ struct intersection_segment_segment_point Segment2 const& segment2, RobustPolicy const& robust_policy, OutputIterator out, - Strategy const& ) + Strategy const& strategy) { typedef typename point_type::type point_type; @@ -106,16 +107,15 @@ struct intersection_segment_segment_point >::type > intersection_return_type; - typedef strategy::intersection::relate_cartesian_segments + typedef policies::relate::segments_intersection_points < - policies::relate::segments_intersection_points - < - intersection_return_type - > - > policy; + intersection_return_type + > policy_type; - intersection_return_type is = policy::apply(segment1, segment2, - robust_policy, pi_rob, pj_rob, qi_rob, qj_rob); + intersection_return_type + is = strategy.apply(segment1, segment2, + policy_type(), robust_policy, + pi_rob, pj_rob, qi_rob, qj_rob); for (std::size_t i = 0; i < is.count; i++) { @@ -134,13 +134,14 @@ struct intersection_linestring_linestring_point < typename Linestring1, typename Linestring2, typename RobustPolicy, - typename OutputIterator, typename Strategy + typename OutputIterator, + typename Strategy > static inline OutputIterator apply(Linestring1 const& linestring1, Linestring2 const& linestring2, RobustPolicy const& robust_policy, OutputIterator out, - Strategy const& ) + Strategy const& strategy) { typedef typename point_type::type point_type; @@ -151,7 +152,8 @@ struct intersection_linestring_linestring_point > turn_info; std::deque turns; - geometry::get_intersection_points(linestring1, linestring2, robust_policy, turns); + geometry::get_intersection_points(linestring1, linestring2, + robust_policy, turns, strategy); for (typename boost::range_iterator const>::type it = boost::begin(turns); it != boost::end(turns); ++it) @@ -295,7 +297,7 @@ struct intersection_of_linestring_with_areal static inline OutputIterator apply(LineString const& linestring, Areal const& areal, RobustPolicy const& robust_policy, OutputIterator out, - Strategy const& ) + Strategy const& strategy) { if (boost::size(linestring) == 0) { @@ -325,7 +327,7 @@ struct intersection_of_linestring_with_areal false, (OverlayType == overlay_intersection ? ReverseAreal : !ReverseAreal), detail::overlay::assign_null_policy - >(linestring, areal, robust_policy, turns, policy); + >(linestring, areal, strategy, robust_policy, turns, policy); if (no_crossing_turns_or_empty(turns)) { @@ -621,7 +623,7 @@ struct intersection_insert static inline OutputIterator apply(Geometry1 const& geometry1, Geometry2 const& geometry2, RobustPolicy const& robust_policy, - OutputIterator out, Strategy const& ) + OutputIterator out, Strategy const& strategy) { typedef detail::overlay::turn_info @@ -635,7 +637,7 @@ struct intersection_insert geometry::get_turns < false, false, detail::overlay::assign_null_policy - >(geometry1, geometry2, robust_policy, turns, policy); + >(geometry1, geometry2, strategy, robust_policy, turns, policy); for (typename std::vector::const_iterator it = turns.begin(); it != turns.end(); ++it) { @@ -996,7 +998,11 @@ inline OutputIterator intersection_insert(Geometry1 const& geometry1, concepts::check(); concepts::check(); - typedef typename Strategy::rescale_policy_type rescale_policy_type; + typedef typename geometry::rescale_policy_type + < + typename geometry::point_type::type // TODO from both + >::type rescale_policy_type; + rescale_policy_type robust_policy = geometry::get_rescale_policy(geometry1, geometry2); @@ -1037,22 +1043,13 @@ inline OutputIterator intersection_insert(Geometry1 const& geometry1, concepts::check(); concepts::check(); - typedef typename geometry::rescale_policy_type + typedef typename strategy::intersection::services::default_strategy < - typename geometry::point_type::type // TODO from both - >::type rescale_policy_type; - - typedef intersection_strategies - < - typename cs_tag::type, - Geometry1, - Geometry2, - typename geometry::point_type::type, - rescale_policy_type - > strategy; - + typename cs_tag::type + >::type strategy_type; + return intersection_insert(geometry1, geometry2, out, - strategy()); + strategy_type()); } }} // namespace detail::intersection diff --git a/include/boost/geometry/algorithms/detail/overlay/linear_linear.hpp b/include/boost/geometry/algorithms/detail/overlay/linear_linear.hpp index 34517f659..a74bb33ba 100644 --- a/include/boost/geometry/algorithms/detail/overlay/linear_linear.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/linear_linear.hpp @@ -1,11 +1,12 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2015, Oracle and/or its affiliates. +// Copyright (c) 2014-2017, Oracle and/or its affiliates. // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_LINEAR_LINEAR_HPP @@ -158,11 +159,13 @@ protected: typename Turns, typename LinearGeometry1, typename LinearGeometry2, + typename IntersectionStrategy, typename RobustPolicy > static inline void compute_turns(Turns& turns, LinearGeometry1 const& linear1, LinearGeometry2 const& linear2, + IntersectionStrategy const& strategy, RobustPolicy const& robust_policy) { turns.clear(); @@ -180,7 +183,7 @@ protected: assign_policy >, RobustPolicy - >::apply(turns, linear1, linear2, interrupt_policy, robust_policy); + >::apply(turns, linear1, linear2, interrupt_policy, strategy, robust_policy); } @@ -237,7 +240,7 @@ public: Linear2 const& linear2, RobustPolicy const& robust_policy, OutputIterator oit, - Strategy const& ) + Strategy const& strategy) { typedef typename detail::relate::turns::get_turns < @@ -255,7 +258,7 @@ public: typedef std::vector turns_container; turns_container turns; - compute_turns(turns, linear1, linear2, robust_policy); + compute_turns(turns, linear1, linear2, strategy, robust_policy); if ( turns.empty() ) { diff --git a/include/boost/geometry/algorithms/detail/overlay/overlay.hpp b/include/boost/geometry/algorithms/detail/overlay/overlay.hpp index 09c80025a..f1af2f194 100644 --- a/include/boost/geometry/algorithms/detail/overlay/overlay.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/overlay.hpp @@ -3,10 +3,11 @@ // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland -// This file was modified by Oracle on 2015. -// Modifications copyright (c) 2015, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2017. +// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -184,7 +185,7 @@ struct overlay Geometry1 const& geometry1, Geometry2 const& geometry2, RobustPolicy const& robust_policy, OutputIterator out, - Strategy const& , + Strategy const& strategy, Visitor& visitor) { bool const is_empty1 = geometry::is_empty(geometry1); @@ -233,7 +234,7 @@ std::cout << "get turns" << std::endl; < Reverse1, Reverse2, detail::overlay::assign_null_policy - >(geometry1, geometry2, robust_policy, turns, policy); + >(geometry1, geometry2, strategy, robust_policy, turns, policy); visitor.visit_turns(1, turns); @@ -262,6 +263,7 @@ std::cout << "traverse" << std::endl; traverse::apply ( geometry1, geometry2, + strategy, robust_policy, turns, rings, clusters, diff --git a/include/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp b/include/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp index 156cb5486..a26f54e00 100644 --- a/include/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp @@ -1,12 +1,13 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2015, Oracle and/or its affiliates. +// Copyright (c) 2015-2017, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html -// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle - #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_POINTLIKE_LINEAR_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_POINTLIKE_LINEAR_HPP @@ -69,12 +70,12 @@ struct point_linear_point Linear const& linear, RobustPolicy const&, OutputIterator oit, - Strategy const&) + Strategy const& strategy) { action_selector_pl_l < PointOut, OverlayType - >::apply(point, Policy::apply(point, linear), oit); + >::apply(point, Policy::apply(point, linear, strategy), oit); return oit; } }; @@ -95,7 +96,7 @@ struct multipoint_segment_point Segment const& segment, RobustPolicy const&, OutputIterator oit, - Strategy const&) + Strategy const& strategy) { for (typename boost::range_iterator::type it = boost::begin(multipoint); @@ -105,7 +106,7 @@ struct multipoint_segment_point action_selector_pl_l < PointOut, OverlayType - >::apply(*it, Policy::apply(*it, segment), oit); + >::apply(*it, Policy::apply(*it, segment, strategy), oit); } return oit; @@ -145,11 +146,14 @@ private: } }; - template + template class item_visitor_type { public: - item_visitor_type(OutputIterator& oit) : m_oit(oit) {} + item_visitor_type(OutputIterator& oit, Strategy const& strategy) + : m_oit(oit) + , m_strategy(strategy) + {} template inline void apply(Item1 const& item1, Item2 const& item2) @@ -157,11 +161,12 @@ private: action_selector_pl_l < PointOut, overlay_intersection - >::apply(item1, Policy::apply(item1, item2), m_oit); + >::apply(item1, Policy::apply(item1, item2, m_strategy), m_oit); } private: OutputIterator& m_oit; + Strategy const& m_strategy; }; // structs for partition -- end @@ -189,12 +194,13 @@ private: Linear const& m_linear; }; - template + template static inline OutputIterator get_common_points(MultiPoint const& multipoint, Linear const& linear, - OutputIterator oit) + OutputIterator oit, + Strategy const& strategy) { - item_visitor_type item_visitor(oit); + item_visitor_type item_visitor(oit, strategy); segment_range rng(linear); @@ -203,10 +209,9 @@ private: geometry::model::box < typename boost::range_value::type - >, - expand_box, - overlaps_box - >::apply(multipoint, rng, item_visitor); + > + >::apply(multipoint, rng, item_visitor, + expand_box(), overlaps_box()); return oit; } @@ -228,7 +233,8 @@ public: // compute the common points get_common_points(multipoint, linear, - std::back_inserter(common_points)); + std::back_inserter(common_points), + strategy); return multipoint_multipoint_point < diff --git a/include/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp b/include/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp index aedf22e1f..8540ef98a 100644 --- a/include/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp @@ -2,6 +2,11 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2017. +// Modifications copyright (c) 2017 Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -61,20 +66,25 @@ template typename Geometry, typename Turns, typename TurnPolicy, + typename IntersectionStrategy, typename RobustPolicy, typename InterruptPolicy > struct self_section_visitor { Geometry const& m_geometry; + IntersectionStrategy const& m_intersection_strategy; RobustPolicy const& m_rescale_policy; Turns& m_turns; InterruptPolicy& m_interrupt_policy; inline self_section_visitor(Geometry const& g, - RobustPolicy const& rp, - Turns& turns, InterruptPolicy& ip) + IntersectionStrategy const& is, + RobustPolicy const& rp, + Turns& turns, + InterruptPolicy& ip) : m_geometry(g) + , m_intersection_strategy(is) , m_rescale_policy(rp) , m_turns(turns) , m_interrupt_policy(ip) @@ -97,6 +107,7 @@ struct self_section_visitor 0, m_geometry, sec1, 0, m_geometry, sec2, false, + m_intersection_strategy, m_rescale_policy, m_turns, m_interrupt_policy); } @@ -116,9 +127,10 @@ struct self_section_visitor template struct get_turns { - template + template static inline bool apply( Geometry const& geometry, + IntersectionStrategy const& intersection_strategy, RobustPolicy const& robust_policy, Turns& turns, InterruptPolicy& interrupt_policy) @@ -142,17 +154,17 @@ struct get_turns self_section_visitor < Geometry, - Turns, TurnPolicy, RobustPolicy, InterruptPolicy - > visitor(geometry, robust_policy, turns, interrupt_policy); + Turns, TurnPolicy, IntersectionStrategy, RobustPolicy, InterruptPolicy + > visitor(geometry, intersection_strategy, robust_policy, turns, interrupt_policy); try { geometry::partition < - box_type, - detail::section::get_section_box, - detail::section::overlaps_section_box - >::apply(sec, visitor); + box_type + >::apply(sec, visitor, + detail::section::get_section_box(), + detail::section::overlaps_section_box()); } catch(self_ip_exception const& ) { @@ -208,9 +220,10 @@ struct self_get_turn_points TurnPolicy > { - template + template static inline bool apply( Box const& , + Strategy const& , RobustPolicy const& , Turns& , InterruptPolicy& ) @@ -259,6 +272,7 @@ struct self_get_turn_points \tparam Turns type of intersection container (e.g. vector of "intersection/turn point"'s) \param geometry geometry + \param strategy strategy to be used \param robust_policy policy to handle robustness issues \param turns container which will contain intersection points \param interrupt_policy policy determining if process is stopped @@ -268,13 +282,15 @@ template < typename AssignPolicy, typename Geometry, + typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy > inline void self_turns(Geometry const& geometry, - RobustPolicy const& robust_policy, - Turns& turns, InterruptPolicy& interrupt_policy) + IntersectionStrategy const& strategy, + RobustPolicy const& robust_policy, + Turns& turns, InterruptPolicy& interrupt_policy) { concepts::check(); @@ -285,7 +301,7 @@ inline void self_turns(Geometry const& geometry, typename tag::type, Geometry, turn_policy - >::apply(geometry, robust_policy, turns, interrupt_policy); + >::apply(geometry, strategy, robust_policy, turns, interrupt_policy); } diff --git a/include/boost/geometry/algorithms/detail/overlay/traversal.hpp b/include/boost/geometry/algorithms/detail/overlay/traversal.hpp index 5adc0fcf6..bc828920e 100644 --- a/include/boost/geometry/algorithms/detail/overlay/traversal.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/traversal.hpp @@ -140,10 +140,10 @@ struct traversal { for (int i = 0; i < 2; i++) { - turn_operation_type& op = turn.operations[i]; - if (op.visited.none()) + turn_operation_type& turn_op = turn.operations[i]; + if (turn_op.visited.none()) { - op.visited.set_visited(); + turn_op.visited.set_visited(); } } } diff --git a/include/boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp b/include/boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp index e0dfee19a..9ab82a77c 100644 --- a/include/boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp @@ -2,6 +2,10 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2017. +// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -38,6 +42,7 @@ template typename Geometry2, typename Turns, typename Clusters, + typename IntersectionStrategy, typename RobustPolicy, typename Visitor, typename Backtrack @@ -56,12 +61,14 @@ struct traversal_ring_creator inline traversal_ring_creator(Geometry1 const& geometry1, Geometry2 const& geometry2, Turns& turns, Clusters const& clusters, + IntersectionStrategy const& intersection_strategy, RobustPolicy const& robust_policy, Visitor& visitor) : m_trav(geometry1, geometry2, turns, clusters, robust_policy,visitor) , m_geometry1(geometry1) , m_geometry2(geometry2) , m_turns(turns) , m_clusters(clusters) + , m_intersection_strategy(intersection_strategy) , m_robust_policy(robust_policy) , m_visitor(visitor) { @@ -280,7 +287,8 @@ struct traversal_ring_creator rings, ring, m_turns, start_turn, m_turns[turn_index].operations[op_index], traverse_error, - m_geometry1, m_geometry2, m_robust_policy, + m_geometry1, m_geometry2, + m_intersection_strategy, m_robust_policy, state, m_visitor); } } @@ -314,6 +322,7 @@ private: Geometry2 const& m_geometry2; Turns& m_turns; Clusters const& m_clusters; + IntersectionStrategy const& m_intersection_strategy; RobustPolicy const& m_robust_policy; Visitor& m_visitor; }; diff --git a/include/boost/geometry/algorithms/detail/overlay/traverse.hpp b/include/boost/geometry/algorithms/detail/overlay/traverse.hpp index f01e50eb0..058f6c945 100644 --- a/include/boost/geometry/algorithms/detail/overlay/traverse.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/traverse.hpp @@ -58,6 +58,7 @@ class traverse public : template < + typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename Rings, @@ -66,6 +67,7 @@ public : > static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2, + IntersectionStrategy const& intersection_strategy, RobustPolicy const& robust_policy, Turns& turns, Rings& rings, Clusters& clusters, @@ -88,10 +90,11 @@ public : Reverse1, Reverse2, OverlayType, Geometry1, Geometry2, Turns, Clusters, + IntersectionStrategy, RobustPolicy, Visitor, Backtrack > trav(geometry1, geometry2, turns, clusters, - robust_policy, visitor); + intersection_strategy, robust_policy, visitor); std::size_t finalized_ring_size = boost::size(rings); diff --git a/include/boost/geometry/algorithms/detail/partition.hpp b/include/boost/geometry/algorithms/detail/partition.hpp index 8b19add47..12c6a5466 100644 --- a/include/boost/geometry/algorithms/detail/partition.hpp +++ b/include/boost/geometry/algorithms/detail/partition.hpp @@ -2,10 +2,11 @@ // Copyright (c) 2011-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2015. -// Modifications copyright (c) 2015 Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2017. +// Modifications copyright (c) 2015-2017 Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -47,13 +48,14 @@ inline void divide_box(Box const& box, Box& lower_box, Box& upper_box) // Divide forward_range into three subsets: lower, upper and oversized // (not-fitting) // (lower == left or bottom, upper == right or top) -template +template inline void divide_into_subsets(Box const& lower_box, - Box const& upper_box, - IteratorVector const& input, - IteratorVector& lower, - IteratorVector& upper, - IteratorVector& exceeding) + Box const& upper_box, + IteratorVector const& input, + IteratorVector& lower, + IteratorVector& upper, + IteratorVector& exceeding, + OverlapsPolicy const& overlaps_policy) { typedef typename boost::range_iterator < @@ -62,8 +64,8 @@ inline void divide_into_subsets(Box const& lower_box, for(it_type it = boost::begin(input); it != boost::end(input); ++it) { - bool const lower_overlapping = OverlapsPolicy::apply(lower_box, **it); - bool const upper_overlapping = OverlapsPolicy::apply(upper_box, **it); + bool const lower_overlapping = overlaps_policy.apply(lower_box, **it); + bool const upper_overlapping = overlaps_policy.apply(upper_box, **it); if (lower_overlapping && upper_overlapping) { @@ -87,23 +89,24 @@ inline void divide_into_subsets(Box const& lower_box, template < - typename ExpandPolicy, typename Box, - typename IteratorVector + typename IteratorVector, + typename ExpandPolicy > -inline void expand_with_elements(Box& total, IteratorVector const& input) +inline void expand_with_elements(Box& total, IteratorVector const& input, + ExpandPolicy const& expand_policy) { typedef typename boost::range_iterator::type it_type; for(it_type it = boost::begin(input); it != boost::end(input); ++it) { - ExpandPolicy::apply(total, **it); + expand_policy.apply(total, **it); } } // Match forward_range with itself -template -inline void handle_one(IteratorVector const& input, Policy& policy) +template +inline void handle_one(IteratorVector const& input, VisitPolicy& visitor) { if (boost::size(input) == 0) { @@ -118,7 +121,7 @@ inline void handle_one(IteratorVector const& input, Policy& policy) it_type it2 = it1; for (++it2; it2 != boost::end(input); ++it2) { - policy.apply(**it1, **it2); + visitor.apply(**it1, **it2); } } } @@ -126,13 +129,13 @@ inline void handle_one(IteratorVector const& input, Policy& policy) // Match forward range 1 with forward range 2 template < - typename Policy, typename IteratorVector1, - typename IteratorVector2 + typename IteratorVector2, + typename VisitPolicy > inline void handle_two(IteratorVector1 const& input1, - IteratorVector2 const& input2, - Policy& policy) + IteratorVector2 const& input2, + VisitPolicy& visitor) { typedef typename boost::range_iterator < @@ -157,14 +160,14 @@ inline void handle_two(IteratorVector1 const& input1, it2 != boost::end(input2); ++it2) { - policy.apply(**it1, **it2); + visitor.apply(**it1, **it2); } } } template inline bool recurse_ok(IteratorVector const& input, - std::size_t min_elements, std::size_t level) + std::size_t min_elements, std::size_t level) { return boost::size(input) >= min_elements && level < 100; @@ -172,8 +175,8 @@ inline bool recurse_ok(IteratorVector const& input, template inline bool recurse_ok(IteratorVector1 const& input1, - IteratorVector2 const& input2, - std::size_t min_elements, std::size_t level) + IteratorVector2 const& input2, + std::size_t min_elements, std::size_t level) { return boost::size(input1) >= min_elements && recurse_ok(input2, min_elements, level); @@ -186,103 +189,114 @@ template typename IteratorVector3 > inline bool recurse_ok(IteratorVector1 const& input1, - IteratorVector2 const& input2, - IteratorVector3 const& input3, - std::size_t min_elements, std::size_t level) + IteratorVector2 const& input2, + IteratorVector3 const& input3, + std::size_t min_elements, std::size_t level) { return boost::size(input1) >= min_elements && recurse_ok(input2, input3, min_elements, level); } -template -< - int Dimension, - typename Box, - typename OverlapsPolicy1, - typename OverlapsPolicy2, - typename ExpandPolicy1, - typename ExpandPolicy2, - typename VisitBoxPolicy -> + +template class partition_two_ranges; -template -< - int Dimension, - typename Box, - typename OverlapsPolicy, - typename ExpandPolicy, - typename VisitBoxPolicy -> +template class partition_one_range { - template - static inline Box get_new_box(IteratorVector const& input) + template + static inline Box get_new_box(IteratorVector const& input, + ExpandPolicy const& expand_policy) { Box box; geometry::assign_inverse(box); - expand_with_elements(box, input); + expand_with_elements(box, input, expand_policy); return box; } - template + template + < + typename IteratorVector, + typename VisitPolicy, + typename ExpandPolicy, + typename OverlapsPolicy, + typename VisitBoxPolicy + > static inline void next_level(Box const& box, - IteratorVector const& input, - std::size_t level, std::size_t min_elements, - Policy& policy, VisitBoxPolicy& box_policy) + IteratorVector const& input, + std::size_t level, std::size_t min_elements, + VisitPolicy& visitor, + ExpandPolicy const& expand_policy, + OverlapsPolicy const& overlaps_policy, + VisitBoxPolicy& box_policy) { if (recurse_ok(input, min_elements, level)) { partition_one_range - < - 1 - Dimension, - Box, - OverlapsPolicy, - ExpandPolicy, - VisitBoxPolicy - >::apply(box, input, level + 1, min_elements, policy, box_policy); + < + 1 - Dimension, + Box + >::apply(box, input, level + 1, min_elements, + visitor, expand_policy, overlaps_policy, box_policy); } else { - handle_one(input, policy); + handle_one(input, visitor); } } // Function to switch to two forward ranges if there are // geometries exceeding the separation line - template + template + < + typename IteratorVector, + typename VisitPolicy, + typename ExpandPolicy, + typename OverlapsPolicy, + typename VisitBoxPolicy + > static inline void next_level2(Box const& box, IteratorVector const& input1, IteratorVector const& input2, std::size_t level, std::size_t min_elements, - Policy& policy, VisitBoxPolicy& box_policy) + VisitPolicy& visitor, + ExpandPolicy const& expand_policy, + OverlapsPolicy const& overlaps_policy, + VisitBoxPolicy& box_policy) { if (recurse_ok(input1, input2, min_elements, level)) { partition_two_ranges - < - 1 - Dimension, - Box, - OverlapsPolicy, OverlapsPolicy, - ExpandPolicy, ExpandPolicy, - VisitBoxPolicy - >::apply(box, input1, input2, level + 1, min_elements, - policy, box_policy); + < + 1 - Dimension, Box + >::apply(box, input1, input2, level + 1, min_elements, + visitor, expand_policy, overlaps_policy, + expand_policy, overlaps_policy, box_policy); } else { - handle_two(input1, input2, policy); + handle_two(input1, input2, visitor); } } public : - template + template + < + typename IteratorVector, + typename VisitPolicy, + typename ExpandPolicy, + typename OverlapsPolicy, + typename VisitBoxPolicy + > static inline void apply(Box const& box, - IteratorVector const& input, - std::size_t level, - std::size_t min_elements, - Policy& policy, VisitBoxPolicy& box_policy) + IteratorVector const& input, + std::size_t level, + std::size_t min_elements, + VisitPolicy& visitor, + ExpandPolicy const& expand_policy, + OverlapsPolicy const& overlaps_policy, + VisitBoxPolicy& box_policy) { box_policy.apply(box, level); @@ -290,101 +304,121 @@ public : divide_box(box, lower_box, upper_box); IteratorVector lower, upper, exceeding; - divide_into_subsets(lower_box, upper_box, - input, lower, upper, exceeding); + divide_into_subsets(lower_box, upper_box, + input, lower, upper, exceeding, + overlaps_policy); if (boost::size(exceeding) > 0) { // Get the box of exceeding-only - Box exceeding_box = get_new_box(exceeding); + Box exceeding_box = get_new_box(exceeding, expand_policy); // Recursively do exceeding elements only, in next dimension they // will probably be less exceeding within the new box next_level(exceeding_box, exceeding, level, min_elements, - policy, box_policy); + visitor, expand_policy, overlaps_policy, box_policy); // Switch to two forward ranges, combine exceeding with // lower resp upper, but not lower/lower, upper/upper next_level2(exceeding_box, exceeding, lower, level, min_elements, - policy, box_policy); + visitor, expand_policy, overlaps_policy, box_policy); next_level2(exceeding_box, exceeding, upper, level, min_elements, - policy, box_policy); + visitor, expand_policy, overlaps_policy, box_policy); } // Recursively call operation both parts - next_level(lower_box, lower, level, min_elements, policy, box_policy); - next_level(upper_box, upper, level, min_elements, policy, box_policy); + next_level(lower_box, lower, level, min_elements, + visitor, expand_policy, overlaps_policy, box_policy); + next_level(upper_box, upper, level, min_elements, + visitor, expand_policy, overlaps_policy, box_policy); } }; template < int Dimension, - typename Box, - typename OverlapsPolicy1, - typename OverlapsPolicy2, - typename ExpandPolicy1, - typename ExpandPolicy2, - typename VisitBoxPolicy + typename Box > class partition_two_ranges { template < - typename Policy, typename IteratorVector1, - typename IteratorVector2 + typename IteratorVector2, + typename VisitPolicy, + typename ExpandPolicy1, + typename OverlapsPolicy1, + typename ExpandPolicy2, + typename OverlapsPolicy2, + typename VisitBoxPolicy > static inline void next_level(Box const& box, IteratorVector1 const& input1, IteratorVector2 const& input2, std::size_t level, std::size_t min_elements, - Policy& policy, VisitBoxPolicy& box_policy) + VisitPolicy& visitor, + ExpandPolicy1 const& expand_policy1, + OverlapsPolicy1 const& overlaps_policy1, + ExpandPolicy2 const& expand_policy2, + OverlapsPolicy2 const& overlaps_policy2, + VisitBoxPolicy& box_policy) { partition_two_ranges < - 1 - Dimension, - Box, - OverlapsPolicy1, - OverlapsPolicy2, - ExpandPolicy1, - ExpandPolicy2, - VisitBoxPolicy + 1 - Dimension, Box >::apply(box, input1, input2, level + 1, min_elements, - policy, box_policy); + visitor, expand_policy1, overlaps_policy1, + expand_policy2, overlaps_policy2, box_policy); } - template - static inline Box get_new_box(IteratorVector const& input) + template + static inline Box get_new_box(IteratorVector const& input, + ExpandPolicy const& expand_policy) { Box box; geometry::assign_inverse(box); - expand_with_elements(box, input); + expand_with_elements(box, input, expand_policy); return box; } - template + template + < + typename IteratorVector1, typename IteratorVector2, + typename ExpandPolicy1, typename ExpandPolicy2 + > static inline Box get_new_box(IteratorVector1 const& input1, - IteratorVector2 const& input2) + IteratorVector2 const& input2, + ExpandPolicy1 const& expand_policy1, + ExpandPolicy2 const& expand_policy2) { - Box box = get_new_box(input1); - expand_with_elements(box, input2); + Box box = get_new_box(input1, expand_policy1); + expand_with_elements(box, input2, expand_policy2); return box; } public : template < - typename Policy, typename IteratorVector1, - typename IteratorVector2 + typename IteratorVector2, + typename VisitPolicy, + typename ExpandPolicy1, + typename OverlapsPolicy1, + typename ExpandPolicy2, + typename OverlapsPolicy2, + typename VisitBoxPolicy > static inline void apply(Box const& box, IteratorVector1 const& input1, IteratorVector2 const& input2, std::size_t level, std::size_t min_elements, - Policy& policy, VisitBoxPolicy& box_policy) + VisitPolicy& visitor, + ExpandPolicy1 const& expand_policy1, + OverlapsPolicy1 const& overlaps_policy1, + ExpandPolicy2 const& expand_policy2, + OverlapsPolicy2 const& overlaps_policy2, + VisitBoxPolicy& box_policy) { box_policy.apply(box, level); @@ -393,10 +427,12 @@ public : IteratorVector1 lower1, upper1, exceeding1; IteratorVector2 lower2, upper2, exceeding2; - divide_into_subsets(lower_box, upper_box, - input1, lower1, upper1, exceeding1); - divide_into_subsets(lower_box, upper_box, - input2, lower2, upper2, exceeding2); + divide_into_subsets(lower_box, upper_box, + input1, lower1, upper1, exceeding1, + overlaps_policy1); + divide_into_subsets(lower_box, upper_box, + input2, lower2, upper2, exceeding2, + overlaps_policy2); if (boost::size(exceeding1) > 0) { @@ -404,13 +440,15 @@ public : if (recurse_ok(exceeding1, exceeding2, min_elements, level)) { - Box exceeding_box = get_new_box(exceeding1, exceeding2); + Box exceeding_box = get_new_box(exceeding1, exceeding2, + expand_policy1, expand_policy2); next_level(exceeding_box, exceeding1, exceeding2, level, - min_elements, policy, box_policy); + min_elements, visitor, expand_policy1, overlaps_policy1, + expand_policy2, overlaps_policy2, box_policy); } else { - handle_two(exceeding1, exceeding2, policy); + handle_two(exceeding1, exceeding2, visitor); } // All exceeding from 1 with lower and upper of 2: @@ -419,16 +457,18 @@ public : // the same combinations again and again) if (recurse_ok(lower2, upper2, exceeding1, min_elements, level)) { - Box exceeding_box = get_new_box(exceeding1); + Box exceeding_box = get_new_box(exceeding1, expand_policy1); next_level(exceeding_box, exceeding1, lower2, level, - min_elements, policy, box_policy); + min_elements, visitor, expand_policy1, overlaps_policy1, + expand_policy2, overlaps_policy2, box_policy); next_level(exceeding_box, exceeding1, upper2, level, - min_elements, policy, box_policy); + min_elements, visitor, expand_policy1, overlaps_policy1, + expand_policy2, overlaps_policy2, box_policy); } else { - handle_two(exceeding1, lower2, policy); - handle_two(exceeding1, upper2, policy); + handle_two(exceeding1, lower2, visitor); + handle_two(exceeding1, upper2, visitor); } } @@ -437,36 +477,40 @@ public : // All exceeding from 2 with lower and upper of 1: if (recurse_ok(lower1, upper1, exceeding2, min_elements, level)) { - Box exceeding_box = get_new_box(exceeding2); + Box exceeding_box = get_new_box(exceeding2, expand_policy2); next_level(exceeding_box, lower1, exceeding2, level, - min_elements, policy, box_policy); + min_elements, visitor, expand_policy1, overlaps_policy1, + expand_policy2, overlaps_policy2, box_policy); next_level(exceeding_box, upper1, exceeding2, level, - min_elements, policy, box_policy); + min_elements, visitor, expand_policy1, overlaps_policy1, + expand_policy2, overlaps_policy2, box_policy); } else { - handle_two(lower1, exceeding2, policy); - handle_two(upper1, exceeding2, policy); + handle_two(lower1, exceeding2, visitor); + handle_two(upper1, exceeding2, visitor); } } if (recurse_ok(lower1, lower2, min_elements, level)) { next_level(lower_box, lower1, lower2, level, - min_elements, policy, box_policy); + min_elements, visitor, expand_policy1, overlaps_policy1, + expand_policy2, overlaps_policy2, box_policy); } else { - handle_two(lower1, lower2, policy); + handle_two(lower1, lower2, visitor); } if (recurse_ok(upper1, upper2, min_elements, level)) { next_level(upper_box, upper1, upper2, level, - min_elements, policy, box_policy); + min_elements, visitor, expand_policy1, overlaps_policy1, + expand_policy2, overlaps_policy2, box_policy); } else { - handle_two(upper1, upper2, policy); + handle_two(upper1, upper2, visitor); } } }; @@ -493,46 +537,86 @@ struct include_all_policy template < typename Box, - typename ExpandPolicy1, - typename OverlapsPolicy1, - typename ExpandPolicy2 = ExpandPolicy1, - typename OverlapsPolicy2 = OverlapsPolicy1, typename IncludePolicy1 = detail::partition::include_all_policy, - typename IncludePolicy2 = detail::partition::include_all_policy, - typename VisitBoxPolicy = detail::partition::visit_no_policy + typename IncludePolicy2 = detail::partition::include_all_policy > class partition { + static const std::size_t default_min_elements = 16; + template < - typename ExpandPolicy, typename IncludePolicy, typename ForwardRange, - typename IteratorVector + typename IteratorVector, + typename ExpandPolicy > static inline void expand_to_range(ForwardRange const& forward_range, - Box& total, IteratorVector& iterator_vector) + Box& total, + IteratorVector& iterator_vector, + ExpandPolicy const& expand_policy) { - for(typename boost::range_iterator::type it - = boost::begin(forward_range); + for(typename boost::range_iterator::type + it = boost::begin(forward_range); it != boost::end(forward_range); ++it) { if (IncludePolicy::apply(*it)) { - ExpandPolicy::apply(total, *it); + expand_policy.apply(total, *it); iterator_vector.push_back(it); } } } -public : - template +public: + template + < + typename ForwardRange, + typename VisitPolicy, + typename ExpandPolicy, + typename OverlapsPolicy + > static inline void apply(ForwardRange const& forward_range, - VisitPolicy& visitor, - std::size_t min_elements = 16, - VisitBoxPolicy box_visitor = detail::partition::visit_no_policy() - ) + VisitPolicy& visitor, + ExpandPolicy const& expand_policy, + OverlapsPolicy const& overlaps_policy) + { + apply(forward_range, visitor, expand_policy, overlaps_policy, + default_min_elements, detail::partition::visit_no_policy()); + } + + template + < + typename ForwardRange, + typename VisitPolicy, + typename ExpandPolicy, + typename OverlapsPolicy + > + static inline void apply(ForwardRange const& forward_range, + VisitPolicy& visitor, + ExpandPolicy const& expand_policy, + OverlapsPolicy const& overlaps_policy, + std::size_t min_elements) + { + apply(forward_range, visitor, expand_policy, overlaps_policy, + min_elements, detail::partition::visit_no_policy()); + } + + template + < + typename ForwardRange, + typename VisitPolicy, + typename ExpandPolicy, + typename OverlapsPolicy, + typename VisitBoxPolicy + > + static inline void apply(ForwardRange const& forward_range, + VisitPolicy& visitor, + ExpandPolicy const& expand_policy, + OverlapsPolicy const& overlaps_policy, + std::size_t min_elements, + VisitBoxPolicy box_visitor) { typedef typename boost::range_iterator < @@ -544,17 +628,14 @@ public : std::vector iterator_vector; Box total; assign_inverse(total); - expand_to_range(forward_range, - total, iterator_vector); + expand_to_range(forward_range, total, + iterator_vector, expand_policy); detail::partition::partition_one_range < - 0, Box, - OverlapsPolicy1, - ExpandPolicy1, - VisitBoxPolicy + 0, Box >::apply(total, iterator_vector, 0, min_elements, - visitor, box_visitor); + visitor, expand_policy, overlaps_policy, box_visitor); } else { @@ -575,15 +656,88 @@ public : < typename ForwardRange1, typename ForwardRange2, - typename VisitPolicy + typename VisitPolicy, + typename ExpandPolicy1, + typename OverlapsPolicy1 > static inline void apply(ForwardRange1 const& forward_range1, - ForwardRange2 const& forward_range2, - VisitPolicy& visitor, - std::size_t min_elements = 16, - VisitBoxPolicy box_visitor - = detail::partition::visit_no_policy() - ) + ForwardRange2 const& forward_range2, + VisitPolicy& visitor, + ExpandPolicy1 const& expand_policy1, + OverlapsPolicy1 const& overlaps_policy1) + { + apply(forward_range1, forward_range2, visitor, + expand_policy1, overlaps_policy1, expand_policy1, overlaps_policy1, + default_min_elements, detail::partition::visit_no_policy()); + } + + template + < + typename ForwardRange1, + typename ForwardRange2, + typename VisitPolicy, + typename ExpandPolicy1, + typename OverlapsPolicy1, + typename ExpandPolicy2, + typename OverlapsPolicy2 + > + static inline void apply(ForwardRange1 const& forward_range1, + ForwardRange2 const& forward_range2, + VisitPolicy& visitor, + ExpandPolicy1 const& expand_policy1, + OverlapsPolicy1 const& overlaps_policy1, + ExpandPolicy2 const& expand_policy2, + OverlapsPolicy2 const& overlaps_policy2) + { + apply(forward_range1, forward_range2, visitor, + expand_policy1, overlaps_policy1, expand_policy2, overlaps_policy2, + default_min_elements, detail::partition::visit_no_policy()); + } + + template + < + typename ForwardRange1, + typename ForwardRange2, + typename VisitPolicy, + typename ExpandPolicy1, + typename OverlapsPolicy1, + typename ExpandPolicy2, + typename OverlapsPolicy2 + > + static inline void apply(ForwardRange1 const& forward_range1, + ForwardRange2 const& forward_range2, + VisitPolicy& visitor, + ExpandPolicy1 const& expand_policy1, + OverlapsPolicy1 const& overlaps_policy1, + ExpandPolicy2 const& expand_policy2, + OverlapsPolicy2 const& overlaps_policy2, + std::size_t min_elements) + { + apply(forward_range1, forward_range2, visitor, + expand_policy1, overlaps_policy1, expand_policy2, overlaps_policy1, + min_elements, detail::partition::visit_no_policy()); + } + + template + < + typename ForwardRange1, + typename ForwardRange2, + typename VisitPolicy, + typename ExpandPolicy1, + typename OverlapsPolicy1, + typename ExpandPolicy2, + typename OverlapsPolicy2, + typename VisitBoxPolicy + > + static inline void apply(ForwardRange1 const& forward_range1, + ForwardRange2 const& forward_range2, + VisitPolicy& visitor, + ExpandPolicy1 const& expand_policy1, + OverlapsPolicy1 const& overlaps_policy1, + ExpandPolicy2 const& expand_policy2, + OverlapsPolicy2 const& overlaps_policy2, + std::size_t min_elements, + VisitBoxPolicy box_visitor) { typedef typename boost::range_iterator < @@ -602,17 +756,18 @@ public : std::vector iterator_vector2; Box total; assign_inverse(total); - expand_to_range(forward_range1, - total, iterator_vector1); - expand_to_range(forward_range2, - total, iterator_vector2); + expand_to_range(forward_range1, total, + iterator_vector1, expand_policy1); + expand_to_range(forward_range2, total, + iterator_vector2, expand_policy2); detail::partition::partition_two_ranges < - 0, Box, OverlapsPolicy1, OverlapsPolicy2, - ExpandPolicy1, ExpandPolicy2, VisitBoxPolicy + 0, Box >::apply(total, iterator_vector1, iterator_vector2, - 0, min_elements, visitor, box_visitor); + 0, min_elements, visitor, expand_policy1, + overlaps_policy1, expand_policy2, overlaps_policy2, + box_visitor); } else { diff --git a/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp b/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp index a74954326..800fbb2e9 100644 --- a/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp +++ b/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014, 2015. -// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017. +// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -40,12 +40,21 @@ namespace detail { namespace relate { // Use the rtree in this case! // may be used to set EI and EB for an Areal geometry for which no turns were generated -template +template +< + typename OtherAreal, + typename Result, + typename PointInArealStrategy, + bool TransposeResult +> class no_turns_aa_pred { public: - no_turns_aa_pred(OtherAreal const& other_areal, Result & res) + no_turns_aa_pred(OtherAreal const& other_areal, + Result & res, + PointInArealStrategy const& point_in_areal_strategy) : m_result(res) + , m_point_in_areal_strategy(point_in_areal_strategy) , m_other_areal(other_areal) , m_flags(0) { @@ -68,6 +77,8 @@ public: template bool operator()(Areal const& areal) { + using detail::within::point_in_geometry; + // if those flags are set nothing will change if ( m_flags == 3 ) { @@ -87,7 +98,9 @@ public: // check if the areal is inside the other_areal // TODO: This is O(N) // Run in a loop O(NM) - optimize! - int const pig = detail::within::point_in_geometry(pt, m_other_areal); + int const pig = point_in_geometry(pt, + m_other_areal, + m_point_in_areal_strategy); //BOOST_GEOMETRY_ASSERT( pig != 0 ); // inside @@ -119,7 +132,9 @@ public: // TODO: O(N) // Optimize! - int const hpig = detail::within::point_in_geometry(range::front(range_ref), m_other_areal); + int const hpig = point_in_geometry(range::front(range_ref), + m_other_areal, + m_point_in_areal_strategy); // hole outside if ( hpig < 0 ) @@ -155,7 +170,9 @@ public: // TODO: O(N) // Optimize! - int const hpig = detail::within::point_in_geometry(range::front(range_ref), m_other_areal); + int const hpig = point_in_geometry(range::front(range_ref), + m_other_areal, + m_point_in_areal_strategy); // hole inside if ( hpig > 0 ) @@ -174,6 +191,7 @@ public: private: Result & m_result; + PointInArealStrategy const& m_point_in_areal_strategy; OtherAreal const& m_other_areal; int m_flags; }; @@ -191,8 +209,10 @@ struct areal_areal typedef typename geometry::point_type::type point1_type; typedef typename geometry::point_type::type point2_type; - template - static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Result & result) + template + static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2, + Result & result, + IntersectionStrategy const& intersection_strategy) { // TODO: If Areal geometry may have infinite size, change the following line: @@ -208,16 +228,31 @@ struct areal_areal interrupt_policy_areal_areal interrupt_policy(geometry1, geometry2, result); - turns::get_turns::apply(turns, geometry1, geometry2, interrupt_policy); + turns::get_turns::apply(turns, geometry1, geometry2, interrupt_policy, intersection_strategy); if ( BOOST_GEOMETRY_CONDITION(result.interrupt) ) return; - no_turns_aa_pred pred1(geometry2, result); + typedef typename IntersectionStrategy::template point_in_geometry_strategy + < + Geometry1, Geometry2 + >::type point_in_areal_strategy12_type; + point_in_areal_strategy12_type point_in_areal_strategy12 + = intersection_strategy.template get_point_in_geometry_strategy(); + typedef typename IntersectionStrategy::template point_in_geometry_strategy + < + Geometry2, Geometry1 + >::type point_in_areal_strategy21_type; + point_in_areal_strategy21_type point_in_areal_strategy21 + = intersection_strategy.template get_point_in_geometry_strategy(); + + no_turns_aa_pred + pred1(geometry2, result, point_in_areal_strategy12); for_each_disjoint_geometry_if<0, Geometry1>::apply(turns.begin(), turns.end(), geometry1, pred1); if ( BOOST_GEOMETRY_CONDITION(result.interrupt) ) return; - no_turns_aa_pred pred2(geometry1, result); + no_turns_aa_pred + pred2(geometry1, result, point_in_areal_strategy21); for_each_disjoint_geometry_if<1, Geometry2>::apply(turns.begin(), turns.end(), geometry2, pred2); if ( BOOST_GEOMETRY_CONDITION(result.interrupt) ) return; @@ -256,7 +291,8 @@ struct areal_areal { // analyse rings for which turns were not generated // or only i/i or u/u was generated - uncertain_rings_analyser<0, Result, Geometry1, Geometry2> rings_analyser(result, geometry1, geometry2); + uncertain_rings_analyser<0, Result, Geometry1, Geometry2, point_in_areal_strategy12_type> + rings_analyser(result, geometry1, geometry2, point_in_areal_strategy12); analyse_uncertain_rings<0>::apply(rings_analyser, turns.begin(), turns.end()); if ( BOOST_GEOMETRY_CONDITION(result.interrupt) ) @@ -295,7 +331,8 @@ struct areal_areal { // analyse rings for which turns were not generated // or only i/i or u/u was generated - uncertain_rings_analyser<1, Result, Geometry2, Geometry1> rings_analyser(result, geometry2, geometry1); + uncertain_rings_analyser<1, Result, Geometry2, Geometry1, point_in_areal_strategy21_type> + rings_analyser(result, geometry2, geometry1, point_in_areal_strategy21); analyse_uncertain_rings<1>::apply(rings_analyser, turns.begin(), turns.end()); //if ( result.interrupt ) @@ -565,7 +602,14 @@ struct areal_areal analyser.apply(res); } - template + template + < + std::size_t OpId, + typename Result, + typename Geometry, + typename OtherGeometry, + typename PointInArealStrategy + > class uncertain_rings_analyser { static const bool transpose_result = OpId != 0; @@ -574,10 +618,13 @@ struct areal_areal public: inline uncertain_rings_analyser(Result & result, Geometry const& geom, - OtherGeometry const& other_geom) - : geometry(geom), other_geometry(other_geom) + OtherGeometry const& other_geom, + PointInArealStrategy const& point_in_areal_strategy) + : geometry(geom) + , other_geometry(other_geom) , interrupt(result.interrupt) // just in case, could be false as well , m_result(result) + , m_point_in_areal_strategy(point_in_areal_strategy) , m_flags(0) { // check which relations must be analysed @@ -624,7 +671,10 @@ struct areal_areal // TODO: optimize! e.g. use spatial index // O(N) - running it in a loop gives O(NM) - int const pig = detail::within::point_in_geometry(range::front(range_ref), other_geometry); + using detail::within::point_in_geometry; + int const pig = point_in_geometry(range::front(range_ref), + other_geometry, + m_point_in_areal_strategy); //BOOST_GEOMETRY_ASSERT(pig != 0); if ( pig > 0 ) @@ -713,6 +763,7 @@ struct areal_areal private: Result & m_result; + PointInArealStrategy const& m_point_in_areal_strategy; int m_flags; }; diff --git a/include/boost/geometry/algorithms/detail/relate/implementation.hpp b/include/boost/geometry/algorithms/detail/relate/implementation.hpp index a6f1545ed..3bd0f806c 100644 --- a/include/boost/geometry/algorithms/detail/relate/implementation.hpp +++ b/include/boost/geometry/algorithms/detail/relate/implementation.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014, 2015. -// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017. +// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -25,6 +25,9 @@ #include #include +#include +#include + namespace boost { namespace geometry { diff --git a/include/boost/geometry/algorithms/detail/relate/interface.hpp b/include/boost/geometry/algorithms/detail/relate/interface.hpp index 95d452931..3575fe2bc 100644 --- a/include/boost/geometry/algorithms/detail/relate/interface.hpp +++ b/include/boost/geometry/algorithms/detail/relate/interface.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014, 2015. -// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017. +// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -29,6 +29,7 @@ #include #include #include +#include namespace boost { namespace geometry { @@ -186,18 +187,59 @@ struct result_handler_type > type; }; + }} // namespace detail::relate #endif // DOXYGEN_NO_DETAIL +namespace resolve_strategy { + +struct relate +{ + template + static inline void apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + ResultHandler & handler, + Strategy const& strategy) + { + dispatch::relate + < + Geometry1, + Geometry2 + >::apply(geometry1, geometry2, handler, strategy); + } + + template + static inline void apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + ResultHandler & handler, + default_strategy) + { + typedef typename strategy::relate::services::default_strategy + < + Geometry1, + Geometry2 + >::type strategy_type; + + dispatch::relate + < + Geometry1, + Geometry2 + >::apply(geometry1, geometry2, handler, strategy_type()); + } +}; + +} // resolve_strategy + namespace resolve_variant { template struct relate { - template + template static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, - Mask const& mask) + Mask const& mask, + Strategy const& strategy) { concepts::check(); concepts::check(); @@ -210,11 +252,7 @@ struct relate Mask >::type handler(mask); - dispatch::relate - < - Geometry1, - Geometry2 - >::apply(geometry1, geometry2, handler); + resolve_strategy::relate::apply(geometry1, geometry2, handler, strategy); return handler.result(); } @@ -223,60 +261,64 @@ struct relate template struct relate, Geometry2> { - template + template struct visitor : boost::static_visitor { Geometry2 const& m_geometry2; Mask const& m_mask; + Strategy const& m_strategy; - visitor(Geometry2 const& geometry2, Mask const& mask) - : m_geometry2(geometry2), m_mask(mask) {} + visitor(Geometry2 const& geometry2, Mask const& mask, Strategy const& strategy) + : m_geometry2(geometry2), m_mask(mask), m_strategy(strategy) {} template bool operator()(Geometry1 const& geometry1) const { return relate - ::apply(geometry1, m_geometry2, m_mask); + ::apply(geometry1, m_geometry2, m_mask, m_strategy); } }; - template + template static inline bool apply(boost::variant const& geometry1, Geometry2 const& geometry2, - Mask const& mask) + Mask const& mask, + Strategy const& strategy) { - return boost::apply_visitor(visitor(geometry2, mask), geometry1); + return boost::apply_visitor(visitor(geometry2, mask, strategy), geometry1); } }; template struct relate > { - template + template struct visitor : boost::static_visitor { Geometry1 const& m_geometry1; Mask const& m_mask; + Strategy const& m_strategy; - visitor(Geometry1 const& geometry1, Mask const& mask) - : m_geometry1(geometry1), m_mask(mask) {} + visitor(Geometry1 const& geometry1, Mask const& mask, Strategy const& strategy) + : m_geometry1(geometry1), m_mask(mask), m_strategy(strategy) {} template bool operator()(Geometry2 const& geometry2) const { return relate - ::apply(m_geometry1, geometry2, m_mask); + ::apply(m_geometry1, geometry2, m_mask, m_strategy); } }; - template + template static inline bool apply(Geometry1 const& geometry1, boost::variant const& geometry2, - Mask const& mask) + Mask const& mask, + Strategy const& strategy) { - return boost::apply_visitor(visitor(geometry1, mask), geometry2); + return boost::apply_visitor(visitor(geometry1, mask, strategy), geometry2); } }; @@ -289,35 +331,66 @@ struct relate< boost::variant > { - template + template struct visitor : boost::static_visitor { Mask const& m_mask; + Strategy const& m_strategy; - visitor(Mask const& mask) - : m_mask(mask) {} + visitor(Mask const& mask, Strategy const& strategy) + : m_mask(mask), m_strategy(strategy) {} template bool operator()(Geometry1 const& geometry1, Geometry2 const& geometry2) const { return relate - ::apply(geometry1, geometry2, m_mask); + ::apply(geometry1, geometry2, m_mask, m_strategy); } }; - template + template static inline bool apply(boost::variant const& geometry1, boost::variant const& geometry2, - Mask const& mask) + Mask const& mask, + Strategy const& strategy) { - return boost::apply_visitor(visitor(mask), geometry1, geometry2); + return boost::apply_visitor(visitor(mask, strategy), geometry1, geometry2); } }; } // namespace resolve_variant +/*! +\brief Checks relation between a pair of geometries defined by a mask. +\ingroup relate +\tparam Geometry1 \tparam_geometry +\tparam Geometry2 \tparam_geometry +\tparam Mask An intersection model Mask type. +\tparam Strategy \tparam_strategy{Relate} +\param geometry1 \param_geometry +\param geometry2 \param_geometry +\param mask An intersection model mask object. +\param strategy \param_strategy{relate} +\return true if the relation is compatible with the mask, false otherwise. + +\qbk{distinguish,with strategy} +\qbk{[include reference/algorithms/relate.qbk]} + */ +template +inline bool relate(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Mask const& mask, + Strategy const& strategy) +{ + return resolve_variant::relate + < + Geometry1, + Geometry2 + >::apply(geometry1, geometry2, mask, strategy); +} + /*! \brief Checks relation between a pair of geometries defined by a mask. \ingroup relate @@ -340,7 +413,7 @@ inline bool relate(Geometry1 const& geometry1, < Geometry1, Geometry2 - >::apply(geometry1, geometry2, mask); + >::apply(geometry1, geometry2, mask, default_strategy()); } }} // namespace boost::geometry diff --git a/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp b/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp index 58ba7bd1a..f1b4fdf81 100644 --- a/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp +++ b/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014, 2015. -// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017. +// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -46,15 +46,24 @@ namespace detail { namespace relate { // Use the rtree in this case! // may be used to set IE and BE for a Linear geometry for which no turns were generated -template +template +< + typename Geometry2, + typename Result, + typename PointInArealStrategy, + typename BoundaryChecker, + bool TransposeResult +> class no_turns_la_linestring_pred { public: no_turns_la_linestring_pred(Geometry2 const& geometry2, Result & res, + PointInArealStrategy const& point_in_areal_strategy, BoundaryChecker const& boundary_checker) : m_geometry2(geometry2) , m_result(res) + , m_point_in_areal_strategy(point_in_areal_strategy) , m_boundary_checker(boundary_checker) , m_interrupt_flags(0) { @@ -98,7 +107,9 @@ public: return false; } - int const pig = detail::within::point_in_geometry(range::front(linestring), m_geometry2); + int const pig = detail::within::point_in_geometry(range::front(linestring), + m_geometry2, + m_point_in_areal_strategy); //BOOST_GEOMETRY_ASSERT_MSG(pig != 0, "There should be no IPs"); if ( pig > 0 ) @@ -138,6 +149,7 @@ public: private: Geometry2 const& m_geometry2; Result & m_result; + PointInArealStrategy const& m_point_in_areal_strategy; BoundaryChecker const& m_boundary_checker; unsigned m_interrupt_flags; }; @@ -225,8 +237,10 @@ struct linear_areal > {}; - template - static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Result & result) + template + static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2, + Result & result, + IntersectionStrategy const& intersection_strategy) { // TODO: If Areal geometry may have infinite size, change the following line: @@ -242,7 +256,7 @@ struct linear_areal interrupt_policy_linear_areal interrupt_policy(geometry2, result); - turns::get_turns::apply(turns, geometry1, geometry2, interrupt_policy); + turns::get_turns::apply(turns, geometry1, geometry2, interrupt_policy, intersection_strategy); if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) ) return; @@ -251,9 +265,13 @@ struct linear_areal < Geometry2, Result, + typename IntersectionStrategy::template point_in_geometry_strategy::type, boundary_checker, TransposeResult - > pred1(geometry2, result, boundary_checker1); + > pred1(geometry2, + result, + intersection_strategy.template get_point_in_geometry_strategy(), + boundary_checker1); for_each_disjoint_geometry_if<0, Geometry1>::apply(turns.begin(), turns.end(), geometry1, pred1); if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) ) return; @@ -279,7 +297,8 @@ struct linear_areal analyse_each_turn(result, analyser, turns.begin(), turns.end(), geometry1, geometry2, - boundary_checker1); + boundary_checker1, + intersection_strategy.get_side_strategy()); if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) ) return; @@ -615,11 +634,13 @@ struct linear_areal typename TurnIt, typename Geometry, typename OtherGeometry, - typename BoundaryChecker> + typename BoundaryChecker, + typename SideStrategy> void apply(Result & res, TurnIt it, Geometry const& geometry, OtherGeometry const& other_geometry, - BoundaryChecker const& boundary_checker) + BoundaryChecker const& boundary_checker, + SideStrategy const& side_strategy) { overlay::operation_type op = it->operations[op_id].operation; @@ -856,7 +877,8 @@ struct linear_areal bool const from_inside = first_point && calculate_from_inside(geometry, other_geometry, - *it); + *it, + side_strategy); if ( from_inside ) update(res); @@ -956,7 +978,8 @@ struct linear_areal bool const first_from_inside = first_point && calculate_from_inside(geometry, other_geometry, - *it); + *it, + side_strategy); if ( first_from_inside ) { update(res); @@ -1144,10 +1167,11 @@ struct linear_areal // check if the passed turn's segment of Linear geometry arrived // from the inside or the outside of the Areal geometry - template + template static inline bool calculate_from_inside(Geometry1 const& geometry1, Geometry2 const& geometry2, - Turn const& turn) + Turn const& turn, + SideStrategy const& side_strategy) { typedef typename cs_tag::type cs_tag; @@ -1194,16 +1218,18 @@ struct linear_areal boost::end(range2)); // Will this sequence of points be always correct? - overlay::side_calculator side_calc(qi_conv, new_pj, pi, qi, qj, *qk_it); + overlay::side_calculator + side_calc(qi_conv, new_pj, pi, qi, qj, *qk_it, side_strategy); return calculate_from_inside_sides(side_calc); } else { - point1_type new_qj; + point2_type new_qj; geometry::convert(turn.point, new_qj); - overlay::side_calculator side_calc(qi_conv, new_pj, pi, qi, new_qj, qj); + overlay::side_calculator + side_calc(qi_conv, new_pj, pi, qi, new_qj, qj, side_strategy); return calculate_from_inside_sides(side_calc); } @@ -1270,13 +1296,15 @@ struct linear_areal typename Analyser, typename Geometry, typename OtherGeometry, - typename BoundaryChecker> + typename BoundaryChecker, + typename SideStrategy> static inline void analyse_each_turn(Result & res, Analyser & analyser, TurnIt first, TurnIt last, Geometry const& geometry, OtherGeometry const& other_geometry, - BoundaryChecker const& boundary_checker) + BoundaryChecker const& boundary_checker, + SideStrategy const& side_strategy) { if ( first == last ) return; @@ -1285,7 +1313,8 @@ struct linear_areal { analyser.apply(res, it, geometry, other_geometry, - boundary_checker); + boundary_checker, + side_strategy); if ( BOOST_GEOMETRY_CONDITION( res.interrupt ) ) return; @@ -1420,10 +1449,12 @@ struct areal_linear static const bool interruption_enabled = linear_areal_type::interruption_enabled; - template - static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Result & result) + template + static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2, + Result & result, + IntersectionStrategy const& intersection_strategy) { - linear_areal_type::apply(geometry2, geometry1, result); + linear_areal_type::apply(geometry2, geometry1, result, intersection_strategy); } }; diff --git a/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp b/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp index 7a3f373e0..520f2bd77 100644 --- a/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp +++ b/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp @@ -2,15 +2,15 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014, 2015. -// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017. +// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle - #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LINEAR_LINEAR_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LINEAR_LINEAR_HPP @@ -119,8 +119,10 @@ struct linear_linear typedef typename geometry::point_type::type point1_type; typedef typename geometry::point_type::type point2_type; - template - static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Result & result) + template + static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2, + Result & result, + IntersectionStrategy const& intersection_strategy) { // The result should be FFFFFFFFF relate::set::value>(result);// FFFFFFFFd, d in [1,9] or T @@ -138,7 +140,7 @@ struct linear_linear Geometry1, Geometry2, detail::get_turns::get_turn_info_type > - >::apply(turns, geometry1, geometry2, interrupt_policy); + >::apply(turns, geometry1, geometry2, interrupt_policy, intersection_strategy); if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) ) return; diff --git a/include/boost/geometry/algorithms/detail/relate/point_geometry.hpp b/include/boost/geometry/algorithms/detail/relate/point_geometry.hpp index be08016a1..a0c6c0d49 100644 --- a/include/boost/geometry/algorithms/detail/relate/point_geometry.hpp +++ b/include/boost/geometry/algorithms/detail/relate/point_geometry.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014, 2015. -// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017. +// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -37,10 +37,10 @@ struct point_geometry static const bool interruption_enabled = true; - template - static inline void apply(Point const& point, Geometry const& geometry, Result & result) + template + static inline void apply(Point const& point, Geometry const& geometry, Result & result, Strategy const& strategy) { - int pig = detail::within::point_in_geometry(point, geometry); + int pig = detail::within::point_in_geometry(point, geometry, strategy); if ( pig > 0 ) // within { @@ -95,10 +95,10 @@ struct geometry_point static const bool interruption_enabled = true; - template - static inline void apply(Geometry const& geometry, Point const& point, Result & result) + template + static inline void apply(Geometry const& geometry, Point const& point, Result & result, Strategy const& strategy) { - point_geometry::apply(point, geometry, result); + point_geometry::apply(point, geometry, result, strategy); } }; diff --git a/include/boost/geometry/algorithms/detail/relate/point_point.hpp b/include/boost/geometry/algorithms/detail/relate/point_point.hpp index e55be0822..b41d346f0 100644 --- a/include/boost/geometry/algorithms/detail/relate/point_point.hpp +++ b/include/boost/geometry/algorithms/detail/relate/point_point.hpp @@ -2,15 +2,15 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014. -// Modifications copyright (c) 2013, 2014, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2017. +// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle - #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_POINT_POINT_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_POINT_POINT_HPP @@ -35,8 +35,10 @@ struct point_point { static const bool interruption_enabled = false; - template - static inline void apply(Point1 const& point1, Point2 const& point2, Result & result) + template + static inline void apply(Point1 const& point1, Point2 const& point2, + Result & result, + Strategy const& /*strategy*/) { bool equal = detail::equals::equals_point_point(point1, point2); if ( equal ) @@ -86,8 +88,10 @@ struct point_multipoint { static const bool interruption_enabled = false; - template - static inline void apply(Point const& point, MultiPoint const& multi_point, Result & result) + template + static inline void apply(Point const& point, MultiPoint const& multi_point, + Result & result, + Strategy const& /*strategy*/) { if ( boost::empty(multi_point) ) { @@ -122,10 +126,12 @@ struct multipoint_point { static const bool interruption_enabled = false; - template - static inline void apply(MultiPoint const& multi_point, Point const& point, Result & result) + template + static inline void apply(MultiPoint const& multi_point, Point const& point, + Result & result, + Strategy const& strategy) { - point_multipoint::apply(point, multi_point, result); + point_multipoint::apply(point, multi_point, result, strategy); } }; @@ -134,8 +140,10 @@ struct multipoint_multipoint { static const bool interruption_enabled = true; - template - static inline void apply(MultiPoint1 const& multi_point1, MultiPoint2 const& multi_point2, Result & result) + template + static inline void apply(MultiPoint1 const& multi_point1, MultiPoint2 const& multi_point2, + Result & result, + Strategy const& /*strategy*/) { { // TODO: throw on empty input? diff --git a/include/boost/geometry/algorithms/detail/relate/relate_impl.hpp b/include/boost/geometry/algorithms/detail/relate/relate_impl.hpp index e8e422993..2ec2361c0 100644 --- a/include/boost/geometry/algorithms/detail/relate/relate_impl.hpp +++ b/include/boost/geometry/algorithms/detail/relate/relate_impl.hpp @@ -57,7 +57,8 @@ struct relate_impl implemented_tag >::type { - static inline bool apply(Geometry1 const& g1, Geometry2 const& g2) + template + static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy) { typename detail::relate::result_handler_type < @@ -66,7 +67,7 @@ struct relate_impl typename StaticMaskTrait::type >::type handler; - dispatch::relate::apply(g1, g2, handler); + dispatch::relate::apply(g1, g2, handler, strategy); return handler.result(); } diff --git a/include/boost/geometry/algorithms/detail/relate/turns.hpp b/include/boost/geometry/algorithms/detail/relate/turns.hpp index 09d74dec3..6fa05eaf2 100644 --- a/include/boost/geometry/algorithms/detail/relate/turns.hpp +++ b/include/boost/geometry/algorithms/detail/relate/turns.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014, 2015. -// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017. +// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -75,28 +75,35 @@ struct get_turns { detail::get_turns::no_interrupt_policy interrupt_policy; - apply(turns, geometry1, geometry2, interrupt_policy); + typename strategy::intersection::services::default_strategy + < + typename cs_tag::type + >::type intersection_strategy; + + apply(turns, geometry1, geometry2, interrupt_policy, intersection_strategy); } - template + template static inline void apply(Turns & turns, Geometry1 const& geometry1, Geometry2 const& geometry2, - InterruptPolicy & interrupt_policy) + InterruptPolicy & interrupt_policy, + IntersectionStrategy const& intersection_strategy) { RobustPolicy robust_policy = geometry::get_rescale_policy < RobustPolicy >(geometry1, geometry2); - apply(turns, geometry1, geometry2, interrupt_policy, robust_policy); + apply(turns, geometry1, geometry2, interrupt_policy, intersection_strategy, robust_policy); } - template + template static inline void apply(Turns & turns, Geometry1 const& geometry1, Geometry2 const& geometry2, InterruptPolicy & interrupt_policy, + IntersectionStrategy const& intersection_strategy, RobustPolicy const& robust_policy) { static const bool reverse1 = detail::overlay::do_reverse @@ -119,7 +126,8 @@ struct get_turns reverse2, GetTurnPolicy >::apply(0, geometry1, 1, geometry2, - robust_policy, turns, interrupt_policy); + intersection_strategy, robust_policy, + turns, interrupt_policy); } }; diff --git a/include/boost/geometry/algorithms/detail/relation/interface.hpp b/include/boost/geometry/algorithms/detail/relation/interface.hpp index e9a947455..83d27ed72 100644 --- a/include/boost/geometry/algorithms/detail/relation/interface.hpp +++ b/include/boost/geometry/algorithms/detail/relation/interface.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014, 2015. -// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017. +// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -35,16 +35,16 @@ struct result_handler_type }} // namespace detail::relate #endif // DOXYGEN_NO_DETAIL - namespace resolve_variant { template struct relation { - template + template static inline Matrix apply(Geometry1 const& geometry1, - Geometry2 const& geometry2) + Geometry2 const& geometry2, + Strategy const& strategy) { concepts::check(); concepts::check(); @@ -57,11 +57,7 @@ struct relation Matrix >::type handler; - dispatch::relate - < - Geometry1, - Geometry2 - >::apply(geometry1, geometry2, handler); + resolve_strategy::relate::apply(geometry1, geometry2, handler, strategy); return handler.result(); } @@ -70,56 +66,60 @@ struct relation template struct relation, Geometry2> { - template + template struct visitor : boost::static_visitor { Geometry2 const& m_geometry2; + Strategy const& m_strategy; - visitor(Geometry2 const& geometry2) - : m_geometry2(geometry2) {} + visitor(Geometry2 const& geometry2, Strategy const& strategy) + : m_geometry2(geometry2), m_strategy(strategy) {} template Matrix operator()(Geometry1 const& geometry1) const { return relation - ::template apply(geometry1, m_geometry2); + ::template apply(geometry1, m_geometry2, m_strategy); } }; - template + template static inline Matrix apply(boost::variant const& geometry1, - Geometry2 const& geometry2) + Geometry2 const& geometry2, + Strategy const& strategy) { - return boost::apply_visitor(visitor(geometry2), geometry1); + return boost::apply_visitor(visitor(geometry2, strategy), geometry1); } }; template struct relation > { - template + template struct visitor : boost::static_visitor { Geometry1 const& m_geometry1; + Strategy const& m_strategy; - visitor(Geometry1 const& geometry1) - : m_geometry1(geometry1) {} + visitor(Geometry1 const& geometry1, Strategy const& strategy) + : m_geometry1(geometry1), m_strategy(strategy) {} template Matrix operator()(Geometry2 const& geometry2) const { return relation - ::template apply(m_geometry1, geometry2); + ::template apply(m_geometry1, geometry2, m_strategy); } }; - template + template static inline Matrix apply(Geometry1 const& geometry1, - boost::variant const& geometry2) + boost::variant const& geometry2, + Strategy const& strategy) { - return boost::apply_visitor(visitor(geometry1), geometry2); + return boost::apply_visitor(visitor(geometry1, strategy), geometry2); } }; @@ -134,30 +134,63 @@ struct relation boost::variant > { - template + template struct visitor : boost::static_visitor { + Strategy const& m_strategy; + + visitor(Strategy const& strategy) + : m_strategy(strategy) {} + template Matrix operator()(Geometry1 const& geometry1, Geometry2 const& geometry2) const { return relation - ::template apply(geometry1, geometry2); + ::template apply(geometry1, geometry2, m_strategy); } }; - template + template static inline Matrix apply(boost::variant const& geometry1, - boost::variant const& geometry2) + boost::variant const& geometry2, + Strategy const& strategy) { - return boost::apply_visitor(visitor(), geometry1, geometry2); + return boost::apply_visitor(visitor(strategy), geometry1, geometry2); } }; } // namespace resolve_variant +/*! +\brief Calculates the relation between a pair of geometries as defined in DE-9IM. +\ingroup relation +\tparam Geometry1 \tparam_geometry +\tparam Geometry2 \tparam_geometry +\tparam Strategy \tparam_strategy{Relation} +\param geometry1 \param_geometry +\param geometry2 \param_geometry +\param strategy \param_strategy{relation} +\return The DE-9IM matrix expressing the relation between geometries. + +\qbk{distinguish,with strategy} +\qbk{[include reference/algorithms/relation.qbk]} + */ +template +inline de9im::matrix relation(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) +{ + return resolve_variant::relation + < + Geometry1, + Geometry2 + >::template apply(geometry1, geometry2, strategy); +} + + /*! \brief Calculates the relation between a pair of geometries as defined in DE-9IM. \ingroup relation @@ -177,7 +210,7 @@ inline de9im::matrix relation(Geometry1 const& geometry1, < Geometry1, Geometry2 - >::template apply(geometry1, geometry2); + >::template apply(geometry1, geometry2, default_strategy()); } diff --git a/include/boost/geometry/algorithms/detail/within/point_in_geometry.hpp b/include/boost/geometry/algorithms/detail/within/point_in_geometry.hpp index a73364c33..a24f4d21e 100644 --- a/include/boost/geometry/algorithms/detail/within/point_in_geometry.hpp +++ b/include/boost/geometry/algorithms/detail/within/point_in_geometry.hpp @@ -5,8 +5,10 @@ // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2013, 2014, 2015. -// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017. +// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -15,8 +17,6 @@ // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle - #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_POINT_IN_GEOMETRY_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_POINT_IN_GEOMETRY_HPP @@ -35,8 +35,7 @@ #include #include #include -#include -#include +#include #include #include @@ -46,6 +45,7 @@ namespace boost { namespace geometry { #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace within { + // TODO: is this needed? inline int check_result_type(int result) { @@ -83,50 +83,11 @@ int point_in_range(Point const& point, Range const& range, Strategy const& strat template inline int point_in_range(Point const& point, Range const& range) { - typedef typename point_type::type point_type1; - typedef typename point_type::type point_type2; - - typedef typename strategy::within::services::default_strategy + typedef typename strategy::point_in_geometry::services::default_strategy < - typename tag::type, - typename tag::type, - typename tag::type, - typename tag_cast::type, areal_tag>::type, - typename tag_cast - < - typename cs_tag::type, spherical_tag - >::type, - typename tag_cast - < - typename cs_tag::type, spherical_tag - >::type, - Point, - Geometry + Point, Geometry >::type strategy_type; - typedef typename strategy::covered_by::services::default_strategy - < - typename tag::type, - typename tag::type, - typename tag::type, - typename tag_cast::type, areal_tag>::type, - typename tag_cast - < - typename cs_tag::type, spherical_tag - >::type, - typename tag_cast - < - typename cs_tag::type, spherical_tag - >::type, - Point, - Geometry - >::type strategy_type2; - - static const bool same_strategies = boost::is_same::value; - BOOST_MPL_ASSERT_MSG((same_strategies), - DEFAULT_WITHIN_AND_COVERED_BY_STRATEGIES_NOT_COMPATIBLE, - (strategy_type, strategy_type2)); - return point_in_range(point, range, strategy_type()); } @@ -414,50 +375,11 @@ inline int point_in_geometry(Point const& point, Geometry const& geometry, Strat template inline int point_in_geometry(Point const& point, Geometry const& geometry) { - typedef typename point_type::type point_type1; - typedef typename point_type::type point_type2; - - typedef typename strategy::within::services::default_strategy + typedef typename strategy::point_in_geometry::services::default_strategy < - typename tag::type, - typename tag::type, - typename tag::type, - typename tag_cast::type, areal_tag>::type, - typename tag_cast - < - typename cs_tag::type, spherical_tag - >::type, - typename tag_cast - < - typename cs_tag::type, spherical_tag - >::type, - Point, - Geometry + Point, Geometry >::type strategy_type; - typedef typename strategy::covered_by::services::default_strategy - < - typename tag::type, - typename tag::type, - typename tag::type, - typename tag_cast::type, areal_tag>::type, - typename tag_cast - < - typename cs_tag::type, spherical_tag - >::type, - typename tag_cast - < - typename cs_tag::type, spherical_tag - >::type, - Point, - Geometry - >::type strategy_type2; - - static const bool same_strategies = boost::is_same::value; - BOOST_MPL_ASSERT_MSG((same_strategies), - DEFAULT_WITHIN_AND_COVERED_BY_STRATEGIES_NOT_COMPATIBLE, - (strategy_type, strategy_type2)); - return point_in_geometry(point, geometry, strategy_type()); } diff --git a/include/boost/geometry/algorithms/difference.hpp b/include/boost/geometry/algorithms/difference.hpp index f7ca48cbe..2d0afffe8 100644 --- a/include/boost/geometry/algorithms/difference.hpp +++ b/include/boost/geometry/algorithms/difference.hpp @@ -2,6 +2,10 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2017. +// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -49,10 +53,10 @@ template typename Strategy > inline OutputIterator difference_insert(Geometry1 const& geometry1, - Geometry2 const& geometry2, - RobustPolicy const& robust_policy, - OutputIterator out, - Strategy const& strategy) + Geometry2 const& geometry2, + RobustPolicy const& robust_policy, + OutputIterator out, + Strategy const& strategy) { concepts::check(); concepts::check(); @@ -93,25 +97,22 @@ template typename OutputIterator > inline OutputIterator difference_insert(Geometry1 const& geometry1, - Geometry2 const& geometry2, - RobustPolicy const& robust_policy, - OutputIterator out) + Geometry2 const& geometry2, + RobustPolicy const& robust_policy, + OutputIterator out) { concepts::check(); concepts::check(); concepts::check(); - typedef intersection_strategies + typename strategy::relate::services::default_strategy < - typename cs_tag::type, Geometry1, - Geometry2, - typename geometry::point_type::type, - RobustPolicy - > strategy; + Geometry2 + >::type strategy; return difference_insert(geometry1, geometry2, - robust_policy, out, strategy()); + robust_policy, out, strategy); } @@ -140,7 +141,8 @@ template typename Collection > inline void difference(Geometry1 const& geometry1, - Geometry2 const& geometry2, Collection& output_collection) + Geometry2 const& geometry2, + Collection& output_collection) { concepts::check(); concepts::check(); @@ -155,7 +157,8 @@ inline void difference(Geometry1 const& geometry1, >::type rescale_policy_type; rescale_policy_type robust_policy - = geometry::get_rescale_policy(geometry1, geometry2); + = geometry::get_rescale_policy(geometry1, + geometry2); detail::difference::difference_insert( geometry1, geometry2, robust_policy, diff --git a/include/boost/geometry/algorithms/dispatch/disjoint.hpp b/include/boost/geometry/algorithms/dispatch/disjoint.hpp index 627bcff83..78015f1a5 100644 --- a/include/boost/geometry/algorithms/dispatch/disjoint.hpp +++ b/include/boost/geometry/algorithms/dispatch/disjoint.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2014 Mateusz Loskot, London, UK. // Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2013-2014. -// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013-2017. +// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -60,6 +60,29 @@ struct disjoint : not_implemented {}; + +// If reversal is needed, perform it +template +< + typename Geometry1, typename Geometry2, + std::size_t DimensionCount, + typename Tag1, typename Tag2 +> +struct disjoint +{ + template + static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy) + { + return disjoint + < + Geometry2, Geometry1, + DimensionCount, + Tag2, Tag1 + >::apply(g2, g1, strategy); + } +}; + + } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH diff --git a/include/boost/geometry/algorithms/equals.hpp b/include/boost/geometry/algorithms/equals.hpp index d04d5c7f3..550a4d66c 100644 --- a/include/boost/geometry/algorithms/equals.hpp +++ b/include/boost/geometry/algorithms/equals.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2014, 2015, 2016. -// Modifications copyright (c) 2014-2016 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2015, 2016, 2017. +// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -40,7 +41,6 @@ #include #include -#include #include // For trivial checks @@ -65,6 +65,25 @@ namespace detail { namespace equals { +template +< + std::size_t Dimension, + std::size_t DimensionCount +> +struct point_point +{ + template + static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& strategy) + { + return ! detail::disjoint::point_point + < + Point1, Point2, + Dimension, DimensionCount + >::apply(point1, point2, strategy); + } +}; + + template < std::size_t Dimension, @@ -72,23 +91,23 @@ template > struct box_box { - template - static inline bool apply(Box1 const& box1, Box2 const& box2) + template + static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy) { if (!geometry::math::equals(get(box1), get(box2)) || !geometry::math::equals(get(box1), get(box2))) { return false; } - return box_box::apply(box1, box2); + return box_box::apply(box1, box2, strategy); } }; template struct box_box { - template - static inline bool apply(Box1 const& , Box2 const& ) + template + static inline bool apply(Box1 const& , Box2 const& , Strategy const& ) { return true; } @@ -97,8 +116,8 @@ struct box_box struct segment_segment { - template - static inline bool apply(Segment1 const& segment1, Segment2 const& segment2) + template + static inline bool apply(Segment1 const& segment1, Segment2 const& segment2, Strategy const& ) { return equals::equals_point_point( indexed_point_view(segment1), @@ -141,33 +160,43 @@ struct length_check }; +template +struct collected_vector +{ + typedef typename geometry::select_most_precise + < + typename select_coordinate_type + < + Geometry1, Geometry2 + >::type, + double + >::type calculation_type; + + typedef geometry::collected_vector + < + calculation_type, + Geometry1, + typename IntersectionStrategy::side_strategy_type + > type; +}; + template struct equals_by_collection { - template - static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2) + template + static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const&) { if (! TrivialCheck::apply(geometry1, geometry2)) { return false; } - typedef typename geometry::select_most_precise + typedef typename collected_vector < - typename select_coordinate_type - < - Geometry1, Geometry2 - >::type, - double - >::type calculation_type; + Geometry1, Geometry2, Strategy + >::type collected_vector_type; - typedef geometry::collected_vector - < - calculation_type, - Geometry1 - > collected_vector; - - std::vector c1, c2; + std::vector c1, c2; geometry::collect_vectors(c1, geometry1); geometry::collect_vectors(c2, geometry2); @@ -195,6 +224,53 @@ struct equals_by_relate > {}; +// If collect_vectors which is a SideStrategy-dispatched optimization +// is implemented in a way consistent with the Intersection/Side Strategy +// then collect_vectors is used, otherwise relate is used. +// NOTE: the result could be coneptually different for invalid +// geometries in different coordinate systems because collect_vectors +// and relate treat invalid geometries differently. +template +struct equals_by_collection_or_relate +{ + template + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) + { + typedef typename boost::is_base_of + < + nyi::not_implemented_tag, + typename collected_vector + < + Geometry1, Geometry2, Strategy + >::type + >::type enable_relate_type; + + return apply(geometry1, geometry2, strategy, enable_relate_type()); + } + +private: + template + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy, + boost::false_type /*enable_relate*/) + { + return equals_by_collection::apply(geometry1, geometry2, strategy); + } + + template + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy, + boost::true_type /*enable_relate*/) + { + return equals_by_relate::apply(geometry1, geometry2, strategy); + } +}; + + }} // namespace detail::equals #endif // DOXYGEN_NO_DETAIL @@ -226,7 +302,8 @@ template struct equals : equals { - static inline bool apply(Geometry1 const& g1, Geometry2 const& g2) + template + static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy) { return equals < @@ -234,19 +311,30 @@ struct equals Tag2, Tag1, DimensionCount, false - >::apply(g2, g1); + >::apply(g2, g1, strategy); } }; template struct equals - : geometry::detail::not_ - < - detail::disjoint::point_point - > + : detail::equals::point_point<0, DimensionCount> {}; +template +struct equals + : detail::equals::equals_by_relate +{}; + +template +struct equals + : detail::equals::equals_by_relate +{}; + +template +struct equals + : detail::equals::equals_by_relate +{}; template struct equals @@ -256,19 +344,19 @@ struct equals template struct equals - : detail::equals::equals_by_collection + : detail::equals::equals_by_collection_or_relate {}; template struct equals - : detail::equals::equals_by_collection + : detail::equals::equals_by_collection_or_relate {}; template struct equals - : detail::equals::equals_by_collection + : detail::equals::equals_by_collection_or_relate {}; @@ -290,7 +378,6 @@ struct equals struct equals - //: detail::equals::equals_by_collection : detail::equals::equals_by_relate {}; @@ -313,7 +400,7 @@ struct equals 2, Reverse > - : detail::equals::equals_by_collection + : detail::equals::equals_by_collection_or_relate {}; @@ -325,7 +412,7 @@ struct equals 2, Reverse > - : detail::equals::equals_by_collection + : detail::equals::equals_by_collection_or_relate {}; template @@ -336,7 +423,7 @@ struct equals 2, Reverse > - : detail::equals::equals_by_collection + : detail::equals::equals_by_collection_or_relate {}; @@ -344,80 +431,129 @@ struct equals #endif // DOXYGEN_NO_DISPATCH +namespace resolve_strategy +{ + +struct equals +{ + template + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) + { + return dispatch::equals + < + Geometry1, Geometry2 + >::apply(geometry1, geometry2, strategy); + } + + template + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + default_strategy) + { + typedef typename strategy::relate::services::default_strategy + < + Geometry1, + Geometry2 + >::type strategy_type; + + return dispatch::equals + < + Geometry1, Geometry2 + >::apply(geometry1, geometry2, strategy_type()); + } +}; + +} // namespace resolve_strategy + + namespace resolve_variant { template struct equals { + template static inline bool apply(Geometry1 const& geometry1, - Geometry2 const& geometry2) + Geometry2 const& geometry2, + Strategy const& strategy) { concepts::check_concepts_and_equal_dimensions - < - Geometry1 const, - Geometry2 const - >(); + < + Geometry1 const, + Geometry2 const + >(); - return dispatch::equals - ::apply(geometry1, geometry2); + return resolve_strategy::equals + ::apply(geometry1, geometry2, strategy); } }; template struct equals, Geometry2> { + template struct visitor: static_visitor { Geometry2 const& m_geometry2; + Strategy const& m_strategy; - visitor(Geometry2 const& geometry2) + visitor(Geometry2 const& geometry2, Strategy const& strategy) : m_geometry2(geometry2) + , m_strategy(strategy) {} template inline bool operator()(Geometry1 const& geometry1) const { return equals - ::apply(geometry1, m_geometry2); + ::apply(geometry1, m_geometry2, m_strategy); } }; + template static inline bool apply( boost::variant const& geometry1, - Geometry2 const& geometry2 + Geometry2 const& geometry2, + Strategy const& strategy ) { - return boost::apply_visitor(visitor(geometry2), geometry1); + return boost::apply_visitor(visitor(geometry2, strategy), geometry1); } }; template struct equals > { + template struct visitor: static_visitor { Geometry1 const& m_geometry1; + Strategy const& m_strategy; - visitor(Geometry1 const& geometry1) + visitor(Geometry1 const& geometry1, Strategy const& strategy) : m_geometry1(geometry1) + , m_strategy(strategy) {} template inline bool operator()(Geometry2 const& geometry2) const { return equals - ::apply(m_geometry1, geometry2); + ::apply(m_geometry1, geometry2, m_strategy); } }; + template static inline bool apply( Geometry1 const& geometry1, - boost::variant const& geometry2 + boost::variant const& geometry2, + Strategy const& strategy ) { - return boost::apply_visitor(visitor(geometry1), geometry2); + return boost::apply_visitor(visitor(geometry1, strategy), geometry2); } }; @@ -430,30 +566,70 @@ struct equals< boost::variant > { + template struct visitor: static_visitor { + Strategy const& m_strategy; + + visitor(Strategy const& strategy) + : m_strategy(strategy) + {} + template inline bool operator()(Geometry1 const& geometry1, Geometry2 const& geometry2) const { return equals - ::apply(geometry1, geometry2); + ::apply(geometry1, geometry2, m_strategy); } }; + template static inline bool apply( boost::variant const& geometry1, - boost::variant const& geometry2 + boost::variant const& geometry2, + Strategy const& strategy ) { - return boost::apply_visitor(visitor(), geometry1, geometry2); + return boost::apply_visitor(visitor(strategy), geometry1, geometry2); } }; } // namespace resolve_variant +/*! +\brief \brief_check{are spatially equal} +\details \details_check12{equals, is spatially equal}. Spatially equal means + that the same point set is included. A box can therefore be spatially equal + to a ring or a polygon, or a linestring can be spatially equal to a + multi-linestring or a segment. This only works theoretically, not all + combinations are implemented yet. +\ingroup equals +\tparam Geometry1 \tparam_geometry +\tparam Geometry2 \tparam_geometry +\tparam Strategy \tparam_strategy{Equals} +\param geometry1 \param_geometry +\param geometry2 \param_geometry +\param strategy \param_strategy{equals} +\return \return_check2{are spatially equal} + +\qbk{distinguish,with strategy} +\qbk{[include reference/algorithms/equals.qbk]} + */ +template +inline bool equals(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) +{ + return resolve_variant::equals + < + Geometry1, Geometry2 + >::apply(geometry1, geometry2, strategy); +} + + /*! \brief \brief_check{are spatially equal} \details \details_check12{equals, is spatially equal}. Spatially equal means @@ -469,13 +645,12 @@ struct equals< \return \return_check2{are spatially equal} \qbk{[include reference/algorithms/equals.qbk]} - */ template inline bool equals(Geometry1 const& geometry1, Geometry2 const& geometry2) { return resolve_variant::equals - ::apply(geometry1, geometry2); + ::apply(geometry1, geometry2, default_strategy()); } diff --git a/include/boost/geometry/algorithms/intersects.hpp b/include/boost/geometry/algorithms/intersects.hpp index 5349db76b..12ae169f1 100644 --- a/include/boost/geometry/algorithms/intersects.hpp +++ b/include/boost/geometry/algorithms/intersects.hpp @@ -4,10 +4,11 @@ // Copyright (c) 2008-2014 Bruno Lalande, Paris, France. // Copyright (c) 2009-2014 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2013-2014. -// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013-2017. +// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -29,6 +30,8 @@ #include #include +#include + namespace boost { namespace geometry { @@ -52,6 +55,10 @@ inline bool intersects(Geometry const& geometry) concepts::check(); typedef typename geometry::point_type::type point_type; + typedef typename strategy::relate::services::default_strategy + < + Geometry, Geometry + >::type strategy_type; typedef detail::no_rescale_policy rescale_policy_type; typedef detail::overlay::turn_info @@ -67,17 +74,44 @@ inline bool intersects(Geometry const& geometry) detail::overlay::assign_null_policy > turn_policy; + strategy_type strategy; rescale_policy_type robust_policy; detail::disjoint::disjoint_interrupt_policy policy; detail::self_get_turn_points::get_turns < turn_policy - >::apply(geometry, robust_policy, turns, policy); + >::apply(geometry, strategy, robust_policy, turns, policy); return policy.has_intersections; } +/*! +\brief \brief_check2{have at least one intersection} +\ingroup intersects +\tparam Geometry1 \tparam_geometry +\tparam Geometry2 \tparam_geometry +\tparam Strategy \tparam_strategy{Intersects} +\param geometry1 \param_geometry +\param geometry2 \param_geometry +\param strategy \param_strategy{intersects} +\return \return_check2{intersect each other} + +\qbk{distinguish,with strategy} +\qbk{[include reference/algorithms/intersects.qbk]} + */ +template +inline bool intersects(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) +{ + concepts::check(); + concepts::check(); + + return ! geometry::disjoint(geometry1, geometry2, strategy); +} + + /*! \brief \brief_check2{have at least one intersection} \ingroup intersects diff --git a/include/boost/geometry/algorithms/overlaps.hpp b/include/boost/geometry/algorithms/overlaps.hpp index 32738c294..bedf17599 100644 --- a/include/boost/geometry/algorithms/overlaps.hpp +++ b/include/boost/geometry/algorithms/overlaps.hpp @@ -4,8 +4,8 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2014, 2015. -// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2015, 2017. +// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -113,8 +113,8 @@ struct box_box_loop struct box_box { - template - static inline bool apply(Box1 const& b1, Box2 const& b2) + template + static inline bool apply(Box1 const& b1, Box2 const& b2, Strategy const& /*strategy*/) { bool overlaps = true; bool within1 = true; @@ -137,7 +137,6 @@ struct box_box }} // namespace detail::overlaps #endif // DOXYGEN_NO_DETAIL -//struct not_implemented_for_this_geometry_type : public boost::false_type {}; #ifndef DOXYGEN_NO_DISPATCH namespace dispatch @@ -170,6 +169,35 @@ struct overlaps #endif // DOXYGEN_NO_DISPATCH +/*! +\brief \brief_check2{overlap} +\ingroup overlaps +\tparam Geometry1 \tparam_geometry +\tparam Geometry2 \tparam_geometry +\tparam Strategy \tparam_strategy{Overlaps} +\param geometry1 \param_geometry +\param geometry2 \param_geometry +\param strategy \param_strategy{overlaps} +\return \return_check2{overlap} + +\qbk{distinguish,with strategy} +\qbk{[include reference/algorithms/overlaps.qbk]} +*/ +template +inline bool overlaps(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) +{ + concepts::check(); + concepts::check(); + + return dispatch::overlaps + < + Geometry1, + Geometry2 + >::apply(geometry1, geometry2, strategy); +} + /*! \brief \brief_check2{overlap} \ingroup overlaps @@ -187,11 +215,17 @@ inline bool overlaps(Geometry1 const& geometry1, Geometry2 const& geometry2) concepts::check(); concepts::check(); + typedef typename strategy::relate::services::default_strategy + < + Geometry1, + Geometry2 + >::type strategy_type; + return dispatch::overlaps < Geometry1, Geometry2 - >::apply(geometry1, geometry2); + >::apply(geometry1, geometry2, strategy_type()); } }} // namespace boost::geometry diff --git a/include/boost/geometry/algorithms/sym_difference.hpp b/include/boost/geometry/algorithms/sym_difference.hpp index 33f94c932..5d5bd904b 100644 --- a/include/boost/geometry/algorithms/sym_difference.hpp +++ b/include/boost/geometry/algorithms/sym_difference.hpp @@ -2,10 +2,11 @@ // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2015. -// Modifications copyright (c) 2015 Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2017. +// Modifications copyright (c) 2015-2017 Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -276,14 +277,10 @@ inline OutputIterator sym_difference_insert(Geometry1 const& geometry1, concepts::check(); concepts::check(); - typedef intersection_strategies + typedef typename strategy::intersection::services::default_strategy < - typename cs_tag::type, - Geometry1, - Geometry2, - typename geometry::point_type::type, - RobustPolicy - > strategy_type; + typename cs_tag::type + >::type strategy_type; return sym_difference_insert(geometry1, geometry2, robust_policy, out, strategy_type()); } diff --git a/include/boost/geometry/algorithms/touches.hpp b/include/boost/geometry/algorithms/touches.hpp index 6384cc2a8..49e104d25 100644 --- a/include/boost/geometry/algorithms/touches.hpp +++ b/include/boost/geometry/algorithms/touches.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2013, 2014, 2015. -// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017. +// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -104,8 +104,8 @@ struct box_box_loop struct box_box { - template - static inline bool apply(Box1 const& b1, Box2 const& b2) + template + static inline bool apply(Box1 const& b1, Box2 const& b2, Strategy const& /*strategy*/) { BOOST_STATIC_ASSERT((boost::is_same < @@ -205,15 +205,17 @@ struct areal_interrupt_policy } }; -template +template struct check_each_ring_for_within { bool has_within; Geometry const& m_geometry; + PointInRingStrategy const& m_strategy; - inline check_each_ring_for_within(Geometry const& g) + inline check_each_ring_for_within(Geometry const& g, PointInRingStrategy const& strategy) : has_within(false) , m_geometry(g) + , m_strategy(strategy) {} template @@ -221,18 +223,31 @@ struct check_each_ring_for_within { typename geometry::point_type::type p; geometry::point_on_border(p, range); - if ( !has_within && geometry::within(p, m_geometry) ) + if ( !has_within && geometry::within(p, m_geometry, m_strategy) ) { has_within = true; } } }; -template +template inline bool rings_containing(FirstGeometry const& geometry1, - SecondGeometry const& geometry2) + SecondGeometry const& geometry2, + IntersectionStrategy const& strategy) { - check_each_ring_for_within checker(geometry1); + // NOTE: This strategy could be defined inside IntersectionStrategy + typedef typename IntersectionStrategy::template point_in_geometry_strategy + < + FirstGeometry, SecondGeometry + >::type point_in_ring_strategy_type; + + point_in_ring_strategy_type point_in_ring_strategy + = strategy.template get_point_in_geometry_strategy(); + + check_each_ring_for_within + < + FirstGeometry, point_in_ring_strategy_type + > checker(geometry1, point_in_ring_strategy); geometry::detail::for_each_range(geometry2, checker); return checker.has_within; } @@ -240,8 +255,10 @@ inline bool rings_containing(FirstGeometry const& geometry1, template struct areal_areal { - static inline - bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2) + template + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + IntersectionStrategy const& strategy) { typedef detail::no_rescale_policy rescale_policy_type; typedef typename geometry::point_type::type point_type; @@ -259,11 +276,11 @@ struct areal_areal detail::overlay::do_reverse::value>::value, detail::overlay::do_reverse::value>::value, detail::overlay::assign_null_policy - >(geometry1, geometry2, robust_policy, turns, policy); + >(geometry1, geometry2, strategy, robust_policy, turns, policy); return policy.result() - && ! geometry::detail::touches::rings_containing(geometry1, geometry2) - && ! geometry::detail::touches::rings_containing(geometry2, geometry1); + && ! geometry::detail::touches::rings_containing(geometry1, geometry2, strategy) + && ! geometry::detail::touches::rings_containing(geometry2, geometry1, strategy); } }; @@ -271,10 +288,10 @@ struct areal_areal struct use_point_in_geometry { - template - static inline bool apply(Point const& point, Geometry const& geometry) + template + static inline bool apply(Point const& point, Geometry const& geometry, Strategy const& strategy) { - return detail::within::point_in_geometry(point, geometry) == 0; + return detail::within::point_in_geometry(point, geometry, strategy) == 0; } }; @@ -288,7 +305,8 @@ namespace dispatch { template < - typename Geometry1, typename Geometry2, + typename Geometry1, + typename Geometry2, typename Tag1 = typename tag::type, typename Tag2 = typename tag::type, typename CastedTag1 = typename tag_cast::type, @@ -309,18 +327,30 @@ template struct touches : touches { - static inline bool apply(Geometry1 const& g1, Geometry2 const& g2) + template + static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy) { - return touches::apply(g2, g1); + return touches::apply(g2, g1, strategy); } }; // P/P -template -struct touches +template +struct touches { - static inline bool apply(Geometry1 const& , Geometry2 const& ) + template + static inline bool apply(Geometry1 const& , Geometry2 const& , Strategy const&) + { + return false; + } +}; + +template +struct touches +{ + template + static inline bool apply(Geometry1 const&, Geometry2 const&, Strategy const&) { return false; } @@ -403,66 +433,115 @@ struct touches #endif // DOXYGEN_NO_DISPATCH +namespace resolve_strategy +{ + +struct touches +{ + template + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) + { + return dispatch::touches + < + Geometry1, Geometry2 + >::apply(geometry1, geometry2, strategy); + } + + template + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + default_strategy) + { + typedef typename strategy::relate::services::default_strategy + < + Geometry1, + Geometry2 + >::type strategy_type; + + return dispatch::touches + < + Geometry1, Geometry2 + >::apply(geometry1, geometry2, strategy_type()); + } +}; + +} // namespace resolve_strategy + + namespace resolve_variant { template struct touches { - static bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2) + template + static bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy) { concepts::check(); concepts::check(); - return dispatch::touches - ::apply(geometry1, geometry2); + return resolve_strategy::touches::apply(geometry1, geometry2, strategy); } }; template struct touches, Geometry2> { + template struct visitor: boost::static_visitor { Geometry2 const& m_geometry2; + Strategy const& m_strategy; - visitor(Geometry2 const& geometry2): m_geometry2(geometry2) {} + visitor(Geometry2 const& geometry2, Strategy const& strategy) + : m_geometry2(geometry2) + , m_strategy(strategy) + {} template bool operator()(Geometry1 const& geometry1) const { - return touches::apply(geometry1, m_geometry2); + return touches::apply(geometry1, m_geometry2, m_strategy); } }; - static inline bool - apply(boost::variant const& geometry1, - Geometry2 const& geometry2) + template + static inline bool apply(boost::variant const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) { - return boost::apply_visitor(visitor(geometry2), geometry1); + return boost::apply_visitor(visitor(geometry2, strategy), geometry1); } }; template struct touches > { + template struct visitor: boost::static_visitor { Geometry1 const& m_geometry1; + Strategy const& m_strategy; - visitor(Geometry1 const& geometry1): m_geometry1(geometry1) {} + visitor(Geometry1 const& geometry1, Strategy const& strategy) + : m_geometry1(geometry1) + , m_strategy(strategy) + {} template bool operator()(Geometry2 const& geometry2) const { - return touches::apply(m_geometry1, geometry2); + return touches::apply(m_geometry1, geometry2, m_strategy); } }; - static inline bool - apply(Geometry1 const& geometry1, - boost::variant const& geometry2) + template + static inline bool apply(Geometry1 const& geometry1, + boost::variant const& geometry2, + Strategy const& strategy) { - return boost::apply_visitor(visitor(geometry1), geometry2); + return boost::apply_visitor(visitor(geometry1, strategy), geometry2); } }; @@ -471,21 +550,29 @@ template , boost::variant > { + template struct visitor: boost::static_visitor { + Strategy const& m_strategy; + + visitor(Strategy const& strategy) + : m_strategy(strategy) + {} + template bool operator()(Geometry1 const& geometry1, Geometry2 const& geometry2) const { - return touches::apply(geometry1, geometry2); + return touches::apply(geometry1, geometry2, m_strategy); } }; - static inline bool - apply(boost::variant const& geometry1, - boost::variant const& geometry2) + template + static inline bool apply(boost::variant const& geometry1, + boost::variant const& geometry2, + Strategy const& strategy) { - return boost::apply_visitor(visitor(), geometry1, geometry2); + return boost::apply_visitor(visitor(strategy), geometry1, geometry2); } }; @@ -496,6 +583,10 @@ struct self_touches { concepts::check(); + typedef typename strategy::relate::services::default_strategy + < + Geometry, Geometry + >::type strategy_type; typedef detail::no_rescale_policy rescale_policy_type; typedef typename geometry::point_type::type point_type; typedef detail::overlay::turn_info @@ -511,11 +602,12 @@ struct self_touches std::deque turns; detail::touches::areal_interrupt_policy policy; + strategy_type strategy; rescale_policy_type robust_policy; detail::self_get_turn_points::get_turns < policy_type - >::apply(geometry, robust_policy, turns, policy); + >::apply(geometry, strategy, robust_policy, turns, policy); return policy.result(); } @@ -578,7 +670,35 @@ inline bool touches(Geometry const& geometry) template inline bool touches(Geometry1 const& geometry1, Geometry2 const& geometry2) { - return resolve_variant::touches::apply(geometry1, geometry2); + return resolve_variant::touches + < + Geometry1, Geometry2 + >::apply(geometry1, geometry2, default_strategy()); +} + +/*! +\brief \brief_check2{have at least one touching point (tangent - non overlapping)} +\ingroup touches +\tparam Geometry1 \tparam_geometry +\tparam Geometry2 \tparam_geometry +\tparam Strategy \tparam_strategy{Touches} +\param geometry1 \param_geometry +\param geometry2 \param_geometry +\param strategy \param_strategy{touches} +\return \return_check2{touch each other} + +\qbk{distinguish,with strategy} +\qbk{[include reference/algorithms/touches.qbk]} + */ +template +inline bool touches(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) +{ + return resolve_variant::touches + < + Geometry1, Geometry2 + >::apply(geometry1, geometry2, strategy); } diff --git a/include/boost/geometry/algorithms/union.hpp b/include/boost/geometry/algorithms/union.hpp index f0e55ec98..e2a7d2b96 100644 --- a/include/boost/geometry/algorithms/union.hpp +++ b/include/boost/geometry/algorithms/union.hpp @@ -2,10 +2,11 @@ // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2014. -// Modifications copyright (c) 2014 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2017. +// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -214,14 +215,10 @@ inline OutputIterator union_insert(Geometry1 const& geometry1, Geometry2 >::type rescale_policy_type; - typedef intersection_strategies + typename strategy::intersection::services::default_strategy < - typename cs_tag::type, - Geometry1, - Geometry2, - typename geometry::point_type::type, - rescale_policy_type - > strategy; + typename cs_tag::type + >::type strategy; rescale_policy_type robust_policy = geometry::get_rescale_policy(geometry1, geometry2); @@ -229,7 +226,7 @@ inline OutputIterator union_insert(Geometry1 const& geometry1, return dispatch::union_insert < Geometry1, Geometry2, GeometryOut - >::apply(geometry1, geometry2, robust_policy, out, strategy()); + >::apply(geometry1, geometry2, robust_policy, out, strategy); } diff --git a/include/boost/geometry/algorithms/within.hpp b/include/boost/geometry/algorithms/within.hpp index a1e6a58f8..ba170dd27 100644 --- a/include/boost/geometry/algorithms/within.hpp +++ b/include/boost/geometry/algorithms/within.hpp @@ -4,8 +4,10 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2013, 2014. -// Modifications copyright (c) 2013, 2014 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2017. +// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -14,8 +16,6 @@ // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle - #ifndef BOOST_GEOMETRY_ALGORITHMS_WITHIN_HPP #define BOOST_GEOMETRY_ALGORITHMS_WITHIN_HPP @@ -52,6 +52,7 @@ #include #include +#include #include #include @@ -75,9 +76,13 @@ struct use_point_in_geometry struct use_relate { template - static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& /*strategy*/) + static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy) { - return Strategy::apply(geometry1, geometry2); + typedef typename detail::de9im::static_mask_within_type + < + Geometry1, Geometry2 + >::type within_mask; + return geometry::relate(geometry1, geometry2, within_mask(), strategy); } }; @@ -300,23 +305,8 @@ struct within Geometry2 const& geometry2, default_strategy) { - typedef typename point_type::type point_type1; - typedef typename point_type::type point_type2; - typedef typename strategy::within::services::default_strategy < - typename tag::type, - typename tag::type, - typename tag::type, - typename tag_cast::type, areal_tag>::type, - typename tag_cast - < - typename cs_tag::type, spherical_tag - >::type, - typename tag_cast - < - typename cs_tag::type, spherical_tag - >::type, Geometry1, Geometry2 >::type strategy_type; @@ -517,8 +507,9 @@ inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2) } */ template -inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2, - Strategy const& strategy) +inline bool within(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) { return resolve_variant::within < diff --git a/include/boost/geometry/formulas/andoyer_inverse.hpp b/include/boost/geometry/formulas/andoyer_inverse.hpp index 57b5ab538..04a43995b 100644 --- a/include/boost/geometry/formulas/andoyer_inverse.hpp +++ b/include/boost/geometry/formulas/andoyer_inverse.hpp @@ -97,7 +97,7 @@ public: CT const d = acos(cos_d); // [0, pi] CT const sin_d = sin(d); // [-1, 1] - + if ( BOOST_GEOMETRY_CONDITION(EnableDistance) ) { CT const K = math::sqr(sin_lat1-sin_lat2); diff --git a/include/boost/geometry/formulas/area_formulas.hpp b/include/boost/geometry/formulas/area_formulas.hpp new file mode 100644 index 000000000..a9c503b65 --- /dev/null +++ b/include/boost/geometry/formulas/area_formulas.hpp @@ -0,0 +1,578 @@ +// Boost.Geometry + +// Copyright (c) 2015-2016 Oracle and/or its affiliates. + +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_FORMULAS_AREA_FORMULAS_HPP +#define BOOST_GEOMETRY_FORMULAS_AREA_FORMULAS_HPP + +#include +#include + +namespace boost { namespace geometry { namespace formula +{ + +/*! +\brief Formulas for computing spherical and ellipsoidal polygon area. + The current class computes the area of the trapezoid defined by a segment + the two meridians passing by the endpoints and the equator. +\author See +- Danielsen JS, The area under the geodesic. Surv Rev 30(232): +61–66, 1989 +- Charles F.F Karney, Algorithms for geodesics, 2011 +https://arxiv.org/pdf/1109.4448.pdf +*/ + +template < + typename CT, + std::size_t SeriesOrder = 2, + bool ExpandEpsN = true +> +class area_formulas +{ + +public: + + //TODO: move the following to a more general space to be used by other + // classes as well + /* + Evaluate the polynomial in x using Horner's method. + */ + template + static inline NT horner_evaluate(NT x, + IteratorType begin, + IteratorType end) + { + NT result(0); + IteratorType it = end; + do + { + result = result * x + *--it; + } + while (it != begin); + return result; + } + + /* + Clenshaw algorithm for summing trigonometric series + https://en.wikipedia.org/wiki/Clenshaw_algorithm + */ + template + static inline NT clenshaw_sum(NT cosx, + IteratorType begin, + IteratorType end) + { + IteratorType it = end; + bool odd = true; + CT b_k, b_k1(0), b_k2(0); + do + { + CT c_k = odd ? *--it : NT(0); + b_k = c_k + NT(2) * cosx * b_k1 - b_k2; + b_k2 = b_k1; + b_k1 = b_k; + odd = !odd; + } + while (it != begin); + + return *begin + b_k1 * cosx - b_k2; + } + + template + static inline void normalize(T& x, T& y) + { + T h = boost::math::hypot(x, y); + x /= h; + y /= h; + } + + /* + Generate and evaluate the series expansion of the following integral + + I4 = -integrate( (t(ep2) - t(k2*sin(sigma1)^2)) / (ep2 - k2*sin(sigma1)^2) + * sin(sigma1)/2, sigma1, pi/2, sigma ) + where + + t(x) = sqrt(1+1/x)*asinh(sqrt(x)) + x + + valid for ep2 and k2 small. We substitute k2 = 4 * eps / (1 - eps)^2 + and ep2 = 4 * n / (1 - n)^2 and expand in eps and n. + + The resulting sum of the series is of the form + + sum(C4[l] * cos((2*l+1)*sigma), l, 0, maxpow-1) ) + + The above expansion is performed in Computer Algebra System Maxima. + The C++ code (that yields the function evaluate_coeffs_n below) is generated + by the following Maxima script and is based on script: + http://geographiclib.sourceforge.net/html/geod.mac + + // Maxima script begin + taylordepth:5$ + ataylor(expr,var,ord):=expand(ratdisrep(taylor(expr,var,0,ord)))$ + jtaylor(expr,var1,var2,ord):=block([zz],expand(subst([zz=1], + ratdisrep(taylor(subst([var1=zz*var1,var2=zz*var2],expr),zz,0,ord)))))$ + + compute(maxpow):=block([int,t,intexp,area, x,ep2,k2], + maxpow:maxpow-1, + t : sqrt(1+1/x) * asinh(sqrt(x)) + x, + int:-(tf(ep2) - tf(k2*sin(sigma)^2)) / (ep2 - k2*sin(sigma)^2) + * sin(sigma)/2, + int:subst([tf(ep2)=subst([x=ep2],t), + tf(k2*sin(sigma)^2)=subst([x=k2*sin(sigma)^2],t)], + int), + int:subst([abs(sin(sigma))=sin(sigma)],int), + int:subst([k2=4*eps/(1-eps)^2,ep2=4*n/(1-n)^2],int), + intexp:jtaylor(int,n,eps,maxpow), + area:trigreduce(integrate(intexp,sigma)), + area:expand(area-subst(sigma=%pi/2,area)), + for i:0 thru maxpow do C4[i]:coeff(area,cos((2*i+1)*sigma)), + if expand(area-sum(C4[i]*cos((2*i+1)*sigma),i,0,maxpow)) # 0 + then error("left over terms in I4"), + 'done)$ + + printcode(maxpow):= + block([tab2:" ",tab3:" "], + print(" switch (SeriesOrder) {"), + for nn:1 thru maxpow do block([c], + print(concat(tab2,"case ",string(nn-1),":")), + c:0, + for m:0 thru nn-1 do block( + [q:jtaylor(subst([n=n],C4[m]),n,eps,nn-1), + linel:1200], + for j:m thru nn-1 do ( + print(concat(tab3,"coeffs_n[",c,"] = ", + string(horner(coeff(q,eps,j))),";")), + c:c+1) + ), + print(concat(tab3,"break;"))), + print(" }"), + 'done)$ + + maxpow:6$ + compute(maxpow)$ + printcode(maxpow)$ + // Maxima script end + + In the resulting code we should replace each number x by CT(x) + e.g. using the following scirpt: + sed -e 's/[0-9]\+/CT(&)/g; s/\[CT(/\[/g; s/)\]/\]/g; + s/case\sCT(/case /g; s/):/:/g' + */ + + static inline void evaluate_coeffs_n(CT n, CT coeffs_n[]) + { + + switch (SeriesOrder) { + case 0: + coeffs_n[0] = CT(2)/CT(3); + break; + case 1: + coeffs_n[0] = (CT(10)-CT(4)*n)/CT(15); + coeffs_n[1] = -CT(1)/CT(5); + coeffs_n[2] = CT(1)/CT(45); + break; + case 2: + coeffs_n[0] = (n*(CT(8)*n-CT(28))+CT(70))/CT(105); + coeffs_n[1] = (CT(16)*n-CT(7))/CT(35); + coeffs_n[2] = -CT(2)/CT(105); + coeffs_n[3] = (CT(7)-CT(16)*n)/CT(315); + coeffs_n[4] = -CT(2)/CT(105); + coeffs_n[5] = CT(4)/CT(525); + break; + case 3: + coeffs_n[0] = (n*(n*(CT(4)*n+CT(24))-CT(84))+CT(210))/CT(315); + coeffs_n[1] = ((CT(48)-CT(32)*n)*n-CT(21))/CT(105); + coeffs_n[2] = (-CT(32)*n-CT(6))/CT(315); + coeffs_n[3] = CT(11)/CT(315); + coeffs_n[4] = (n*(CT(32)*n-CT(48))+CT(21))/CT(945); + coeffs_n[5] = (CT(64)*n-CT(18))/CT(945); + coeffs_n[6] = -CT(1)/CT(105); + coeffs_n[7] = (CT(12)-CT(32)*n)/CT(1575); + coeffs_n[8] = -CT(8)/CT(1575); + coeffs_n[9] = CT(8)/CT(2205); + break; + case 4: + coeffs_n[0] = (n*(n*(n*(CT(16)*n+CT(44))+CT(264))-CT(924))+CT(2310))/CT(3465); + coeffs_n[1] = (n*(n*(CT(48)*n-CT(352))+CT(528))-CT(231))/CT(1155); + coeffs_n[2] = (n*(CT(1088)*n-CT(352))-CT(66))/CT(3465); + coeffs_n[3] = (CT(121)-CT(368)*n)/CT(3465); + coeffs_n[4] = CT(4)/CT(1155); + coeffs_n[5] = (n*((CT(352)-CT(48)*n)*n-CT(528))+CT(231))/CT(10395); + coeffs_n[6] = ((CT(704)-CT(896)*n)*n-CT(198))/CT(10395); + coeffs_n[7] = (CT(80)*n-CT(99))/CT(10395); + coeffs_n[8] = CT(4)/CT(1155); + coeffs_n[9] = (n*(CT(320)*n-CT(352))+CT(132))/CT(17325); + coeffs_n[10] = (CT(384)*n-CT(88))/CT(17325); + coeffs_n[11] = -CT(8)/CT(1925); + coeffs_n[12] = (CT(88)-CT(256)*n)/CT(24255); + coeffs_n[13] = -CT(16)/CT(8085); + coeffs_n[14] = CT(64)/CT(31185); + break; + case 5: + coeffs_n[0] = (n*(n*(n*(n*(CT(100)*n+CT(208))+CT(572))+CT(3432))-CT(12012))+CT(30030)) + /CT(45045); + coeffs_n[1] = (n*(n*(n*(CT(64)*n+CT(624))-CT(4576))+CT(6864))-CT(3003))/CT(15015); + coeffs_n[2] = (n*((CT(14144)-CT(10656)*n)*n-CT(4576))-CT(858))/CT(45045); + coeffs_n[3] = ((-CT(224)*n-CT(4784))*n+CT(1573))/CT(45045); + coeffs_n[4] = (CT(1088)*n+CT(156))/CT(45045); + coeffs_n[5] = CT(97)/CT(15015); + coeffs_n[6] = (n*(n*((-CT(64)*n-CT(624))*n+CT(4576))-CT(6864))+CT(3003))/CT(135135); + coeffs_n[7] = (n*(n*(CT(5952)*n-CT(11648))+CT(9152))-CT(2574))/CT(135135); + coeffs_n[8] = (n*(CT(5792)*n+CT(1040))-CT(1287))/CT(135135); + coeffs_n[9] = (CT(468)-CT(2944)*n)/CT(135135); + coeffs_n[10] = CT(1)/CT(9009); + coeffs_n[11] = (n*((CT(4160)-CT(1440)*n)*n-CT(4576))+CT(1716))/CT(225225); + coeffs_n[12] = ((CT(4992)-CT(8448)*n)*n-CT(1144))/CT(225225); + coeffs_n[13] = (CT(1856)*n-CT(936))/CT(225225); + coeffs_n[14] = CT(8)/CT(10725); + coeffs_n[15] = (n*(CT(3584)*n-CT(3328))+CT(1144))/CT(315315); + coeffs_n[16] = (CT(1024)*n-CT(208))/CT(105105); + coeffs_n[17] = -CT(136)/CT(63063); + coeffs_n[18] = (CT(832)-CT(2560)*n)/CT(405405); + coeffs_n[19] = -CT(128)/CT(135135); + coeffs_n[20] = CT(128)/CT(99099); + break; + } + } + + /* + Expand in k2 and ep2. + */ + static inline void evaluate_coeffs_ep(CT ep, CT coeffs_n[]) + { + switch (SeriesOrder) { + case 0: + coeffs_n[0] = CT(2)/CT(3); + break; + case 1: + coeffs_n[0] = (CT(10)-ep)/CT(15); + coeffs_n[1] = -CT(1)/CT(20); + coeffs_n[2] = CT(1)/CT(180); + break; + case 2: + coeffs_n[0] = (ep*(CT(4)*ep-CT(7))+CT(70))/CT(105); + coeffs_n[1] = (CT(4)*ep-CT(7))/CT(140); + coeffs_n[2] = CT(1)/CT(42); + coeffs_n[3] = (CT(7)-CT(4)*ep)/CT(1260); + coeffs_n[4] = -CT(1)/CT(252); + coeffs_n[5] = CT(1)/CT(2100); + break; + case 3: + coeffs_n[0] = (ep*((CT(12)-CT(8)*ep)*ep-CT(21))+CT(210))/CT(315); + coeffs_n[1] = ((CT(12)-CT(8)*ep)*ep-CT(21))/CT(420); + coeffs_n[2] = (CT(3)-CT(2)*ep)/CT(126); + coeffs_n[3] = -CT(1)/CT(72); + coeffs_n[4] = (ep*(CT(8)*ep-CT(12))+CT(21))/CT(3780); + coeffs_n[5] = (CT(2)*ep-CT(3))/CT(756); + coeffs_n[6] = CT(1)/CT(360); + coeffs_n[7] = (CT(3)-CT(2)*ep)/CT(6300); + coeffs_n[8] = -CT(1)/CT(1800); + coeffs_n[9] = CT(1)/CT(17640); + break; + case 4: + coeffs_n[0] = (ep*(ep*(ep*(CT(64)*ep-CT(88))+CT(132))-CT(231))+CT(2310))/CT(3465); + coeffs_n[1] = (ep*(ep*(CT(64)*ep-CT(88))+CT(132))-CT(231))/CT(4620); + coeffs_n[2] = (ep*(CT(16)*ep-CT(22))+CT(33))/CT(1386); + coeffs_n[3] = (CT(8)*ep-CT(11))/CT(792); + coeffs_n[4] = CT(1)/CT(110); + coeffs_n[5] = (ep*((CT(88)-CT(64)*ep)*ep-CT(132))+CT(231))/CT(41580); + coeffs_n[6] = ((CT(22)-CT(16)*ep)*ep-CT(33))/CT(8316); + coeffs_n[7] = (CT(11)-CT(8)*ep)/CT(3960); + coeffs_n[8] = -CT(1)/CT(495); + coeffs_n[9] = (ep*(CT(16)*ep-CT(22))+CT(33))/CT(69300); + coeffs_n[10] = (CT(8)*ep-CT(11))/CT(19800); + coeffs_n[11] = CT(1)/CT(1925); + coeffs_n[12] = (CT(11)-CT(8)*ep)/CT(194040); + coeffs_n[13] = -CT(1)/CT(10780); + coeffs_n[14] = CT(1)/CT(124740); + break; + case 5: + coeffs_n[0] = (ep*(ep*(ep*((CT(832)-CT(640)*ep)*ep-CT(1144))+CT(1716))-CT(3003))+CT(30030))/CT(45045); + coeffs_n[1] = (ep*(ep*((CT(832)-CT(640)*ep)*ep-CT(1144))+CT(1716))-CT(3003))/CT(60060); + coeffs_n[2] = (ep*((CT(208)-CT(160)*ep)*ep-CT(286))+CT(429))/CT(18018); + coeffs_n[3] = ((CT(104)-CT(80)*ep)*ep-CT(143))/CT(10296); + coeffs_n[4] = (CT(13)-CT(10)*ep)/CT(1430); + coeffs_n[5] = -CT(1)/CT(156); + coeffs_n[6] = (ep*(ep*(ep*(CT(640)*ep-CT(832))+CT(1144))-CT(1716))+CT(3003))/CT(540540); + coeffs_n[7] = (ep*(ep*(CT(160)*ep-CT(208))+CT(286))-CT(429))/CT(108108); + coeffs_n[8] = (ep*(CT(80)*ep-CT(104))+CT(143))/CT(51480); + coeffs_n[9] = (CT(10)*ep-CT(13))/CT(6435); + coeffs_n[10] = CT(5)/CT(3276); + coeffs_n[11] = (ep*((CT(208)-CT(160)*ep)*ep-CT(286))+CT(429))/CT(900900); + coeffs_n[12] = ((CT(104)-CT(80)*ep)*ep-CT(143))/CT(257400); + coeffs_n[13] = (CT(13)-CT(10)*ep)/CT(25025); + coeffs_n[14] = -CT(1)/CT(2184); + coeffs_n[15] = (ep*(CT(80)*ep-CT(104))+CT(143))/CT(2522520); + coeffs_n[16] = (CT(10)*ep-CT(13))/CT(140140); + coeffs_n[17] = CT(5)/CT(45864); + coeffs_n[18] = (CT(13)-CT(10)*ep)/CT(1621620); + coeffs_n[19] = -CT(1)/CT(58968); + coeffs_n[20] = CT(1)/CT(792792); + break; + } + } + + /* + Given the set of coefficients coeffs1[] evaluate on var2 and return + the set of coefficients coeffs2[] + */ + static inline void evaluate_coeffs_var2(CT var2, + CT coeffs1[], + CT coeffs2[]){ + std::size_t begin(0), end(0); + for(std::size_t i = 0; i <= SeriesOrder; i++){ + end = begin + SeriesOrder + 1 - i; + coeffs2[i] = ((i==0) ? CT(1) : pow(var2,int(i))) + * horner_evaluate(var2, coeffs1 + begin, coeffs1 + end); + begin = end; + } + } + + /* + Compute the spherical excess of a geodesic (or shperical) segment + */ + template < + bool LongSegment, + typename PointOfSegment + > + static inline CT spherical(PointOfSegment const& p1, + PointOfSegment const& p2) + { + CT excess; + + if(LongSegment) // not for segments parallel to equator + { + CT cbet1 = cos(geometry::get_as_radian<1>(p1)); + CT sbet1 = sin(geometry::get_as_radian<1>(p1)); + CT cbet2 = cos(geometry::get_as_radian<1>(p2)); + CT sbet2 = sin(geometry::get_as_radian<1>(p2)); + + CT omg12 = geometry::get_as_radian<0>(p1) + - geometry::get_as_radian<0>(p2); + CT comg12 = cos(omg12); + CT somg12 = sin(omg12); + + CT alp1 = atan2(cbet1 * sbet2 + - sbet1 * cbet2 * comg12, + cbet2 * somg12); + + CT alp2 = atan2(cbet1 * sbet2 * comg12 + - sbet1 * cbet2, + cbet1 * somg12); + + excess = alp2 - alp1; + + } else { + + // Trapezoidal formula + + CT tan_lat1 = + tan(geometry::get_as_radian<1>(p1) / 2.0); + CT tan_lat2 = + tan(geometry::get_as_radian<1>(p2) / 2.0); + + excess = CT(2.0) + * atan(((tan_lat1 + tan_lat2) / (CT(1) + tan_lat1 * tan_lat2)) + * tan((geometry::get_as_radian<0>(p2) + - geometry::get_as_radian<0>(p1)) / 2)); + } + + return excess; + } + + struct return_type_ellipsoidal + { + return_type_ellipsoidal() + : spherical_term(0), + ellipsoidal_term(0) + {} + + CT spherical_term; + CT ellipsoidal_term; + }; + + /* + Compute the ellipsoidal correction of a geodesic (or shperical) segment + */ + template < + template class Inverse, + //typename AzimuthStrategy, + typename PointOfSegment, + typename SpheroidConst + > + static inline return_type_ellipsoidal ellipsoidal(PointOfSegment const& p1, + PointOfSegment const& p2, + SpheroidConst spheroid_const) + { + return_type_ellipsoidal result; + + // Azimuth Approximation + + typedef Inverse inverse_type; + typedef typename inverse_type::result_type inverse_result; + + inverse_result i_res = inverse_type::apply(get_as_radian<0>(p1), + get_as_radian<1>(p1), + get_as_radian<0>(p2), + get_as_radian<1>(p2), + spheroid_const.m_spheroid); + + CT alp1 = i_res.azimuth; + CT alp2 = i_res.reverse_azimuth; + + // Constants + + CT const ep = spheroid_const.m_ep; + CT const f = geometry::detail::flattening(spheroid_const.m_spheroid); + CT const one_minus_f = CT(1) - f; + std::size_t const series_order_plus_one = SeriesOrder + 1; + std::size_t const series_order_plus_two = SeriesOrder + 2; + + // Basic trigonometric computations + + CT tan_bet1 = tan(get_as_radian<1>(p1)) * one_minus_f; + CT tan_bet2 = tan(get_as_radian<1>(p2)) * one_minus_f; + CT cos_bet1 = cos(atan(tan_bet1)); + CT cos_bet2 = cos(atan(tan_bet2)); + CT sin_bet1 = tan_bet1 * cos_bet1; + CT sin_bet2 = tan_bet2 * cos_bet2; + CT sin_alp1 = sin(alp1); + CT cos_alp1 = cos(alp1); + CT cos_alp2 = cos(alp2); + CT sin_alp0 = sin_alp1 * cos_bet1; + + // Spherical term computation + + CT sin_omg1 = sin_alp0 * sin_bet1; + CT cos_omg1 = cos_alp1 * cos_bet1; + CT sin_omg2 = sin_alp0 * sin_bet2; + CT cos_omg2 = cos_alp2 * cos_bet2; + CT cos_omg12 = cos_omg1 * cos_omg2 + sin_omg1 * sin_omg2; + CT excess; + + bool meridian = get<0>(p2) - get<0>(p1) == CT(0) + || get<1>(p1) == CT(90) || get<1>(p1) == -CT(90) + || get<1>(p2) == CT(90) || get<1>(p2) == -CT(90); + + if (!meridian && cos_omg12 > -CT(0.7) + && sin_bet2 - sin_bet1 < CT(1.75)) // short segment + { + CT sin_omg12 = cos_omg1 * sin_omg2 - sin_omg1 * cos_omg2; + normalize(sin_omg12, cos_omg12); + + CT cos_omg12p1 = CT(1) + cos_omg12; + CT cos_bet1p1 = CT(1) + cos_bet1; + CT cos_bet2p1 = CT(1) + cos_bet2; + excess = CT(2) * atan2(sin_omg12 * (sin_bet1 * cos_bet2p1 + sin_bet2 * cos_bet1p1), + cos_omg12p1 * (sin_bet1 * sin_bet2 + cos_bet1p1 * cos_bet2p1)); + } + else + { + /* + CT sin_alp2 = sin(alp2); + CT sin_alp12 = sin_alp2 * cos_alp1 - cos_alp2 * sin_alp1; + CT cos_alp12 = cos_alp2 * cos_alp1 + sin_alp2 * sin_alp1; + excess = atan2(sin_alp12, cos_alp12); + */ + excess = alp2 - alp1; + } + + result.spherical_term = excess; + + // Ellipsoidal term computation (uses integral approximation) + + CT cos_alp0 = math::sqrt(CT(1) - math::sqr(sin_alp0)); + CT cos_sig1 = cos_alp1 * cos_bet1; + CT cos_sig2 = cos_alp2 * cos_bet2; + CT sin_sig1 = sin_bet1; + CT sin_sig2 = sin_bet2; + + normalize(sin_sig1, cos_sig1); + normalize(sin_sig2, cos_sig2); + + CT coeffs[SeriesOrder + 1]; + const std::size_t coeffs_var_size = (series_order_plus_two + * series_order_plus_one) / 2; + CT coeffs_var[coeffs_var_size]; + + if(ExpandEpsN){ // expand by eps and n + + CT k2 = math::sqr(ep * cos_alp0); + CT sqrt_k2_plus_one = math::sqrt(CT(1) + k2); + CT eps = (sqrt_k2_plus_one - CT(1)) / (sqrt_k2_plus_one + CT(1)); + CT n = f / (CT(2) - f); + + // Generate and evaluate the polynomials on n + // to get the series coefficients (that depend on eps) + evaluate_coeffs_n(n, coeffs_var); + + // Generate and evaluate the polynomials on eps (i.e. var2 = eps) + // to get the final series coefficients + evaluate_coeffs_var2(eps, coeffs_var, coeffs); + + }else{ // expand by k2 and ep + + CT k2 = math::sqr(ep * cos_alp0); + CT ep2 = math::sqr(ep); + + // Generate and evaluate the polynomials on ep2 + evaluate_coeffs_ep(ep2, coeffs_var); + + // Generate and evaluate the polynomials on k2 (i.e. var2 = k2) + evaluate_coeffs_var2(k2, coeffs_var, coeffs); + + } + + // Evaluate the trigonometric sum + CT I12 = clenshaw_sum(cos_sig2, coeffs, coeffs + series_order_plus_one) + - clenshaw_sum(cos_sig1, coeffs, coeffs + series_order_plus_one); + + // The part of the ellipsodal correction that depends on + // point coordinates + result.ellipsoidal_term = cos_alp0 * sin_alp0 * I12; + + return result; + } + + // Keep track whenever a segment crosses the prime meridian + // First normalize to [0,360) + template + static inline int crosses_prime_meridian(PointOfSegment const& p1, + PointOfSegment const& p2, + StateType& state) + { + CT const pi + = geometry::math::pi(); + CT const two_pi + = geometry::math::two_pi(); + + CT p1_lon = get_as_radian<0>(p1) + - ( floor( get_as_radian<0>(p1) / two_pi ) + * two_pi ); + CT p2_lon = get_as_radian<0>(p2) + - ( floor( get_as_radian<0>(p2) / two_pi ) + * two_pi ); + + CT max_lon = (std::max)(p1_lon, p2_lon); + CT min_lon = (std::min)(p1_lon, p2_lon); + + if(max_lon > pi && min_lon < pi && max_lon - min_lon > pi) + { + state.m_crosses_prime_meridian++; + } + + return state.m_crosses_prime_meridian; + } + +}; + +}}} // namespace boost::geometry::formula + + +#endif // BOOST_GEOMETRY_FORMULAS_AREA_FORMULAS_HPP diff --git a/include/boost/geometry/formulas/spherical.hpp b/include/boost/geometry/formulas/spherical.hpp index 2195bbbe1..23269d644 100644 --- a/include/boost/geometry/formulas/spherical.hpp +++ b/include/boost/geometry/formulas/spherical.hpp @@ -1,6 +1,7 @@ // Boost.Geometry // Copyright (c) 2016, 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, @@ -27,6 +28,18 @@ namespace boost { namespace geometry { namespace formula { +template +struct result_spherical +{ + result_spherical() + : azimuth(0) + , reverse_azimuth(0) + {} + + T azimuth; + T reverse_azimuth; +}; + template static inline Point3d sph_to_cart3d(PointSph const& point_sph) { @@ -89,6 +102,47 @@ static inline int sph_side_value(Point3d1 const& norm, Point3d2 const& pt) : -1; // d < 0 } +template +static inline result_spherical spherical_azimuth(T1 const& lon1, + T1 const& lat1, + T2 const& lon2, + T2 const& lat2) +{ + typedef result_spherical result_type; + result_type result; + + // http://williams.best.vwh.net/avform.htm#Crs + // https://en.wikipedia.org/wiki/Great-circle_navigation + CT dlon = lon2 - lon1; + CT cos_dlon = cos(dlon); + CT sin_dlon = sin(dlon); + CT cos_lat1 = cos(lat1); + CT cos_lat2 = cos(lat2); + CT sin_lat1 = sin(lat1); + CT sin_lat2 = sin(lat2); + + // An optimization which should kick in often for Boxes + //if ( math::equals(dlon, ReturnType(0)) ) + //if ( get<0>(p1) == get<0>(p2) ) + //{ + // return - sin(get_as_radian<1>(p1)) * cos_p2lat); + //} + + // "An alternative formula, not requiring the pre-computation of d" + // In the formula below dlon is used as "d" + result.azimuth = atan2(sin_dlon * cos_lat2, + cos_lat1 * sin_lat2 - sin_lat1 * cos_lat2 * cos_dlon); + + if (ReverseAzimuth) + { + result.reverse_azimuth = + atan2(sin_dlon * cos_lat1, + sin_lat2 * cos_lat1 * cos_dlon - cos_lat2 * sin_lat1); + } + + return result; +} + } // namespace formula }} // namespace boost::geometry diff --git a/include/boost/geometry/formulas/vertex_latitude.hpp b/include/boost/geometry/formulas/vertex_latitude.hpp new file mode 100644 index 000000000..1d4c24a82 --- /dev/null +++ b/include/boost/geometry/formulas/vertex_latitude.hpp @@ -0,0 +1,148 @@ +// Boost.Geometry + +// Copyright (c) 2016-2017 Oracle and/or its affiliates. + +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// 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_MAXIMUM_LATITUDE_HPP +#define BOOST_GEOMETRY_FORMULAS_MAXIMUM_LATITUDE_HPP + +#include +#include +#include +#include + +namespace boost { namespace geometry { namespace formula +{ + +/*! +\brief Algorithm to compute the vertex latitude of a geodesic segment. Vertex is +a point on the geodesic that maximizes (or minimizes) the latitude. +\author See + [Wood96] Wood - Vertex Latitudes on Ellipsoid Geodesics, SIAM Rev., 38(4), + 637–644, 1996 +*/ + +template +class vertex_latitude_on_sphere +{ + +public: + template + static inline CT apply(T1 const& lat1, + T2 const& alp1) + { + return std::acos( math::abs(cos(lat1) * sin(alp1)) ); + } +}; + +template +class vertex_latitude_on_spheroid +{ + +public: +/* + * formula based on paper + * [Wood96] Wood - Vertex Latitudes on Ellipsoid Geodesics, SIAM Rev., 38(4), + * 637–644, 1996 + template + static inline CT apply(T1 const& lat1, + T2 const& alp1, + Spheroid const& spheroid) + { + CT const f = detail::flattening(spheroid); + + CT const e2 = f * (CT(2) - f); + CT const sin_alp1 = sin(alp1); + CT const sin2_lat1 = math::sqr(sin(lat1)); + CT const cos2_lat1 = CT(1) - sin2_lat1; + + CT const e2_sin2 = CT(1) - e2 * sin2_lat1; + CT const cos2_sin2 = cos2_lat1 * math::sqr(sin_alp1); + CT const vertex_lat = std::asin( math::sqrt((e2_sin2 - cos2_sin2) + / (e2_sin2 - e2 * cos2_sin2))); + return vertex_lat; + } +*/ + + // simpler formula based on Clairaut relation for spheroids + template + static inline CT apply(T1 const& lat1, + T2 const& alp1, + Spheroid const& spheroid) + { + CT const f = detail::flattening(spheroid); + + CT const one_minus_f = (CT(1) - f); + + //get the reduced latitude + CT const bet1 = atan( one_minus_f * tan(lat1) ); + + //apply Clairaut relation + CT const betv = vertex_latitude_on_sphere::apply(bet1, alp1); + + //return the spheroid latitude + return atan( tan(betv) / one_minus_f ); + } + + /* + template + inline static void sign_adjustment(CT lat1, CT lat2, CT vertex_lat, T& vrt_result) + { + // signbit returns a non-zero value (true) if the sign is negative; + // and zero (false) otherwise. + bool sign = std::signbit(std::abs(lat1) > std::abs(lat2) ? lat1 : lat2); + + vrt_result.north = sign ? std::max(lat1, lat2) : vertex_lat; + vrt_result.south = sign ? vertex_lat * CT(-1) : std::min(lat1, lat2); + } + + template + inline static bool vertex_on_segment(CT alp1, CT alp2, CT lat1, CT lat2, T& vrt_result) + { + CT const half_pi = math::pi() / CT(2); + + // if the segment does not contain the vertex of the geodesic + // then return the endpoint of max (min) latitude + if ((alp1 < half_pi && alp2 < half_pi) + || (alp1 > half_pi && alp2 > half_pi)) + { + vrt_result.north = std::max(lat1, lat2); + vrt_result.south = std::min(lat1, lat2); + return false; + } + return true; + } + */ +}; + + +template +struct vertex_latitude +{ + BOOST_MPL_ASSERT_MSG + ( + false, NOT_IMPLEMENTED_FOR_THIS_COORDINATE_SYSTEM, (types) + ); + +}; + +template +struct vertex_latitude + : vertex_latitude_on_sphere +{}; + +template +struct vertex_latitude + : vertex_latitude_on_spheroid +{}; + + +}}} // namespace boost::geometry::formula + +#endif // BOOST_GEOMETRY_FORMULAS_MAXIMUM_LATITUDE_HPP diff --git a/include/boost/geometry/index/detail/algorithms/nth_element.hpp b/include/boost/geometry/index/detail/algorithms/nth_element.hpp new file mode 100644 index 000000000..201180ae3 --- /dev/null +++ b/include/boost/geometry/index/detail/algorithms/nth_element.hpp @@ -0,0 +1,62 @@ +// Boost.Geometry Index +// +// Copyright (c) 2017 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 +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_NTH_ELEMENT_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_NTH_ELEMENT_HPP + +#include + +namespace boost { namespace geometry { namespace index { namespace detail { + +// See https://svn.boost.org/trac/boost/ticket/12861 +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58800 +// https://gcc.gnu.org/develop.html#timeline +// 20120920 4.7.2 - no bug +// 20130322 4.8.0 - no bug +// 20130411 4.7.3 - no bug +// 20130531 4.8.1 - no bug +// 20131016 4.8.2 - bug +// 20140422 4.9.0 - fixed +// 20140522 4.8.3 - fixed +// 20140612 4.7.4 - fixed +// 20140716 4.9.1 - fixed +#if defined(__GLIBCXX__) && (__GLIBCXX__ == 20131016) + +#warning "std::nth_element replaced with std::sort, libstdc++ bug workaround."; + +template +void nth_element(RandomIt first, RandomIt , RandomIt last) +{ + std::sort(first, last); +} + +template +void nth_element(RandomIt first, RandomIt , RandomIt last, Compare comp) +{ + std::sort(first, last, comp); +} + +#else + +template +void nth_element(RandomIt first, RandomIt nth, RandomIt last) +{ + std::nth_element(first, nth, last); +} + +template +void nth_element(RandomIt first, RandomIt nth, RandomIt last, Compare comp) +{ + std::nth_element(first, nth, last, comp); +} + +#endif + +}}}} // namespace boost::geometry::index::detail + +#endif // BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_NTH_ELEMENT_HPP diff --git a/include/boost/geometry/index/detail/rtree/pack_create.hpp b/include/boost/geometry/index/detail/rtree/pack_create.hpp index d1491b8d4..2d3903a7b 100644 --- a/include/boost/geometry/index/detail/rtree/pack_create.hpp +++ b/include/boost/geometry/index/detail/rtree/pack_create.hpp @@ -2,7 +2,7 @@ // // R-tree initial packing // -// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2017 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 @@ -13,6 +13,7 @@ #include #include +#include #include @@ -67,7 +68,7 @@ struct nth_element_and_half_boxes { if ( I == dim_index ) { - std::nth_element(first, median, last, point_entries_comparer()); + index::detail::nth_element(first, median, last, point_entries_comparer()); geometry::convert(box, left); geometry::convert(box, right); diff --git a/include/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp b/include/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp index 7a96986a2..89697b594 100644 --- a/include/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp +++ b/include/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-2014 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2017 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 @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -112,7 +113,7 @@ private: first_n_children_count = overlap_cost_threshold; // rearrange by content_diff // in order to calculate nearly minimum overlap cost - std::nth_element(children_contents.begin(), children_contents.begin() + first_n_children_count, children_contents.end(), content_diff_less); + index::detail::nth_element(children_contents.begin(), children_contents.begin() + first_n_children_count, children_contents.end(), content_diff_less); } // calculate minimum or nearly minimum overlap cost diff --git a/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp b/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp index 8f270537f..187d37fac 100644 --- a/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp +++ b/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp @@ -2,7 +2,7 @@ // // R-tree R*-tree split algorithm implementation // -// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2017 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 @@ -12,8 +12,9 @@ #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_RSTAR_REDISTRIBUTE_ELEMENTS_HPP #include -#include #include +#include +#include #include @@ -122,8 +123,9 @@ struct choose_split_axis_and_index_for_corner // { // typename Elements::iterator f = elements_copy.begin() + index_first; // typename Elements::iterator l = elements_copy.begin() + index_last; -// std::nth_element(elements_copy.begin(), f, elements_copy.end(), elements_less); // MAY THROW, BASIC (copy) -// std::nth_element(f, l, elements_copy.end(), elements_less); // MAY THROW, BASIC (copy) +// // NOTE: for stdlibc++ shipped with gcc 4.8.2 std::nth_element is replaced with std::sort anyway +// index::detail::nth_element(elements_copy.begin(), f, elements_copy.end(), elements_less); // MAY THROW, BASIC (copy) +// index::detail::nth_element(f, l, elements_copy.end(), elements_less); // MAY THROW, BASIC (copy) // std::sort(f, l, elements_less); // MAY THROW, BASIC (copy) // } @@ -349,7 +351,7 @@ struct nth_element typedef typename tag::type indexable_tag; element_axis_corner_less less(tr); - std::nth_element(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy) + index::detail::nth_element(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy) } } }; diff --git a/include/boost/geometry/index/equal_to.hpp b/include/boost/geometry/index/equal_to.hpp index b0cf098f1..6b722a89f 100644 --- a/include/boost/geometry/index/equal_to.hpp +++ b/include/boost/geometry/index/equal_to.hpp @@ -1,6 +1,6 @@ // Boost.Geometry Index // -// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2016 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 @@ -42,6 +42,15 @@ struct equals } }; +template +struct equals +{ + inline static bool apply(const T * v1, const T * v2) + { + return v1 == v2; + } +}; + template struct tuple_equals { diff --git a/include/boost/geometry/index/parameters.hpp b/include/boost/geometry/index/parameters.hpp index 2b9490768..6a3a67c6c 100644 --- a/include/boost/geometry/index/parameters.hpp +++ b/include/boost/geometry/index/parameters.hpp @@ -11,8 +11,14 @@ #ifndef BOOST_GEOMETRY_INDEX_PARAMETERS_HPP #define BOOST_GEOMETRY_INDEX_PARAMETERS_HPP + #include +#include + +#include + + namespace boost { namespace geometry { namespace index { namespace detail { diff --git a/include/boost/geometry/io/wkt/read.hpp b/include/boost/geometry/io/wkt/read.hpp index 148a5769d..a6990329e 100644 --- a/include/boost/geometry/io/wkt/read.hpp +++ b/include/boost/geometry/io/wkt/read.hpp @@ -203,7 +203,7 @@ inline void check_end(Iterator& it, { if (it != end) { - throw read_wkt_exception("Too much tokens", it, end, wkt); + throw read_wkt_exception("Too many tokens", it, end, wkt); } } diff --git a/include/boost/geometry/policies/robustness/segment_ratio.hpp b/include/boost/geometry/policies/robustness/segment_ratio.hpp index f3dbabe70..9b313fdfa 100644 --- a/include/boost/geometry/policies/robustness/segment_ratio.hpp +++ b/include/boost/geometry/policies/robustness/segment_ratio.hpp @@ -145,11 +145,10 @@ public : m_approximation = m_denominator == 0 ? 0 - : boost::numeric_cast - ( - boost::numeric_cast(m_numerator) * scale() - / boost::numeric_cast(m_denominator) - ); + : ( + boost::numeric_cast(m_numerator) * scale() + / boost::numeric_cast(m_denominator) + ); } inline bool is_zero() const { return math::equals(m_numerator, 0); } @@ -187,7 +186,7 @@ public : return false; } - static fp_type const small_part_of_scale = scale() / 100.0; + static fp_type const small_part_of_scale = scale() / 100; return m_approximation < small_part_of_scale || m_approximation > scale() - small_part_of_scale; } @@ -236,7 +235,14 @@ public : private : - typedef typename promote_floating_point::type fp_type; + // NOTE: if this typedef is used then fp_type is non-fundamental type + // if Type is non-fundamental type + //typedef typename promote_floating_point::type fp_type; + + typedef typename boost::mpl::if_c + < + boost::is_float::value, Type, double + >::type fp_type; Type m_numerator; Type m_denominator; diff --git a/include/boost/geometry/strategies/agnostic/point_in_point.hpp b/include/boost/geometry/strategies/agnostic/point_in_point.hpp index e4f9bec4c..c6e2b6362 100644 --- a/include/boost/geometry/strategies/agnostic/point_in_point.hpp +++ b/include/boost/geometry/strategies/agnostic/point_in_point.hpp @@ -1,12 +1,13 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014 Oracle and/or its affiliates. +// Copyright (c) 2014-2017 Oracle and/or its affiliates. + +// Contributed and/or modified by 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_STRATEGY_AGNOSTIC_POINT_IN_POINT_HPP #define BOOST_GEOMETRY_STRATEGY_AGNOSTIC_POINT_IN_POINT_HPP @@ -41,41 +42,12 @@ struct point_in_point namespace services { -template -struct default_strategy +template +struct default_strategy { - typedef strategy::within::point_in_point type; + typedef strategy::within::point_in_point::type> type; }; -template -struct default_strategy -{ - typedef strategy::within::point_in_point type; -}; - -template -struct default_strategy -{ - typedef strategy::within::point_in_point type; -}; - -template -struct default_strategy -{ - typedef strategy::within::point_in_point::type> type; -}; - -template -struct default_strategy -{ - typedef strategy::within::point_in_point::type> type; -}; - -template -struct default_strategy -{ - typedef strategy::within::point_in_point::type> type; -}; } // namespace services @@ -85,45 +57,14 @@ struct default_strategy -struct default_strategy +template +struct default_strategy { - typedef strategy::within::point_in_point type; -}; - -template -struct default_strategy -{ - typedef strategy::within::point_in_point type; -}; - -template -struct default_strategy -{ - typedef strategy::within::point_in_point type; -}; - -template -struct default_strategy -{ - typedef strategy::within::point_in_point::type> type; -}; - -template -struct default_strategy -{ - typedef strategy::within::point_in_point::type> type; -}; - -template -struct default_strategy -{ - typedef strategy::within::point_in_point::type> type; + typedef strategy::within::point_in_point::type> type; }; }}} // namespace strategy::covered_by::services diff --git a/include/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp b/include/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp index 9e2ec2c4f..46278f012 100644 --- a/include/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp +++ b/include/boost/geometry/strategies/agnostic/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. -// Modifications copyright (c) 2013-2016 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2016, 2017. +// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -314,6 +314,7 @@ struct winding_calculate_count \ingroup strategies \tparam Point \tparam_point \tparam PointOfSegment \tparam_segment_point +\tparam SideStrategy Side strategy \tparam CalculationType \tparam_calculation \author Barend Gehrels \note The implementation is inspired by terralib http://www.terralib.org (LGPL) @@ -329,6 +330,10 @@ template < typename Point, typename PointOfSegment = Point, + typename SideStrategy = typename strategy::side::services::default_strategy + < + typename cs_tag::type + >::type, typename CalculationType = void > class winding @@ -339,14 +344,7 @@ class winding PointOfSegment, CalculationType >::type calculation_type; - - - typedef typename strategy::side::services::default_strategy - < - typename cs_tag::type - >::type strategy_side_type; - - + /*! subclass to keep state */ class counter { @@ -371,7 +369,6 @@ class winding }; - static inline int check_segment(Point const& point, PointOfSegment const& seg1, PointOfSegment const& seg2, counter& state, bool& eq1, bool& eq2) @@ -390,16 +387,22 @@ class winding } -public : +public: + winding() + {} + + winding(SideStrategy const& side_strategy) + : m_side_strategy(side_strategy) + {} // Typedefs and static methods to fulfill the concept typedef Point point_type; typedef PointOfSegment segment_point_type; typedef counter state_type; - static inline bool apply(Point const& point, - PointOfSegment const& s1, PointOfSegment const& s2, - counter& state) + inline bool apply(Point const& point, + PointOfSegment const& s1, PointOfSegment const& s2, + counter& state) const { typedef typename cs_tag::type cs_t; @@ -418,7 +421,7 @@ public : else // count == 2 || count == -2 { // 1 left, -1 right - side = strategy_side_type::apply(s1, s2, point); + side = m_side_strategy.apply(s1, s2, point); } if (side == 0) @@ -445,6 +448,9 @@ public : { return state.code(); } + +private: + SideStrategy m_side_strategy; }; @@ -453,29 +459,26 @@ public : namespace services { -// Register using "areal_tag" for ring, polygon, multi-polygon -template -struct default_strategy -{ - typedef winding::type> type; -}; - -template -struct default_strategy -{ - typedef winding::type> type; -}; - -// TODO: use linear_tag and pointlike_tag the same way how areal_tag is used - template -struct default_strategy +struct default_strategy { typedef winding::type> type; }; template -struct default_strategy +struct default_strategy +{ + typedef winding::type> type; +}; + +template +struct default_strategy +{ + typedef winding::type> type; +}; + +template +struct default_strategy { typedef winding::type> type; }; @@ -488,34 +491,30 @@ struct default_strategy -struct default_strategy -{ - typedef strategy::within::winding::type> type; -}; - -template -struct default_strategy -{ - typedef strategy::within::winding::type> type; -}; - -// TODO: use linear_tag and pointlike_tag the same way how areal_tag is used - template -struct default_strategy +struct default_strategy { typedef strategy::within::winding::type> type; }; template -struct default_strategy +struct default_strategy +{ + typedef strategy::within::winding::type> type; +}; + +template +struct default_strategy +{ + typedef strategy::within::winding::type> type; +}; + +template +struct default_strategy { typedef strategy::within::winding::type> type; }; diff --git a/include/boost/geometry/strategies/agnostic/relate.hpp b/include/boost/geometry/strategies/agnostic/relate.hpp deleted file mode 100644 index 676207694..000000000 --- a/include/boost/geometry/strategies/agnostic/relate.hpp +++ /dev/null @@ -1,122 +0,0 @@ -// Boost.Geometry (aka GGL, Generic Geometry Library) - -// Copyright (c) 2014-2015 Oracle and/or its affiliates. - -// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle - -// Use, modification and distribution is subject to the Boost Software License, -// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_GEOMETRY_STRATEGY_AGNOSTIC_RELATE_HPP -#define BOOST_GEOMETRY_STRATEGY_AGNOSTIC_RELATE_HPP - -#include - - -namespace boost { namespace geometry -{ - -namespace strategy { namespace relate -{ - -template -struct relate -{ - static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2) - { - return geometry::relate(geometry1, geometry2, StaticMask()); - } -}; - -} // namespace relate - -namespace within -{ - -#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS - -namespace services -{ - - -template -struct default_strategy -{ - typedef strategy::relate::relate - < - Geometry1, - Geometry2, - typename detail::de9im::static_mask_within_type - < - Geometry1, Geometry2 - >::type - > type; -}; - -template -struct default_strategy -{ - typedef strategy::relate::relate - < - Geometry1, - Geometry2, - typename detail::de9im::static_mask_within_type - < - Geometry1, Geometry2 - >::type - > type; -}; - - -} // namespace services - -#endif - - -}} // namespace strategy::within - - - -#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS -namespace strategy { namespace covered_by { namespace services -{ - - -template -struct default_strategy -{ - typedef strategy::relate::relate - < - Geometry1, - Geometry2, - typename detail::de9im::static_mask_covered_by_type - < - Geometry1, Geometry2 - >::type - > type; -}; - -template -struct default_strategy -{ - typedef strategy::relate::relate - < - Geometry1, - Geometry2, - typename detail::de9im::static_mask_covered_by_type - < - Geometry1, Geometry2 - >::type - > type; -}; - - -}}} // namespace strategy::covered_by::services -#endif - - -}} // namespace boost::geometry - - -#endif // BOOST_GEOMETRY_STRATEGY_AGNOSTIC_RELATE_HPP diff --git a/include/boost/geometry/strategies/azimuth.hpp b/include/boost/geometry/strategies/azimuth.hpp new file mode 100644 index 000000000..470882d6b --- /dev/null +++ b/include/boost/geometry/strategies/azimuth.hpp @@ -0,0 +1,42 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2016 Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fisikopoulos, 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_AZIMUTH_HPP +#define BOOST_GEOMETRY_STRATEGIES_AZIMUTH_HPP + +#include + +namespace boost { namespace geometry +{ + + +namespace strategy { namespace azimuth { namespace services +{ + +/*! + \brief Traits class binding a default azimuth strategy to a coordinate system + \ingroup azimuth + \tparam Tag tag of coordinate system +*/ +template +struct default_strategy +{ + BOOST_MPL_ASSERT_MSG + ( + false, NOT_IMPLEMENTED_FOR_THIS_CALCULATION_TYPE + , (types) + ); +}; + +}}} // namespace strategy::azimuth::services + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_AZIMUTH_HPP diff --git a/include/boost/geometry/strategies/cartesian/azimuth_cartesian.hpp b/include/boost/geometry/strategies/cartesian/azimuth_cartesian.hpp new file mode 100644 index 000000000..247c6cb33 --- /dev/null +++ b/include/boost/geometry/strategies/cartesian/azimuth_cartesian.hpp @@ -0,0 +1,48 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2016 Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fisikopoulos, 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_CARTESIAN_AZIMUTH_CARTESIAN_HPP +#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AZIMUTH_CARTESIAN_HPP + +#include + +namespace boost { namespace geometry +{ + +namespace strategy { namespace azimuth +{ + +template +< + typename CalculationType +> +class cartesian +{}; + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef strategy::azimuth::cartesian type; +}; + +} + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +}} // namespace strategy::azimuth + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AZIMUTH_CARTESIAN_HPP diff --git a/include/boost/geometry/strategies/cartesian/box_in_box.hpp b/include/boost/geometry/strategies/cartesian/box_in_box.hpp index 28a6f2933..4641aafcb 100644 --- a/include/boost/geometry/strategies/cartesian/box_in_box.hpp +++ b/include/boost/geometry/strategies/cartesian/box_in_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 2015, 2016. -// Modifications copyright (c) 2016, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2016, 2017. +// Modifications copyright (c) 2016-2017, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -238,10 +238,10 @@ namespace within { namespace services template struct default_strategy < + BoxContained, BoxContaining, box_tag, box_tag, - box_tag, areal_tag, - cartesian_tag, cartesian_tag, - BoxContained, BoxContaining + areal_tag, areal_tag, + cartesian_tag, cartesian_tag > { typedef within::box_in_box type; @@ -251,10 +251,10 @@ struct default_strategy template struct default_strategy < + BoxContained, BoxContaining, box_tag, box_tag, - box_tag, areal_tag, - spherical_tag, spherical_tag, - BoxContained, BoxContaining + areal_tag, areal_tag, + spherical_tag, spherical_tag > { typedef within::box_in_box type; @@ -269,10 +269,10 @@ namespace covered_by { namespace services template struct default_strategy < + BoxContained, BoxContaining, box_tag, box_tag, - box_tag, areal_tag, - cartesian_tag, cartesian_tag, - BoxContained, BoxContaining + areal_tag, areal_tag, + cartesian_tag, cartesian_tag > { typedef within::box_in_box @@ -286,10 +286,10 @@ struct default_strategy template struct default_strategy < + BoxContained, BoxContaining, box_tag, box_tag, - box_tag, areal_tag, - spherical_tag, spherical_tag, - BoxContained, BoxContaining + areal_tag, areal_tag, + spherical_tag, spherical_tag > { typedef within::box_in_box diff --git a/include/boost/geometry/strategies/cartesian/cart_intersect.hpp b/include/boost/geometry/strategies/cartesian/cart_intersect.hpp index 0cb5d7545..1f6f56d66 100644 --- a/include/boost/geometry/strategies/cartesian/cart_intersect.hpp +++ b/include/boost/geometry/strategies/cartesian/cart_intersect.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2014, 2016. -// Modifications copyright (c) 2014-2016, Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2016, 2017. +// Modifications copyright (c) 2014-2017, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -33,13 +33,14 @@ #include #include -// Temporary / will be Strategy as template parameter -#include +#include #include - -#include +#include #include #include +#include +#include +#include #include #include @@ -61,10 +62,38 @@ namespace strategy { namespace intersection /*! \see http://mathworld.wolfram.com/Line-LineIntersection.html */ -template +template struct relate_cartesian_segments { - typedef typename Policy::return_type return_type; + typedef side::side_by_triangle side_strategy_type; + + static inline side_strategy_type get_side_strategy() + { + return side_strategy_type(); + } + + template + struct point_in_geometry_strategy + { + typedef strategy::within::winding + < + typename point_type::type, + typename point_type::type, + side_strategy_type, + CalculationType + > type; + }; + + template + static inline typename point_in_geometry_strategy::type + get_point_in_geometry_strategy() + { + typedef typename point_in_geometry_strategy + < + Geometry1, Geometry2 + >::type strategy_type; + return strategy_type(); + } template struct segment_intersection_info @@ -144,9 +173,16 @@ struct relate_cartesian_segments // Relate segments a and b - template - static inline return_type apply(Segment1 const& a, Segment2 const& b, - RobustPolicy const& robust_policy) + template + < + typename Segment1, + typename Segment2, + typename Policy, + typename RobustPolicy + > + static inline typename Policy::return_type + apply(Segment1 const& a, Segment2 const& b, + Policy const& policy, RobustPolicy const& robust_policy) { // type them all as in Segment1 - TODO reconsider this, most precise? typedef typename geometry::point_type::type point_type; @@ -169,18 +205,25 @@ struct relate_cartesian_segments geometry::recalculate(b0_rob, b0, robust_policy); geometry::recalculate(b1_rob, b1, robust_policy); - return apply(a, b, robust_policy, a0_rob, a1_rob, b0_rob, b1_rob); + return apply(a, b, policy, robust_policy, a0_rob, a1_rob, b0_rob, b1_rob); } // The main entry-routine, calculating intersections of segments a / b // NOTE: Robust* types may be the same as Segments' point types - template - static inline return_type apply(Segment1 const& a, Segment2 const& b, - RobustPolicy const& /*robust_policy*/, - RobustPoint1 const& robust_a1, RobustPoint1 const& robust_a2, - RobustPoint2 const& robust_b1, RobustPoint2 const& robust_b2) + template + < + typename Segment1, + typename Segment2, + typename Policy, + typename RobustPolicy, + typename RobustPoint1, + typename RobustPoint2 + > + static inline typename Policy::return_type + apply(Segment1 const& a, Segment2 const& b, + Policy const&, RobustPolicy const& /*robust_policy*/, + RobustPoint1 const& robust_a1, RobustPoint1 const& robust_a2, + RobustPoint2 const& robust_b1, RobustPoint2 const& robust_b2) { BOOST_CONCEPT_ASSERT( (concepts::ConstSegment) ); BOOST_CONCEPT_ASSERT( (concepts::ConstSegment) ); @@ -197,14 +240,9 @@ struct relate_cartesian_segments ; } - typedef typename select_calculation_type - ::type coordinate_type; - - typedef side::side_by_triangle side; - side_info sides; - sides.set<0>(side::apply(robust_b1, robust_b2, robust_a1), - side::apply(robust_b1, robust_b2, robust_a2)); + sides.set<0>(side_strategy_type::apply(robust_b1, robust_b2, robust_a1), + side_strategy_type::apply(robust_b1, robust_b2, robust_a2)); if (sides.same<0>()) { @@ -212,8 +250,8 @@ struct relate_cartesian_segments return Policy::disjoint(); } - sides.set<1>(side::apply(robust_a1, robust_a2, robust_b1), - side::apply(robust_a1, robust_a2, robust_b2)); + sides.set<1>(side_strategy_type::apply(robust_a1, robust_a2, robust_b1), + side_strategy_type::apply(robust_a1, robust_a2, robust_b2)); if (sides.same<1>()) { @@ -230,16 +268,16 @@ struct relate_cartesian_segments >::type robust_coordinate_type; typedef typename segment_ratio_type - < - typename geometry::point_type::type, // TODO: most precise point? - RobustPolicy - >::type ratio_type; + < + typename geometry::point_type::type, // TODO: most precise point? + RobustPolicy + >::type ratio_type; segment_intersection_info - < - coordinate_type, - ratio_type - > sinfo; + < + typename select_calculation_type::type, + ratio_type + > sinfo; sinfo.dx_a = get<1, 0>(a) - get<0, 0>(a); // distance in x-dir sinfo.dx_b = get<1, 0>(b) - get<0, 0>(b); @@ -303,14 +341,14 @@ struct relate_cartesian_segments if (collinear_use_first.first) { - return relate_collinear<0, ratio_type>(a, b, + return relate_collinear<0, Policy, ratio_type>(a, b, robust_a1, robust_a2, robust_b1, robust_b2, a_is_point, b_is_point); } else { // Y direction contains larger segments (maybe dx is zero) - return relate_collinear<1, ratio_type>(a, b, + return relate_collinear<1, Policy, ratio_type>(a, b, robust_a1, robust_a2, robust_b1, robust_b2, a_is_point, b_is_point); } @@ -358,33 +396,35 @@ private: template < std::size_t Dimension, + typename Policy, typename RatioType, typename Segment1, typename Segment2, typename RobustPoint1, typename RobustPoint2 > - static inline return_type relate_collinear(Segment1 const& a, - Segment2 const& b, - RobustPoint1 const& robust_a1, RobustPoint1 const& robust_a2, - RobustPoint2 const& robust_b1, RobustPoint2 const& robust_b2, - bool a_is_point, bool b_is_point) + static inline typename Policy::return_type + relate_collinear(Segment1 const& a, + Segment2 const& b, + RobustPoint1 const& robust_a1, RobustPoint1 const& robust_a2, + RobustPoint2 const& robust_b1, RobustPoint2 const& robust_b2, + bool a_is_point, bool b_is_point) { if (a_is_point) { - return relate_one_degenerate(a, + return relate_one_degenerate(a, get(robust_a1), get(robust_b1), get(robust_b2), true); } if (b_is_point) { - return relate_one_degenerate(b, + return relate_one_degenerate(b, get(robust_b1), get(robust_a1), get(robust_a2), false); } - return relate_collinear(a, b, + return relate_collinear(a, b, get(robust_a1), get(robust_a2), get(robust_b1), @@ -394,17 +434,17 @@ private: /// Relate segments known collinear template < + typename Policy, typename RatioType, typename Segment1, typename Segment2, typename RobustType1, typename RobustType2 > - static inline return_type relate_collinear(Segment1 const& a - , Segment2 const& b - , RobustType1 oa_1, RobustType1 oa_2 - , RobustType2 ob_1, RobustType2 ob_2 - ) + static inline typename Policy::return_type + relate_collinear(Segment1 const& a, Segment2 const& b, + RobustType1 oa_1, RobustType1 oa_2, + RobustType2 ob_1, RobustType2 ob_2) { // Calculate the ratios where a starts in b, b starts in a // a1--------->a2 (2..7) @@ -496,17 +536,16 @@ private: /// Relate segments where one is degenerate template < + typename Policy, typename RatioType, typename DegenerateSegment, typename RobustType1, typename RobustType2 > - static inline return_type relate_one_degenerate( - DegenerateSegment const& degenerate_segment - , RobustType1 d - , RobustType2 s1, RobustType2 s2 - , bool a_degenerate - ) + static inline typename Policy::return_type + relate_one_degenerate(DegenerateSegment const& degenerate_segment, + RobustType1 d, RobustType2 s1, RobustType2 s2, + bool a_degenerate) { // Calculate the ratios where ds starts in s // a1--------->a2 (2..6) @@ -546,10 +585,10 @@ private: namespace services { -template -struct default_strategy +template +struct default_strategy { - typedef relate_cartesian_segments type; + typedef relate_cartesian_segments type; }; } // namespace services @@ -558,6 +597,69 @@ struct default_strategy }} // namespace strategy::intersection +namespace strategy +{ + +namespace within { namespace services +{ + +template +struct default_strategy +{ + typedef strategy::intersection::relate_cartesian_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_cartesian_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_cartesian_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_cartesian_segments<> type; +}; + +}} // within::services + +namespace covered_by { namespace services +{ + +template +struct default_strategy +{ + typedef strategy::intersection::relate_cartesian_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_cartesian_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_cartesian_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_cartesian_segments<> type; +}; + +}} // within::services + +} // strategy + }} // namespace boost::geometry diff --git a/include/boost/geometry/strategies/cartesian/disjoint_segment_box.hpp b/include/boost/geometry/strategies/cartesian/disjoint_segment_box.hpp new file mode 100644 index 000000000..427080332 --- /dev/null +++ b/include/boost/geometry/strategies/cartesian/disjoint_segment_box.hpp @@ -0,0 +1,320 @@ +// Boost.Geometry + +// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2014 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2014 Mateusz Loskot, London, UK. +// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland. + +// This file was modified by Oracle on 2013-2017. +// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + +// 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_SEGMENT_BOX_HPP +#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISJOINT_SEGMENT_BOX_HPP + + +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#include + + +namespace boost { namespace geometry { namespace strategy { namespace disjoint +{ + +namespace detail +{ + +template +struct compute_tmin_tmax_per_dim +{ + template + static inline void apply(SegmentPoint const& p0, + SegmentPoint const& p1, + Box const& box, + RelativeDistance& ti_min, + RelativeDistance& ti_max, + RelativeDistance& diff) + { + typedef typename coordinate_type::type box_coordinate_type; + typedef typename coordinate_type + < + SegmentPoint + >::type point_coordinate_type; + + RelativeDistance c_p0 = boost::numeric_cast + < + point_coordinate_type + >( geometry::get(p0) ); + + RelativeDistance c_p1 = boost::numeric_cast + < + point_coordinate_type + >( geometry::get(p1) ); + + RelativeDistance c_b_min = boost::numeric_cast + < + box_coordinate_type + >( geometry::get(box) ); + + RelativeDistance c_b_max = boost::numeric_cast + < + box_coordinate_type + >( geometry::get(box) ); + + if ( geometry::get(p1) >= geometry::get(p0) ) + { + diff = c_p1 - c_p0; + ti_min = c_b_min - c_p0; + ti_max = c_b_max - c_p0; + } + else + { + diff = c_p0 - c_p1; + ti_min = c_p0 - c_b_max; + ti_max = c_p0 - c_b_min; + } + } +}; + + +template +< + typename RelativeDistance, + typename SegmentPoint, + typename Box, + std::size_t I, + std::size_t Dimension +> +struct disjoint_segment_box_impl +{ + template + static inline bool apply(SegmentPoint const& p0, + SegmentPoint const& p1, + Box const& box, + RelativeDistancePair& t_min, + RelativeDistancePair& t_max) + { + RelativeDistance ti_min, ti_max, diff; + + compute_tmin_tmax_per_dim::apply(p0, p1, box, ti_min, ti_max, diff); + + if ( geometry::math::equals(diff, 0) ) + { + if ( (geometry::math::equals(t_min.second, 0) + && t_min.first > ti_max) + || + (geometry::math::equals(t_max.second, 0) + && t_max.first < ti_min) + || + (math::sign(ti_min) * math::sign(ti_max) > 0) ) + { + return true; + } + } + + RelativeDistance t_min_x_diff = t_min.first * diff; + RelativeDistance t_max_x_diff = t_max.first * diff; + + if ( t_min_x_diff > ti_max * t_min.second + || t_max_x_diff < ti_min * t_max.second ) + { + return true; + } + + if ( ti_min * t_min.second > t_min_x_diff ) + { + t_min.first = ti_min; + t_min.second = diff; + } + if ( ti_max * t_max.second < t_max_x_diff ) + { + t_max.first = ti_max; + t_max.second = diff; + } + + if ( t_min.first > t_min.second || t_max.first < 0 ) + { + return true; + } + + return disjoint_segment_box_impl + < + RelativeDistance, + SegmentPoint, + Box, + I + 1, + Dimension + >::apply(p0, p1, box, t_min, t_max); + } +}; + + +template +< + typename RelativeDistance, + typename SegmentPoint, + typename Box, + std::size_t Dimension +> +struct disjoint_segment_box_impl + < + RelativeDistance, SegmentPoint, Box, 0, Dimension + > +{ + static inline bool apply(SegmentPoint const& p0, + SegmentPoint const& p1, + Box const& box) + { + std::pair t_min, t_max; + RelativeDistance diff; + + compute_tmin_tmax_per_dim<0>::apply(p0, p1, box, + t_min.first, t_max.first, diff); + + if ( geometry::math::equals(diff, 0) ) + { + if ( geometry::math::equals(t_min.first, 0) ) { t_min.first = -1; } + if ( geometry::math::equals(t_max.first, 0) ) { t_max.first = 1; } + + if (math::sign(t_min.first) * math::sign(t_max.first) > 0) + { + return true; + } + } + + if ( t_min.first > diff || t_max.first < 0 ) + { + return true; + } + + t_min.second = t_max.second = diff; + + return disjoint_segment_box_impl + < + RelativeDistance, SegmentPoint, Box, 1, Dimension + >::apply(p0, p1, box, t_min, t_max); + } +}; + + +template +< + typename RelativeDistance, + typename SegmentPoint, + typename Box, + std::size_t Dimension +> +struct disjoint_segment_box_impl + < + RelativeDistance, SegmentPoint, Box, Dimension, Dimension + > +{ + template + static inline bool apply(SegmentPoint const&, SegmentPoint const&, + Box const&, + RelativeDistancePair&, RelativeDistancePair&) + { + return false; + } +}; + +} // namespace detail + +// NOTE: This may be temporary place for this or corresponding strategy +// It seems to be more appropriate to implement the opposite of it +// e.g. intersection::segment_box because in disjoint() algorithm +// other strategies that are used are intersection and covered_by strategies. +struct segment_box +{ + template + struct point_in_geometry_strategy + : services::default_strategy + < + typename point_type::type, + Box + > + {}; + + template + static inline typename point_in_geometry_strategy::type + get_point_in_geometry_strategy() + { + typedef typename point_in_geometry_strategy::type strategy_type; + + return strategy_type(); + } + + template + static inline bool apply(Segment const& segment, Box const& box) + { + assert_dimension_equal(); + + typedef typename util::calculation_type::geometric::binary + < + Segment, Box, void + >::type relative_distance_type; + + typedef typename point_type::type segment_point_type; + segment_point_type p0, p1; + geometry::detail::assign_point_from_index<0>(segment, p0); + geometry::detail::assign_point_from_index<1>(segment, p1); + + return detail::disjoint_segment_box_impl + < + relative_distance_type, segment_point_type, Box, + 0, dimension::value + >::apply(p0, p1, box); + } +}; + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +namespace services +{ + +// Currently used in all coordinate systems + +template +struct default_strategy +{ + typedef disjoint::segment_box type; +}; + +template +struct default_strategy +{ + typedef disjoint::segment_box type; +}; + + +} // namespace services + + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}}}} // namespace boost::geometry::strategy::disjoint + + +#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISJOINT_SEGMENT_BOX_HPP diff --git a/include/boost/geometry/strategies/cartesian/envelope_segment.hpp b/include/boost/geometry/strategies/cartesian/envelope_segment.hpp new file mode 100644 index 000000000..63d1ff9ba --- /dev/null +++ b/include/boost/geometry/strategies/cartesian/envelope_segment.hpp @@ -0,0 +1,64 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2017 Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fisikopoulos, 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_CARTESIAN_ENVELOPE_SEGMENT_HPP +#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_SEGMENT_HPP + +#include +#include + +namespace boost { namespace geometry +{ + +namespace strategy { namespace envelope +{ + +template +class cartesian_segment +{ +public : + + template + inline void + apply(Point1 const& point1, Point2 const& point2, Box& box) const + { + geometry::detail::envelope::envelope_one_segment + < + 0, + dimension::value + > + ::apply(point1, + point2, + box, + strategy::envelope::cartesian_segment()); + } + +}; + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef strategy::envelope::cartesian_segment type; +}; + +} + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::envelope + +}} //namepsace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_SEGMENT_HPP diff --git a/include/boost/geometry/strategies/cartesian/point_in_box.hpp b/include/boost/geometry/strategies/cartesian/point_in_box.hpp index 227a98f2a..1c14125a6 100644 --- a/include/boost/geometry/strategies/cartesian/point_in_box.hpp +++ b/include/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-2016. -// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015-2017. +// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -219,10 +219,10 @@ namespace within { namespace services template struct default_strategy < + Point, Box, point_tag, box_tag, - point_tag, areal_tag, - cartesian_tag, cartesian_tag, - Point, Box + pointlike_tag, areal_tag, + cartesian_tag, cartesian_tag > { typedef within::point_in_box type; @@ -232,10 +232,10 @@ struct default_strategy template struct default_strategy < + Point, Box, point_tag, box_tag, - point_tag, areal_tag, - spherical_tag, spherical_tag, - Point, Box + pointlike_tag, areal_tag, + spherical_tag, spherical_tag > { typedef within::point_in_box type; @@ -252,10 +252,10 @@ namespace covered_by { namespace services template struct default_strategy < + Point, Box, point_tag, box_tag, - point_tag, areal_tag, - cartesian_tag, cartesian_tag, - Point, Box + pointlike_tag, areal_tag, + cartesian_tag, cartesian_tag > { typedef within::point_in_box @@ -269,10 +269,10 @@ struct default_strategy template struct default_strategy < + Point, Box, point_tag, box_tag, - point_tag, areal_tag, - spherical_tag, spherical_tag, - Point, Box + pointlike_tag, areal_tag, + spherical_tag, spherical_tag > { typedef within::point_in_box diff --git a/include/boost/geometry/strategies/covered_by.hpp b/include/boost/geometry/strategies/covered_by.hpp index a5aae7703..363e34b68 100644 --- a/include/boost/geometry/strategies/covered_by.hpp +++ b/include/boost/geometry/strategies/covered_by.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 2017. +// Modifications copyright (c) 2017, Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -16,6 +21,12 @@ #include +#include +#include +#include +#include +#include + namespace boost { namespace geometry { @@ -31,23 +42,39 @@ namespace services /*! \brief Traits class binding a covered_by determination strategy to a coordinate system \ingroup covered_by -\tparam TagContained tag (possibly casted) of point-type -\tparam TagContained tag (possibly casted) of (possibly) containing type -\tparam CsTagContained tag of coordinate system of point-type -\tparam CsTagContaining tag of coordinate system of (possibly) containing type -\tparam Geometry geometry-type of input (often point, or box) +\tparam GeometryContained geometry-type of input (possibly) contained type \tparam GeometryContaining geometry-type of input (possibly) containing type +\tparam TagContained casted tag of (possibly) contained type +\tparam TagContaining casted tag of (possibly) containing type +\tparam CsTagContained tag of coordinate system of (possibly) contained type +\tparam CsTagContaining tag of coordinate system of (possibly) containing type */ template < - typename TagContained, - typename TagContaining, - typename CastedTagContained, - typename CastedTagContaining, - typename CsTagContained, - typename CsTagContaining, typename GeometryContained, - typename GeometryContaining + typename GeometryContaining, + typename TagContained = typename tag::type, + typename TagContaining = typename tag::type, + typename CastedTagContained = typename tag_cast + < + typename tag::type, + pointlike_tag, linear_tag, polygonal_tag, areal_tag + >::type, + typename CastedTagContaining = typename tag_cast + < + typename tag::type, + pointlike_tag, linear_tag, polygonal_tag, areal_tag + >::type, + typename CsTagContained = typename tag_cast + < + typename cs_tag::type>::type, + spherical_tag + >::type, + typename CsTagContaining = typename tag_cast + < + typename cs_tag::type>::type, + spherical_tag + >::type > struct default_strategy { diff --git a/include/boost/geometry/strategies/disjoint.hpp b/include/boost/geometry/strategies/disjoint.hpp new file mode 100644 index 000000000..f844cd86a --- /dev/null +++ b/include/boost/geometry/strategies/disjoint.hpp @@ -0,0 +1,90 @@ +// Boost.Geometry + +// Copyright (c) 2017, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_STRATEGIES_DISJOINT_HPP +#define BOOST_GEOMETRY_STRATEGIES_DISJOINT_HPP + + +#include +#include + +#include +#include +#include + +#include +#include +#include + + +namespace boost { namespace geometry { namespace strategy { namespace disjoint +{ + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS +namespace services +{ + +template +< + typename Geometry1, + typename Geometry2, + typename Tag1 = typename geometry::tag::type, + typename Tag2 = typename geometry::tag::type, + int TopDim1 = geometry::topological_dimension::value, + int TopDim2 = geometry::topological_dimension::value +> +struct default_strategy + : relate::services::default_strategy + < + Geometry1, Geometry2 + > +{}; + +template +struct default_strategy + : strategy::covered_by::services::default_strategy +{}; + +template +struct default_strategy + : strategy::covered_by::services::default_strategy +{}; + +template +struct default_strategy + : strategy::covered_by::services::default_strategy + < + typename point_type::type, + Box + > +{}; + +template +struct default_strategy + : strategy::covered_by::services::default_strategy + < + typename point_type::type, + Box + > +{}; + +template +struct default_strategy +{ + // dummy strategy which will be ignored + typedef geometry::default_strategy type; +}; + +} // namespace services +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +}}}} // namespace boost::geometry::strategy::disjoint + + +#endif // BOOST_GEOMETRY_STRATEGIES_DISJOINT_HPP diff --git a/include/boost/geometry/strategies/envelope.hpp b/include/boost/geometry/strategies/envelope.hpp new file mode 100644 index 000000000..f3ab823ea --- /dev/null +++ b/include/boost/geometry/strategies/envelope.hpp @@ -0,0 +1,43 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2016 Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fisikopoulos, 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_ENVELOPE_HPP +#define BOOST_GEOMETRY_STRATEGIES_ENVELOPE_HPP + +#include + +namespace boost { namespace geometry +{ + + +namespace strategy { namespace envelope { namespace services +{ + +/*! + \brief Traits class binding a default envelope strategy to a coordinate system + \ingroup envelope + \tparam Tag tag of coordinate system +*/ +template +struct default_strategy +{ + BOOST_MPL_ASSERT_MSG + ( + false, NOT_IMPLEMENTED_FOR_THIS_CALCULATION_TYPE + , (types) + ); +}; + +}}} // namespace strategy::envelope::services + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_ENVELOPE_HPP + diff --git a/include/boost/geometry/strategies/geographic/area_geographic.hpp b/include/boost/geometry/strategies/geographic/area_geographic.hpp new file mode 100644 index 000000000..efa79df46 --- /dev/null +++ b/include/boost/geometry/strategies/geographic/area_geographic.hpp @@ -0,0 +1,213 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2016 Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fisikopoulos, 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_GEOGRAPHIC_AREA_HPP +#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_AREA_HPP + +#include +#include +#include + +namespace boost { namespace geometry +{ + +namespace strategy { namespace area +{ + +/*! +\brief Geographic area calculation by trapezoidal rule plus integral +approximation that gives the ellipsoidal correction + + +*/ + +template +< + typename PointOfSegment, + template class Inverse = + geometry::formula::thomas_inverse, + std::size_t SeriesOrder = 2, + bool ExpandEpsN = true, + bool LongSegment = false, + typename Spheroid = void, + typename CalculationType = void +> +class geographic +{ + + //Select default types in case they are not set + + typedef typename boost::mpl::if_c + < + boost::is_void::type::value, + typename select_most_precise + < + typename coordinate_type::type, + double + >::type, + CalculationType + >::type CT; +/* + typedef typename boost::mpl::if_c + < + boost::is_void::type::value, + typename geometry::formula::thomas_inverse + < + CT, + false, + true, + true + >, + Strategy + >::type AzimuthStrategy; +*/ + typedef typename boost::mpl::if_c + < + boost::is_void::type::value, + geometry::srs::spheroid, + Spheroid + >::type SpheroidType; + +protected : + struct spheroid_constants + { + SpheroidType m_spheroid; + CT const m_a2; // squared equatorial radius + CT const m_e2; // squared eccentricity + CT const m_ep2; // squared second eccentricity + CT const m_ep; // second eccentricity + CT const m_c2; // authalic radius + + inline spheroid_constants(SpheroidType spheroid) + : m_spheroid(spheroid) + , m_a2(math::sqr(get_radius<0>(spheroid))) + , m_e2(detail::flattening(spheroid) + * (CT(2.0) - CT(detail::flattening(spheroid)))) + , m_ep2(m_e2 / (CT(1.0) - m_e2)) + , m_ep(math::sqrt(m_ep2)) + , m_c2((m_a2 / CT(2.0)) + + ((math::sqr(get_radius<2>(spheroid)) * boost::math::atanh(math::sqrt(m_e2))) + / (CT(2.0) * math::sqrt(m_e2)))) + {} + }; + + struct area_sums + { + CT m_excess_sum; + CT m_correction_sum; + + // Keep track if encircles some pole + std::size_t m_crosses_prime_meridian; + + inline area_sums() + : m_excess_sum(0) + , m_correction_sum(0) + , m_crosses_prime_meridian(0) + {} + inline CT area(spheroid_constants spheroid_const) const + { + CT result; + + CT sum = spheroid_const.m_c2 * m_excess_sum + + spheroid_const.m_e2 * spheroid_const.m_a2 * m_correction_sum; + + // If encircles some pole + if (m_crosses_prime_meridian % 2 == 1) + { + std::size_t times_crosses_prime_meridian + = 1 + (m_crosses_prime_meridian / 2); + + result = CT(2.0) + * geometry::math::pi() + * spheroid_const.m_c2 + * CT(times_crosses_prime_meridian) + - geometry::math::abs(sum); + + if (geometry::math::sign(sum) == 1) + { + result = - result; + } + + } + else + { + result = sum; + } + + return result; + } + }; + +public : + typedef CT return_type; + typedef PointOfSegment segment_point_type; + typedef area_sums state_type; + + inline geographic(SpheroidType spheroid = SpheroidType()) + : spheroid_const(spheroid) + {} + + inline void apply(PointOfSegment const& p1, + PointOfSegment const& p2, + area_sums& state) const + { + + if (! geometry::math::equals(get<0>(p1), get<0>(p2))) + { + + typedef geometry::formula::area_formulas area_formulas; + + typename area_formulas::return_type_ellipsoidal result = + area_formulas::template ellipsoidal + (p1, p2, spheroid_const); + + state.m_excess_sum += result.spherical_term; + state.m_correction_sum += result.ellipsoidal_term; + + // Keep track whenever a segment crosses the prime meridian + geometry::formula::area_formulas + ::crosses_prime_meridian(p1, p2, state); + } + } + + inline return_type result(area_sums const& state) const + { + return state.area(spheroid_const); + } + +private: + spheroid_constants spheroid_const; + +}; + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + + +template +struct default_strategy +{ + typedef strategy::area::geographic type; +}; + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +} + +}} // namespace strategy::area + + + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_AREA_HPP diff --git a/include/boost/geometry/strategies/geographic/azimuth_geographic.hpp b/include/boost/geometry/strategies/geographic/azimuth_geographic.hpp new file mode 100644 index 000000000..18f7fcf35 --- /dev/null +++ b/include/boost/geometry/strategies/geographic/azimuth_geographic.hpp @@ -0,0 +1,90 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2016-2017 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 +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_AZIMUTH_HPP +#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_AZIMUTH_HPP + +#include + +#include + +namespace boost { namespace geometry +{ + +namespace strategy { namespace azimuth +{ + +template +< + typename CalculationType, + typename Spheroid = geometry::srs::spheroid, + template class Inverse = + geometry::formula::thomas_inverse +> +class geographic +{ +public : + + typedef Spheroid model_type; + + inline geographic() + : m_spheroid() + {} + + explicit inline geographic(Spheroid const& spheroid) + : m_spheroid(spheroid) + {} + + inline model_type const& model() const + { + return m_spheroid; + } + + inline void apply(CalculationType const& lon1_rad, + CalculationType const& lat1_rad, + CalculationType const& lon2_rad, + CalculationType const& lat2_rad, + CalculationType& a1, + CalculationType& a2) const + { + typedef Inverse inverse_type; + typedef typename inverse_type::result_type inverse_result; + inverse_result i_res = inverse_type::apply(lon1_rad, lat1_rad, + lon2_rad, lat2_rad, + m_spheroid); + a1 = i_res.azimuth; + a2 = i_res.reverse_azimuth; + } + +private : + Spheroid m_spheroid; +}; + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef strategy::azimuth::geographic type; +}; + +} + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +}} // namespace strategy::azimuth + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_AZIMUTH_HPP diff --git a/include/boost/geometry/strategies/geographic/envelope_segment.hpp b/include/boost/geometry/strategies/geographic/envelope_segment.hpp new file mode 100644 index 000000000..3d7b3cb9e --- /dev/null +++ b/include/boost/geometry/strategies/geographic/envelope_segment.hpp @@ -0,0 +1,96 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2017 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 +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_ENVELOPE_SEGMENT_HPP +#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_ENVELOPE_SEGMENT_HPP + +#include +#include +#include +#include + +namespace boost { namespace geometry +{ + +namespace strategy { namespace envelope +{ + +template +< + typename CalculationType, + typename Spheroid = geometry::srs::spheroid, + template class Inverse = + geometry::formula::thomas_inverse +> +class geographic_segment +{ +public: + typedef Spheroid model_type; + + inline geographic_segment() + : m_spheroid() + {} + + explicit inline geographic_segment(Spheroid const& spheroid) + : m_spheroid(spheroid) + {} + + template + inline void apply(Point1 const& point1, Point2 const& point2, Box& box) const + { + Point1 p1_normalized = detail::return_normalized(point1); + Point2 p2_normalized = detail::return_normalized(point2); + + geometry::strategy::azimuth::geographic + < + CalculationType, + Spheroid, + Inverse + > azimuth_geographic(m_spheroid); + + typedef typename coordinate_system::type::units units_type; + + detail::envelope::envelope_segment_impl + < + geographic_tag + >::template apply(geometry::get<0>(p1_normalized), + geometry::get<1>(p1_normalized), + geometry::get<0>(p2_normalized), + geometry::get<1>(p2_normalized), + box, + azimuth_geographic); + + } + +private: + Spheroid m_spheroid; +}; + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef strategy::envelope::geographic_segment type; +}; + +} + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::envelope + +}} //namepsace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_ENVELOPE_SEGMENT_HPP diff --git a/include/boost/geometry/strategies/intersection.hpp b/include/boost/geometry/strategies/intersection.hpp index f51c5cb20..e5662c9e4 100644 --- a/include/boost/geometry/strategies/intersection.hpp +++ b/include/boost/geometry/strategies/intersection.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2016, Oracle and/or its affiliates. +// Copyright (c) 2016-2017, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -30,10 +30,9 @@ namespace services \brief Traits class binding a segments intersection strategy to a coordinate system \ingroup util \tparam CSTag tag of coordinate system of point-type -\tparam Policy intersection policy \tparam CalculationType \tparam_calculation */ -template +template struct default_strategy { BOOST_MPL_ASSERT_MSG diff --git a/include/boost/geometry/strategies/intersection_strategies.hpp b/include/boost/geometry/strategies/intersection_strategies.hpp index 0452c4692..3b836ea51 100644 --- a/include/boost/geometry/strategies/intersection_strategies.hpp +++ b/include/boost/geometry/strategies/intersection_strategies.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-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, 2017. +// Modifications copyright (c) 2016-2017, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -70,17 +70,18 @@ private : > ip_type; public: + typedef policies::relate::segments_tupled + < + policies::relate::segments_intersection_points + < + ip_type + > , + policies::relate::segments_direction + > intersection_policy_type; + typedef typename strategy::intersection::services::default_strategy < Tag, - policies::relate::segments_tupled - < - policies::relate::segments_intersection_points - < - ip_type - > , - policies::relate::segments_direction - >, CalculationType >::type segment_intersection_strategy_type; diff --git a/include/boost/geometry/strategies/relate.hpp b/include/boost/geometry/strategies/relate.hpp new file mode 100644 index 000000000..ffeed7895 --- /dev/null +++ b/include/boost/geometry/strategies/relate.hpp @@ -0,0 +1,177 @@ +// Boost.Geometry + +// Copyright (c) 2017, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_STRATEGIES_RELATE_HPP +#define BOOST_GEOMETRY_STRATEGIES_RELATE_HPP + + +#include +#include + +#include +#include +#include + +#include +#include +#include + + +namespace boost { namespace geometry +{ + +namespace strategy +{ + +namespace point_in_geometry +{ + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS +namespace services +{ + +template +< + typename Point, + typename Geometry, + typename Tag1 = typename tag::type, + typename Tag2 = typename tag::type +> +struct default_strategy + : strategy::within::services::default_strategy + < + Point, + Geometry + > +{ + typedef typename default_strategy::type within_strategy_type; + + typedef typename strategy::covered_by::services::default_strategy + < + Point, + Geometry + >::type covered_by_strategy_type; + + static const bool same_strategies = boost::is_same::value; + BOOST_MPL_ASSERT_MSG((same_strategies), + DEFAULT_WITHIN_AND_COVERED_BY_STRATEGIES_NOT_COMPATIBLE, + (within_strategy_type, covered_by_strategy_type)); +}; + +template +struct default_strategy + : strategy::within::services::default_strategy +{}; + +template +struct default_strategy + : strategy::within::services::default_strategy +{}; + + +} // namespace services +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +} // namespace point_in_geometry + +namespace relate +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail +{ + +template +struct default_intersection_strategy + : strategy::intersection::services::default_strategy + < + typename cs_tag::type + > +{}; + +template +struct default_point_in_geometry_strategy + : point_in_geometry::services::default_strategy + < + typename point_type::type, + Geometry + > +{}; + +} // namespace detail +#endif // DOXYGEN_NO_DETAIL + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS +namespace services +{ + +template +< + typename Geometry1, + typename Geometry2, + int TopDim1 = geometry::topological_dimension::value, + int TopDim2 = geometry::topological_dimension::value +> +struct default_strategy +{ + BOOST_MPL_ASSERT_MSG + ( + false, NOT_IMPLEMENTED_FOR_THESE_TYPES + , (types) + ); +}; + +template +struct default_strategy + : detail::default_point_in_geometry_strategy +{}; + +template +struct default_strategy + : detail::default_point_in_geometry_strategy +{}; + +template +struct default_strategy + : detail::default_point_in_geometry_strategy +{}; + +template +struct default_strategy + : detail::default_intersection_strategy +{}; + +template +struct default_strategy + : detail::default_intersection_strategy +{}; + +template +struct default_strategy + : detail::default_intersection_strategy +{}; + +template +struct default_strategy + : detail::default_intersection_strategy +{}; + +} // namespace services +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +} // namespace relate + +} // namespace strategy + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_STRATEGIES_RELATE_HPP diff --git a/include/boost/geometry/strategies/spherical/area_huiller.hpp b/include/boost/geometry/strategies/spherical/area_huiller.hpp deleted file mode 100644 index 37d8d2012..000000000 --- a/include/boost/geometry/strategies/spherical/area_huiller.hpp +++ /dev/null @@ -1,214 +0,0 @@ -// Boost.Geometry (aka GGL, Generic Geometry Library) - -// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. - -// This file was modified by Oracle on 2015. -// Modifications copyright (c) 2015, Oracle and/or its affiliates. - -// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle -// 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_SPHERICAL_AREA_HUILLER_HPP -#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_AREA_HUILLER_HPP - - - -#include - -#include -#include - - -namespace boost { namespace geometry -{ - -namespace strategy { namespace area -{ - - - -/*! -\brief Area calculation by spherical excess / Huiller's formula -\ingroup strategies -\tparam PointOfSegment point type of segments of rings/polygons -\tparam CalculationType \tparam_calculation -\author Barend Gehrels. Adapted from: -- http://webdocs.cs.ualberta.ca/~graphics/books/GraphicsGems/gemsiv/sph_poly.c -- http://tog.acm.org/resources/GraphicsGems/gemsiv/sph_poly.c -- http://williams.best.vwh.net/avform.htm -\note The version in Graphics Gems IV (page 132-137) didn't account for -polygons crossing the 0 and 180 meridians. The fix for this algorithm -can be found in Graphics Gems V (pages 45-46). See: -- http://kysmykseka.net/koti/wizardry/Game%20Development/Programming/Graphics%20Gems%204.pdf -- http://kysmykseka.net/koti/wizardry/Game%20Development/Programming/Graphics%20Gems%205.pdf -\note This version works for convex and non-convex polygons, for 180 meridian -crossing polygons and for polygons with holes. However, some cases (especially -180 meridian cases) must still be checked. -\note The version which sums angles, which is often seen, doesn't handle non-convex -polygons correctly. -\note The version which sums longitudes, see http://hdl.handle.net/2014/40409, -is simple and works well in most cases but not in 180 meridian crossing cases. -This probably could be solved. - -\note This version is made for spherical equatorial coordinate systems - -\qbk{ - -[heading Example] -[area_with_strategy] -[area_with_strategy_output] - - -[heading See also] -[link geometry.reference.algorithms.area.area_2_with_strategy area (with strategy)] -} - -*/ -template -< - typename PointOfSegment, - typename CalculationType = void -> -class huiller -{ -typedef typename boost::mpl::if_c - < - boost::is_void::type::value, - typename select_most_precise - < - typename coordinate_type::type, - double - >::type, - CalculationType - >::type calculation_type; - -protected : - struct excess_sum - { - calculation_type sum; - - // Distances are calculated on unit sphere here - strategy::distance::haversine distance_over_unit_sphere; - - - inline excess_sum() - : sum(0) - , distance_over_unit_sphere(1) - {} - inline calculation_type area(calculation_type radius) const - { - return - sum * radius * radius; - } - }; - -public : - typedef calculation_type return_type; - typedef PointOfSegment segment_point_type; - typedef excess_sum state_type; - - inline huiller(calculation_type radius = 1.0) - : m_radius(radius) - {} - - inline void apply(PointOfSegment const& p1, - PointOfSegment const& p2, - excess_sum& state) const - { - if (! geometry::math::equals(get<0>(p1), get<0>(p2))) - { - calculation_type const half = 0.5; - calculation_type const two = 2.0; - calculation_type const four = 4.0; - calculation_type const pi - = geometry::math::pi(); - calculation_type const two_pi - = geometry::math::two_pi(); - calculation_type const half_pi - = geometry::math::half_pi(); - - // Distance p1 p2 - calculation_type a = state.distance_over_unit_sphere.apply(p1, p2); - - // Sides on unit sphere to south pole - calculation_type b = half_pi - geometry::get_as_radian<1>(p2); - calculation_type c = half_pi - geometry::get_as_radian<1>(p1); - - // Semi parameter - calculation_type s = half * (a + b + c); - - // E: spherical excess, using l'Huiller's formula - // [tg(e / 4)]2 = tg[s / 2] tg[(s-a) / 2] tg[(s-b) / 2] tg[(s-c) / 2] - calculation_type excess = four - * atan(geometry::math::sqrt(geometry::math::abs(tan(s / two) - * tan((s - a) / two) - * tan((s - b) / two) - * tan((s - c) / two)))); - - excess = geometry::math::abs(excess); - - // In right direction: positive, add area. In left direction: negative, subtract area. - // Longitude comparisons are not so obvious. If one is negative and other is positive, - // we have to take the dateline into account. - - calculation_type lon_diff = geometry::get_as_radian<0>(p2) - - geometry::get_as_radian<0>(p1); - if (lon_diff <= 0) - { - lon_diff += two_pi; - } - - if (lon_diff > pi) - { - excess = -excess; - } - - state.sum += excess; - } - } - - inline return_type result(excess_sum const& state) const - { - return state.area(m_radius); - } - -private : - /// Radius of the sphere - calculation_type m_radius; -}; - -#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS - -namespace services -{ - - -template -struct default_strategy -{ - typedef strategy::area::huiller type; -}; - -// Note: spherical polar coordinate system requires "get_as_radian_equatorial" -/***template -struct default_strategy -{ - typedef strategy::area::huiller type; -};***/ - -} // namespace services - -#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS - - -}} // namespace strategy::area - - - - -}} // namespace boost::geometry - -#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_AREA_HUILLER_HPP diff --git a/include/boost/geometry/strategies/spherical/area_spherical.hpp b/include/boost/geometry/strategies/spherical/area_spherical.hpp new file mode 100644 index 000000000..faff0d9b4 --- /dev/null +++ b/include/boost/geometry/strategies/spherical/area_spherical.hpp @@ -0,0 +1,167 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2016-2017 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 +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_AREA_SPHERICAL_HPP +#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_AREA_SPHERICAL_HPP + +#include +#include +#include + +namespace boost { namespace geometry +{ + +namespace strategy { namespace area +{ + +/*! +\brief Spherical area calculation by trapezoidal rule + +} + +*/ +template +< + typename PointOfSegment, + bool LongSegment = false, + typename CalculationType = void +> +class spherical +{ +typedef typename boost::mpl::if_c + < + boost::is_void::type::value, + typename select_most_precise + < + typename coordinate_type::type, + double + >::type, + CalculationType + >::type CT; + +protected : + struct excess_sum + { + CT m_sum; + + // Keep track if encircles some pole + size_t m_crosses_prime_meridian; + + inline excess_sum() + : m_sum(0) + , m_crosses_prime_meridian(0) + {} + template + inline CT area(SphereType sphere) const + { + CT result; + CT radius = geometry::get_radius<0>(sphere); + + // Encircles pole + if(m_crosses_prime_meridian % 2 == 1) + { + size_t times_crosses_prime_meridian + = 1 + (m_crosses_prime_meridian / 2); + + result = CT(2) + * geometry::math::pi() + * times_crosses_prime_meridian + - geometry::math::abs(m_sum); + + if(geometry::math::sign(m_sum) == 1) + { + result = - result; + } + + } else { + result = m_sum; + } + + result *= radius * radius; + + return result; + } + }; + +public : + typedef CT return_type; + typedef PointOfSegment segment_point_type; + typedef excess_sum state_type; + typedef geometry::srs::sphere sphere_type; + + inline spherical(sphere_type sphere = sphere_type()) + : m_sphere(sphere) + {} + + inline spherical(CT radius) //backward compatibility + : m_sphere() + { + geometry::set_radius<0>(m_sphere, radius); + } + + inline void apply(PointOfSegment const& p1, + PointOfSegment const& p2, + excess_sum& state) const + { + if (! geometry::math::equals(get<0>(p1), get<0>(p2))) + { + + state.m_sum += geometry::formula::area_formulas + ::template spherical(p1, p2); + + // Keep track whenever a segment crosses the prime meridian + geometry::formula::area_formulas + ::crosses_prime_meridian(p1, p2, state); + + } + } + + inline return_type result(excess_sum const& state) const + { + return state.area(m_sphere); + } + +private : + /// srs Sphere + sphere_type m_sphere; +}; + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + + +template +struct default_strategy +{ + typedef strategy::area::spherical type; +}; + +// Note: spherical polar coordinate system requires "get_as_radian_equatorial" +template +struct default_strategy +{ + typedef strategy::area::spherical type; +}; + +} // namespace services + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::area + + + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_AREA_SPHERICAL_HPP diff --git a/include/boost/geometry/strategies/spherical/azimuth_spherical.hpp b/include/boost/geometry/strategies/spherical/azimuth_spherical.hpp new file mode 100644 index 000000000..52c0a4ef2 --- /dev/null +++ b/include/boost/geometry/strategies/spherical/azimuth_spherical.hpp @@ -0,0 +1,77 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2016-2017 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 +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_AZIMUTH_SPHERICAL_HPP +#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_AZIMUTH_SPHERICAL_HPP + +#include +#include + +namespace boost { namespace geometry +{ + +namespace strategy { namespace azimuth +{ + +template +< + typename CalculationType +> +class spherical +{ +public : + + inline spherical() + {} + + inline void apply(CalculationType const& lon1_rad, + CalculationType const& lat1_rad, + CalculationType const& lon2_rad, + CalculationType const& lat2_rad, + CalculationType& a1, + CalculationType& a2) const + { + geometry::formula::result_spherical result = geometry::formula:: + spherical_azimuth(lon1_rad, lat1_rad, lon2_rad, lat2_rad); + + a1 = result.azimuth; + a2 = result.reverse_azimuth; + } + +}; + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef strategy::azimuth::spherical type; +}; + +/* +template +struct default_strategy +{ + typedef strategy::azimuth::spherical type; +}; +*/ +} + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +}} // namespace strategy::azimuth + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_AZIMUTH_SPHERICAL_HPP diff --git a/include/boost/geometry/strategies/spherical/envelope_segment.hpp b/include/boost/geometry/strategies/spherical/envelope_segment.hpp new file mode 100644 index 000000000..1003c18c2 --- /dev/null +++ b/include/boost/geometry/strategies/spherical/envelope_segment.hpp @@ -0,0 +1,82 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2017 Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fisikopoulos, 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_SPHERICAL_ENVELOPE_SEGMENT_HPP +#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_SEGMENT_HPP + +#include +#include +#include +#include + +namespace boost { namespace geometry +{ + +namespace strategy { namespace envelope +{ + +template +class spherical_segment +{ +public : + + inline spherical_segment() + {} + + template + inline void + apply(Point1 const& point1, Point2 const& point2, Box& box) const + { + Point1 p1_normalized = detail::return_normalized(point1); + Point2 p2_normalized = detail::return_normalized(point2); + + geometry::strategy::azimuth::spherical azimuth_spherical; + + typedef typename coordinate_system::type::units units_type; + + geometry::detail::envelope::envelope_segment_impl + ::template apply(geometry::get<0>(p1_normalized), + geometry::get<1>(p1_normalized), + geometry::get<0>(p2_normalized), + geometry::get<1>(p2_normalized), + box, + azimuth_spherical); + + } +}; + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef strategy::envelope::spherical_segment type; +}; + + +template +struct default_strategy +{ + typedef strategy::envelope::spherical_segment type; +}; + +} + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::envelope + +}} //namepsace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_SEGMENT_HPP + diff --git a/include/boost/geometry/strategies/spherical/intersection.hpp b/include/boost/geometry/strategies/spherical/intersection.hpp index 4ffc853aa..b8b8bf93e 100644 --- a/include/boost/geometry/strategies/spherical/intersection.hpp +++ b/include/boost/geometry/strategies/spherical/intersection.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2016, Oracle and/or its affiliates. +// Copyright (c) 2016-2017, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -32,9 +32,14 @@ #include -#include +#include +#include #include #include +#include +#include +#include +#include #include #include @@ -68,10 +73,38 @@ namespace strategy { namespace intersection // For now, intersection points near the endpoints are checked explicitly if needed (if the IP is near the endpoint) // to generate precise result for them. Only the crossing (i) case may suffer from lower precision. -template +template struct relate_spherical_segments { - typedef typename Policy::return_type return_type; + typedef side::spherical_side_formula side_strategy_type; + + static inline side_strategy_type get_side_strategy() + { + return side_strategy_type(); + } + + template + struct point_in_geometry_strategy + { + typedef strategy::within::winding + < + typename point_type::type, + typename point_type::type, + side_strategy_type, + CalculationType + > type; + }; + + template + static inline typename point_in_geometry_strategy::type + get_point_in_geometry_strategy() + { + typedef typename point_in_geometry_strategy + < + Geometry1, Geometry2 + >::type strategy_type; + return strategy_type(); + } enum intersection_point_flag { ipi_inters = 0, ipi_at_a1, ipi_at_a2, ipi_at_b1, ipi_at_b2 }; @@ -137,9 +170,16 @@ struct relate_spherical_segments }; // Relate segments a and b - template - static inline return_type apply(Segment1 const& a, Segment2 const& b, - RobustPolicy const& robust_policy) + template + < + typename Segment1, + typename Segment2, + typename Policy, + typename RobustPolicy + > + static inline typename Policy::return_type + apply(Segment1 const& a, Segment2 const& b, + Policy const& policy, RobustPolicy const& robust_policy) { typedef typename point_type::type point1_t; typedef typename point_type::type point2_t; @@ -152,14 +192,23 @@ struct relate_spherical_segments detail::assign_point_from_index<0>(b, b1); detail::assign_point_from_index<1>(b, b2); - return apply(a, b, robust_policy, a1, a2, b1, b2); + return apply(a, b, policy, robust_policy, a1, a2, b1, b2); } // Relate segments a and b - template - static inline return_type apply(Segment1 const& a, Segment2 const& b, - RobustPolicy const&, - Point1 const& a1, Point1 const& a2, Point2 const& b1, Point2 const& b2) + template + < + typename Segment1, + typename Segment2, + typename Policy, + typename RobustPolicy, + typename Point1, + typename Point2 + > + static inline typename Policy::return_type + apply(Segment1 const& a, Segment2 const& b, + Policy const&, RobustPolicy const&, + Point1 const& a1, Point1 const& a2, Point2 const& b1, Point2 const& b2) { BOOST_CONCEPT_ASSERT( (concepts::ConstSegment) ); BOOST_CONCEPT_ASSERT( (concepts::ConstSegment) ); @@ -275,12 +324,12 @@ struct relate_spherical_segments { if (a_is_point) { - return collinear_one_degenerted(a, true, b1, b2, a1, a2, b1v, b2v, norm2, a1v); + return collinear_one_degenerted(a, true, b1, b2, a1, a2, b1v, b2v, norm2, a1v); } else if (b_is_point) { // b2 used to be consistent with (degenerated) checks above (is it needed?) - return collinear_one_degenerted(b, false, a1, a2, b1, b2, a1v, a2v, norm1, b1v); + return collinear_one_degenerted(b, false, a1, a2, b1, b2, a1v, a2v, norm1, b1v); } else { @@ -385,12 +434,13 @@ struct relate_spherical_segments } private: - template - static inline return_type collinear_one_degenerted(Segment const& segment, bool degenerated_a, - Point1 const& a1, Point1 const& a2, - Point2 const& b1, Point2 const& b2, - Vec3d const& v1, Vec3d const& v2, Vec3d const& norm, - Vec3d const& vother) + template + static inline typename Policy::return_type + collinear_one_degenerted(Segment const& segment, bool degenerated_a, + Point1 const& a1, Point1 const& a2, + Point2 const& b1, Point2 const& b2, + Vec3d const& v1, Vec3d const& v2, Vec3d const& norm, + Vec3d const& vother) { CalcT dist_1_2, dist_1_o; return ! calculate_collinear_data(a1, a2, b1, b2, v1, v2, norm, vother, dist_1_2, dist_1_o) @@ -671,22 +721,22 @@ private: namespace services { -/*template -struct default_strategy +/*template +struct default_strategy { - typedef relate_spherical_segments type; + typedef relate_spherical_segments type; };*/ -template -struct default_strategy +template +struct default_strategy { - typedef relate_spherical_segments type; + typedef relate_spherical_segments type; }; -template -struct default_strategy +template +struct default_strategy { - typedef relate_spherical_segments type; + typedef relate_spherical_segments type; }; } // namespace services @@ -695,6 +745,71 @@ struct default_strategy }} // namespace strategy::intersection + +namespace strategy +{ + +namespace within { namespace services +{ + +template +struct default_strategy +{ + typedef strategy::intersection::relate_spherical_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_spherical_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_spherical_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_spherical_segments<> type; +}; + +}} // within::services + +namespace covered_by { namespace services +{ + +template +struct default_strategy +{ + typedef strategy::intersection::relate_spherical_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_spherical_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_spherical_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_spherical_segments<> type; +}; + +}} // within::services + +} // strategy + + }} // namespace boost::geometry diff --git a/include/boost/geometry/strategies/strategies.hpp b/include/boost/geometry/strategies/strategies.hpp index 342485cc4..35763675a 100644 --- a/include/boost/geometry/strategies/strategies.hpp +++ b/include/boost/geometry/strategies/strategies.hpp @@ -4,9 +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 2014-2016. -// Modifications copyright (c) 2014-2016 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014-2017. +// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, 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 @@ -23,18 +24,24 @@ #include #include +#include #include #include #include #include +#include +#include #include +#include #include #include // for backward compatibility +#include #include #include #include #include +#include #include #include #include @@ -47,27 +54,34 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include #include -#include +#include +#include #include #include #include #include +#include #include #include +#include +#include #include #include #include +#include //#include //#include //#include @@ -80,8 +94,6 @@ #include #include -#include - #include #include diff --git a/include/boost/geometry/strategies/transform/inverse_transformer.hpp b/include/boost/geometry/strategies/transform/inverse_transformer.hpp index e64a46e4a..5213bce47 100644 --- a/include/boost/geometry/strategies/transform/inverse_transformer.hpp +++ b/include/boost/geometry/strategies/transform/inverse_transformer.hpp @@ -14,15 +14,8 @@ #ifndef BOOST_GEOMETRY_STRATEGIES_TRANSFORM_INVERSE_TRANSFORMER_HPP #define BOOST_GEOMETRY_STRATEGIES_TRANSFORM_INVERSE_TRANSFORMER_HPP -// Remove the ublas checking, otherwise the inverse might fail -// (while nothing seems to be wrong) -#ifdef BOOST_UBLAS_TYPE_CHECK -#undef BOOST_UBLAS_TYPE_CHECK -#endif -#define BOOST_UBLAS_TYPE_CHECK 0 - -#include -#include +#include +#include #include @@ -44,31 +37,13 @@ template std::size_t Dimension2 > class inverse_transformer - : public ublas_transformer + : public matrix_transformer { public : template inline inverse_transformer(Transformer const& input) { - typedef boost::numeric::ublas::matrix matrix_type; - - // create a working copy of the input - matrix_type copy(input.matrix()); - - // create a permutation matrix for the LU-factorization - typedef boost::numeric::ublas::permutation_matrix<> permutation_matrix; - permutation_matrix pm(copy.size1()); - - // perform LU-factorization - int res = boost::numeric::ublas::lu_factorize(copy, pm); - if( res == 0 ) - { - // create identity matrix - this->m_matrix.assign(boost::numeric::ublas::identity_matrix(copy.size1())); - - // backsubstitute to get the inverse - boost::numeric::ublas::lu_substitute(copy, pm, this->m_matrix); - } + this->m_matrix = boost::qvm::inverse(input.matrix()); } }; diff --git a/include/boost/geometry/strategies/transform/map_transformer.hpp b/include/boost/geometry/strategies/transform/map_transformer.hpp index 1109e814b..01ea6168c 100644 --- a/include/boost/geometry/strategies/transform/map_transformer.hpp +++ b/include/boost/geometry/strategies/transform/map_transformer.hpp @@ -46,9 +46,10 @@ template bool SameScale = true > class map_transformer - : public ublas_transformer + : public matrix_transformer { - typedef boost::numeric::ublas::matrix M; + typedef boost::qvm::mat M; + typedef boost::qvm::mat matrix33; public : template @@ -76,26 +77,26 @@ private : { // Translate to a coordinate system centered on world coordinates (-wx, -wy) - M t1(3,3); - t1(0,0) = 1; t1(0,1) = 0; t1(0,2) = -wx; - t1(1,0) = 0; t1(1,1) = 1; t1(1,2) = -wy; - t1(2,0) = 0; t1(2,1) = 0; t1(2,2) = 1; + matrix33 t1; + qvm::A<0,0>(t1) = 1; qvm::A<0,1>(t1) = 0; qvm::A<0,2>(t1) = -wx; + qvm::A<1,0>(t1) = 0; qvm::A<1,1>(t1) = 1; qvm::A<1,2>(t1) = -wy; + qvm::A<2,0>(t1) = 0; qvm::A<2,1>(t1) = 0; qvm::A<2,2>(t1) = 1; // Scale the map - M s(3,3); - s(0,0) = scalex; s(0,1) = 0; s(0,2) = 0; - s(1,0) = 0; s(1,1) = scaley; s(1,2) = 0; - s(2,0) = 0; s(2,1) = 0; s(2,2) = 1; + matrix33 s; + qvm::A<0,0>(s) = scalex; qvm::A<0,1>(s) = 0; qvm::A<0,2>(s) = 0; + qvm::A<1,0>(s) = 0; qvm::A<1,1>(s) = scaley; qvm::A<1,2>(s) = 0; + qvm::A<2,0>(s) = 0; qvm::A<2,1>(s) = 0; qvm::A<2,2>(s) = 1; // Translate to a coordinate system centered on the specified pixels (+px, +py) - M t2(3, 3); - t2(0,0) = 1; t2(0,1) = 0; t2(0,2) = px; - t2(1,0) = 0; t2(1,1) = 1; t2(1,2) = py; - t2(2,0) = 0; t2(2,1) = 0; t2(2,2) = 1; + matrix33 t2; + qvm::A<0,0>(t2) = 1; qvm::A<0,1>(t2) = 0; qvm::A<0,2>(t2) = px; + qvm::A<1,0>(t2) = 0; qvm::A<1,1>(t2) = 1; qvm::A<1,2>(t2) = py; + qvm::A<2,0>(t2) = 0; qvm::A<2,1>(t2) = 0; qvm::A<2,2>(t2) = 1; // Calculate combination matrix in two steps - this->m_matrix = boost::numeric::ublas::prod(s, t1); - this->m_matrix = boost::numeric::ublas::prod(t2, this->m_matrix); + this->m_matrix = s * t1; + this->m_matrix = t2 * this->m_matrix; } @@ -140,20 +141,20 @@ private : if (Mirror) { // Mirror in y-direction - M m(3,3); - m(0,0) = 1; m(0,1) = 0; m(0,2) = 0; - m(1,0) = 0; m(1,1) = -1; m(1,2) = 0; - m(2,0) = 0; m(2,1) = 0; m(2,2) = 1; + matrix33 m; + qvm::A<0,0>(m) = 1; qvm::A<0,1>(m) = 0; qvm::A<0,2>(m) = 0; + qvm::A<1,0>(m) = 0; qvm::A<1,1>(m) = -1; qvm::A<1,2>(m) = 0; + qvm::A<2,0>(m) = 0; qvm::A<2,1>(m) = 0; qvm::A<2,2>(m) = 1; // Translate in y-direction such that it fits again - M y(3, 3); - y(0,0) = 1; y(0,1) = 0; y(0,2) = 0; - y(1,0) = 0; y(1,1) = 1; y(1,2) = height; - y(2,0) = 0; y(2,1) = 0; y(2,2) = 1; + matrix33 y; + qvm::A<0,0>(y) = 1; qvm::A<0,1>(y) = 0; qvm::A<0,2>(y) = 0; + qvm::A<1,0>(y) = 0; qvm::A<1,1>(y) = 1; qvm::A<1,2>(y) = height; + qvm::A<2,0>(y) = 0; qvm::A<2,1>(y) = 0; qvm::A<2,2>(y) = 1; // Calculate combination matrix in two steps - this->m_matrix = boost::numeric::ublas::prod(m, this->m_matrix); - this->m_matrix = boost::numeric::ublas::prod(y, this->m_matrix); + this->m_matrix = m * this->m_matrix; + this->m_matrix = y * this->m_matrix; } } }; diff --git a/include/boost/geometry/strategies/transform/matrix_transformers.hpp b/include/boost/geometry/strategies/transform/matrix_transformers.hpp index d891263a7..e0ac6496f 100644 --- a/include/boost/geometry/strategies/transform/matrix_transformers.hpp +++ b/include/boost/geometry/strategies/transform/matrix_transformers.hpp @@ -22,27 +22,9 @@ #include -// Remove the ublas checking, otherwise the inverse might fail -// (while nothing seems to be wrong) -#ifdef BOOST_UBLAS_TYPE_CHECK -#undef BOOST_UBLAS_TYPE_CHECK -#endif -#define BOOST_UBLAS_TYPE_CHECK 0 - -#include - -#if defined(__clang__) -// Avoid warning about unused UBLAS function: boost_numeric_ublas_abs -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-function" -#endif - -#include -#include - -#if defined(__clang__) -#pragma clang diagnostic pop -#endif +#include +#include +#include #include #include @@ -75,38 +57,37 @@ template std::size_t Dimension1, std::size_t Dimension2 > -class ublas_transformer +class matrix_transformer { }; template -class ublas_transformer +class matrix_transformer { protected : typedef CalculationType ct; - typedef boost::numeric::ublas::matrix matrix_type; + typedef boost::qvm::mat matrix_type; matrix_type m_matrix; public : - inline ublas_transformer( + inline matrix_transformer( ct const& m_0_0, ct const& m_0_1, ct const& m_0_2, ct const& m_1_0, ct const& m_1_1, ct const& m_1_2, ct const& m_2_0, ct const& m_2_1, ct const& m_2_2) - : m_matrix(3, 3) { - m_matrix(0,0) = m_0_0; m_matrix(0,1) = m_0_1; m_matrix(0,2) = m_0_2; - m_matrix(1,0) = m_1_0; m_matrix(1,1) = m_1_1; m_matrix(1,2) = m_1_2; - m_matrix(2,0) = m_2_0; m_matrix(2,1) = m_2_1; m_matrix(2,2) = m_2_2; + qvm::A<0,0>(m_matrix) = m_0_0; qvm::A<0,1>(m_matrix) = m_0_1; qvm::A<0,2>(m_matrix) = m_0_2; + qvm::A<1,0>(m_matrix) = m_1_0; qvm::A<1,1>(m_matrix) = m_1_1; qvm::A<1,2>(m_matrix) = m_1_2; + qvm::A<2,0>(m_matrix) = m_2_0; qvm::A<2,1>(m_matrix) = m_2_1; qvm::A<2,2>(m_matrix) = m_2_2; } - inline ublas_transformer(matrix_type const& matrix) + inline matrix_transformer(matrix_type const& matrix) : m_matrix(matrix) {} - inline ublas_transformer() : m_matrix(3, 3) {} + inline matrix_transformer() {} template inline bool apply(P1 const& p1, P2& p2) const @@ -117,8 +98,8 @@ public : ct const& c1 = get<0>(p1); ct const& c2 = get<1>(p1); - ct p2x = c1 * m_matrix(0,0) + c2 * m_matrix(0,1) + m_matrix(0,2); - ct p2y = c1 * m_matrix(1,0) + c2 * m_matrix(1,1) + m_matrix(1,2); + ct p2x = c1 * qvm::A<0,0>(m_matrix) + c2 * qvm::A<0,1>(m_matrix) + qvm::A<0,2>(m_matrix); + ct p2y = c1 * qvm::A<1,0>(m_matrix) + c2 * qvm::A<1,1>(m_matrix) + qvm::A<1,2>(m_matrix); typedef typename geometry::coordinate_type::type ct2; set<0>(p2, boost::numeric_cast(p2x)); @@ -133,51 +114,50 @@ public : // It IS possible to go from 3 to 2 coordinates template -class ublas_transformer : public ublas_transformer +class matrix_transformer : public matrix_transformer { typedef CalculationType ct; public : - inline ublas_transformer( + inline matrix_transformer( ct const& m_0_0, ct const& m_0_1, ct const& m_0_2, ct const& m_1_0, ct const& m_1_1, ct const& m_1_2, ct const& m_2_0, ct const& m_2_1, ct const& m_2_2) - : ublas_transformer( + : matrix_transformer( m_0_0, m_0_1, m_0_2, m_1_0, m_1_1, m_1_2, m_2_0, m_2_1, m_2_2) {} - inline ublas_transformer() - : ublas_transformer() + inline matrix_transformer() + : matrix_transformer() {} }; template -class ublas_transformer +class matrix_transformer { protected : typedef CalculationType ct; - typedef boost::numeric::ublas::matrix matrix_type; + typedef boost::qvm::mat matrix_type; matrix_type m_matrix; public : - inline ublas_transformer( + inline matrix_transformer( ct const& m_0_0, ct const& m_0_1, ct const& m_0_2, ct const& m_0_3, ct const& m_1_0, ct const& m_1_1, ct const& m_1_2, ct const& m_1_3, ct const& m_2_0, ct const& m_2_1, ct const& m_2_2, ct const& m_2_3, ct const& m_3_0, ct const& m_3_1, ct const& m_3_2, ct const& m_3_3 ) - : m_matrix(4, 4) { - m_matrix(0,0) = m_0_0; m_matrix(0,1) = m_0_1; m_matrix(0,2) = m_0_2; m_matrix(0,3) = m_0_3; - m_matrix(1,0) = m_1_0; m_matrix(1,1) = m_1_1; m_matrix(1,2) = m_1_2; m_matrix(1,3) = m_1_3; - m_matrix(2,0) = m_2_0; m_matrix(2,1) = m_2_1; m_matrix(2,2) = m_2_2; m_matrix(2,3) = m_2_3; - m_matrix(3,0) = m_3_0; m_matrix(3,1) = m_3_1; m_matrix(3,2) = m_3_2; m_matrix(3,3) = m_3_3; + qvm::A<0,0>(m_matrix) = m_0_0; qvm::A<0,1>(m_matrix) = m_0_1; qvm::A<0,2>(m_matrix) = m_0_2; qvm::A<0,3>(m_matrix) = m_0_3; + qvm::A<1,0>(m_matrix) = m_1_0; qvm::A<1,1>(m_matrix) = m_1_1; qvm::A<1,2>(m_matrix) = m_1_2; qvm::A<1,3>(m_matrix) = m_1_3; + qvm::A<2,0>(m_matrix) = m_2_0; qvm::A<2,1>(m_matrix) = m_2_1; qvm::A<2,2>(m_matrix) = m_2_2; qvm::A<2,3>(m_matrix) = m_2_3; + qvm::A<3,0>(m_matrix) = m_3_0; qvm::A<3,1>(m_matrix) = m_3_1; qvm::A<3,2>(m_matrix) = m_3_2; qvm::A<3,3>(m_matrix) = m_3_3; } - inline ublas_transformer() : m_matrix(4, 4) {} + inline matrix_transformer() {} template inline bool apply(P1 const& p1, P2& p2) const @@ -222,7 +202,7 @@ class translate_transformer template -class translate_transformer : public ublas_transformer +class translate_transformer : public matrix_transformer { public : // To have translate transformers compatible for 2/3 dimensions, the @@ -230,7 +210,7 @@ public : inline translate_transformer(CalculationType const& translate_x, CalculationType const& translate_y, CalculationType const& = 0) - : ublas_transformer( + : matrix_transformer( 1, 0, translate_x, 0, 1, translate_y, 0, 0, 1) @@ -239,13 +219,13 @@ public : template -class translate_transformer : public ublas_transformer +class translate_transformer : public matrix_transformer { public : inline translate_transformer(CalculationType const& translate_x, CalculationType const& translate_y, CalculationType const& translate_z) - : ublas_transformer( + : matrix_transformer( 1, 0, 0, translate_x, 0, 1, 0, translate_y, 0, 0, 1, translate_z, @@ -275,14 +255,14 @@ class scale_transformer template -class scale_transformer : public ublas_transformer +class scale_transformer : public matrix_transformer { public : inline scale_transformer(CalculationType const& scale_x, CalculationType const& scale_y, CalculationType const& = 0) - : ublas_transformer( + : matrix_transformer( scale_x, 0, 0, 0, scale_y, 0, 0, 0, 1) @@ -290,7 +270,7 @@ public : inline scale_transformer(CalculationType const& scale) - : ublas_transformer( + : matrix_transformer( scale, 0, 0, 0, scale, 0, 0, 0, 1) @@ -299,13 +279,13 @@ public : template -class scale_transformer : public ublas_transformer +class scale_transformer : public matrix_transformer { public : inline scale_transformer(CalculationType const& scale_x, CalculationType const& scale_y, CalculationType const& scale_z) - : ublas_transformer( + : matrix_transformer( scale_x, 0, 0, 0, 0, scale_y, 0, 0, 0, 0, scale_z, 0, @@ -314,7 +294,7 @@ public : inline scale_transformer(CalculationType const& scale) - : ublas_transformer( + : matrix_transformer( scale, 0, 0, 0, 0, scale, 0, 0, 0, 0, scale, 0, @@ -363,11 +343,11 @@ template std::size_t Dimension2 > class rad_rotate_transformer - : public ublas_transformer + : public matrix_transformer { public : inline rad_rotate_transformer(CalculationType const& angle) - : ublas_transformer( + : matrix_transformer( cos(angle), sin(angle), 0, -sin(angle), cos(angle), 0, 0, 0, 1) diff --git a/include/boost/geometry/strategies/within.hpp b/include/boost/geometry/strategies/within.hpp index d625bc40e..28a3283db 100644 --- a/include/boost/geometry/strategies/within.hpp +++ b/include/boost/geometry/strategies/within.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 2017. +// Modifications copyright (c) 2017, Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -16,6 +21,12 @@ #include +#include +#include +#include +#include +#include + namespace boost { namespace geometry { @@ -30,23 +41,39 @@ namespace services /*! \brief Traits class binding a within determination strategy to a coordinate system \ingroup within -\tparam TagContained tag (possibly casted) of point-type -\tparam TagContained tag (possibly casted) of (possibly) containing type -\tparam CsTagContained tag of coordinate system of point-type -\tparam CsTagContaining tag of coordinate system of (possibly) containing type -\tparam Geometry geometry-type of input (often point, or box) +\tparam GeometryContained geometry-type of input (possibly) contained type \tparam GeometryContaining geometry-type of input (possibly) containing type +\tparam TagContained casted tag of (possibly) contained type +\tparam TagContaining casted tag of (possibly) containing type +\tparam CsTagContained tag of coordinate system of (possibly) contained type +\tparam CsTagContaining tag of coordinate system of (possibly) containing type */ template < - typename TagContained, - typename TagContaining, - typename CastedTagContained, - typename CastedTagContaining, - typename CsTagContained, - typename CsTagContaining, typename GeometryContained, - typename GeometryContaining + typename GeometryContaining, + typename TagContained = typename tag::type, + typename TagContaining = typename tag::type, + typename CastedTagContained = typename tag_cast + < + typename tag::type, + pointlike_tag, linear_tag, polygonal_tag, areal_tag + >::type, + typename CastedTagContaining = typename tag_cast + < + typename tag::type, + pointlike_tag, linear_tag, polygonal_tag, areal_tag + >::type, + typename CsTagContained = typename tag_cast + < + typename cs_tag::type>::type, + spherical_tag + >::type, + typename CsTagContaining = typename tag_cast + < + typename cs_tag::type>::type, + spherical_tag + >::type > struct default_strategy { diff --git a/include/boost/geometry/util/math.hpp b/include/boost/geometry/util/math.hpp index 234cfa1ed..1874fe76a 100644 --- a/include/boost/geometry/util/math.hpp +++ b/include/boost/geometry/util/math.hpp @@ -518,7 +518,7 @@ inline T scaled_epsilon(T const& value) } -// Maybe replace this by boost equals or boost ublas numeric equals or so +// Maybe replace this by boost equals or so /*! \brief returns true if both arguments are equal. diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 173284fa3..5c6f27e46 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -18,6 +18,7 @@ project boost-geometry-test msvc:on msvc:/bigobj clang:-Wno-unneeded-internal-declaration # supress warning by Boost.None + intel:BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE windows,intel:/bigobj BOOST_NO_AUTO_PTR # disable the deprecated std::auto_ptr support in SmartPtr and Core ; diff --git a/test/algorithms/Jamfile.v2 b/test/algorithms/Jamfile.v2 index 63f218504..cb01090ef 100644 --- a/test/algorithms/Jamfile.v2 +++ b/test/algorithms/Jamfile.v2 @@ -4,8 +4,8 @@ # Copyright (c) 2008-2015 Bruno Lalande, Paris, France. # Copyright (c) 2009-2015 Mateusz Loskot, London, UK. # -# This file was modified by Oracle on 2014, 2015, 2016. -# Modifications copyright (c) 2014-2016, Oracle and/or its affiliates. +# This file was modified by Oracle on 2014, 2015, 2016,2017. +# Modifications copyright (c) 2014-2017, Oracle and/or its affiliates. # # Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle # Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -18,8 +18,6 @@ test-suite boost-geometry-algorithms : [ run append.cpp : : : : algorithms_append ] - [ run area.cpp : : : : algorithms_area ] - [ run area_multi.cpp : : : : algorithms_area_multi ] [ run assign.cpp : : : : algorithms_assign ] [ run centroid.cpp : : : : algorithms_centroid ] [ run centroid_multi.cpp : : : : algorithms_centroid_multi ] @@ -60,6 +58,7 @@ test-suite boost-geometry-algorithms [ run unique_multi.cpp : : : : algorithms_unique_multi ] ; +build-project area ; build-project buffer ; build-project detail ; build-project distance ; diff --git a/test/algorithms/area.cpp b/test/algorithms/area.cpp deleted file mode 100644 index 773f09941..000000000 --- a/test/algorithms/area.cpp +++ /dev/null @@ -1,371 +0,0 @@ -// Boost.Geometry (aka GGL, Generic Geometry Library) -// Unit Test - -// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. -// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. - -// This file was modified by Oracle on 2015, 2016. -// Modifications copyright (c) 2015-2016, 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. - -// 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) - - -#include - -#include -#include -#include -#include -#include - -#include -#include -//#define BOOST_GEOMETRY_TEST_DEBUG - -#include - -template -void test_polygon() -{ - // Rotated square, length=sqrt(2) -> area=2 - test_geometry("POLYGON((1 1,2 2,3 1,2 0,1 1))", 2.0); - test_geometry("POLYGON((1 1,2 2,3 1,2 0,1 1))", 2.0); - test_geometry("POLYGON((0 0,0 7,4 2,2 0,0 0))", 16.0); - test_geometry("POLYGON((1 1,2 1,2 2,1 2,1 1))", -1.0); - test_geometry("POLYGON((0 0,0 7,4 2,2 0,0 0), (1 1,2 1,2 2,1 2,1 1))", 15.0); -} - - -template -void test_all() -{ - test_geometry >("POLYGON((0 0,2 2))", 4.0); - test_geometry >("POLYGON((2 2,0 0))", 4.0); - - test_polygon >(); - test_polygon >(); - - // clockwise rings (second is wrongly ordered) - test_geometry >("POLYGON((0 0,0 7,4 2,2 0,0 0))", 16.0); - test_geometry >("POLYGON((0 0,2 0,4 2,0 7,0 0))", -16.0); - - test_geometry >("POLYGON((0 0,0 7,4 2,2 0,0 0))", 16.0); - - // ccw - test_geometry > - ("POLYGON((0 0,0 7,4 2,2 0,0 0), (1 1,2 1,2 2,1 2,1 1))", -15.0); - - test_geometry > - ("POLYGON((1 0,0 1,-1 0,0 -1,1 0))", 2); - - typedef typename bg::coordinate_type

::type coord_type; - if (BOOST_GEOMETRY_CONDITION((boost::is_same::value))) - { - test_geometry > - ("POLYGON((100000001 100000000, 100000000 100000001, \ - 99999999 100000000, 100000000 99999999))", 2); - } - else if (BOOST_GEOMETRY_CONDITION((boost::is_same::value))) - { - test_geometry > - ("POLYGON((100001 100000, 100000 100001, \ - 99999 100000, 100000 99999))", 2); - } -} - -template -void test_spherical(bool polar = false) -{ - typedef typename bg::coordinate_type::type ct; - bg::model::polygon geometry; - - // unit-sphere has area of 4-PI. Polygon covering 1/8 of it: - // calculations splitted for ttmath - ct const four = 4.0; - ct const eight = 8.0; - ct expected = four * boost::geometry::math::pi() / eight; - bg::read_wkt("POLYGON((0 0,0 90,90 0,0 0))", geometry); - - ct area = bg::area(geometry); - BOOST_CHECK_CLOSE(area, expected, 0.0001); - - // With strategy, radius 2 -> 4 pi r^2 - bg::strategy::area::huiller - < - typename bg::point_type::type - > strategy(2.0); - - area = bg::area(geometry, strategy); - ct const two = 2.0; - BOOST_CHECK_CLOSE(area, two * two * expected, 0.0001); - - // Wrangel Island (dateline crossing) - // With (spherical) Earth strategy - bg::strategy::area::huiller - < - typename bg::point_type::type - > spherical_earth(6373); - bg::read_wkt("POLYGON((-178.7858 70.7852, 177.4758 71.2333, 179.7436 71.5733, -178.7858 70.7852))", geometry); - area = bg::area(geometry, spherical_earth); - // SQL Server gives: 4537.9654419375 - // PostGIS gives: 4537.9311668307 - // Note: those are Geographic, this test is Spherical - BOOST_CHECK_CLOSE(area, 4506.6389, 0.001); - - // Wrangel, more in detail - bg::read_wkt("POLYGON((-178.568604 71.564148,-178.017548 71.449692,-177.833313 71.3461,-177.502838 71.277466 ,-177.439453 71.226929,-177.620026 71.116638,-177.9389 71.037491,-178.8186 70.979965,-179.274445 70.907761,-180 70.9972,179.678314 70.895538,179.272766 70.888596,178.791016 70.7964,178.617737 71.035538,178.872192 71.217484,179.530273 71.4383 ,-180 71.535843 ,-179.628601 71.577194,-179.305298 71.551361,-179.03421 71.597748,-178.568604 71.564148))", geometry); - area = bg::area(geometry, spherical_earth); - // SQL Server gives: 7669.10402181435 - // PostGIS gives: 7669.55565459832 - BOOST_CHECK_CLOSE(area, 7616.523769, 0.001); - - // Check more at the equator - /* - select 1,geography::STGeomFromText('POLYGON((-178.7858 10.7852 , 179.7436 11.5733 , 177.4758 11.2333 , -178.7858 10.7852))',4326) .STArea()/1000000.0 - union select 2,geography::STGeomFromText('POLYGON((-178.7858 20.7852 , 179.7436 21.5733 , 177.4758 21.2333 , -178.7858 20.7852))',4326) .STArea()/1000000.0 - union select 3,geography::STGeomFromText('POLYGON((-178.7858 30.7852 , 179.7436 31.5733 , 177.4758 31.2333 , -178.7858 30.7852))',4326) .STArea()/1000000.0 - union select 0,geography::STGeomFromText('POLYGON((-178.7858 0.7852 , 179.7436 1.5733 , 177.4758 1.2333 , -178.7858 0.7852))',4326) .STArea()/1000000.0 - union select 4,geography::STGeomFromText('POLYGON((-178.7858 40.7852 , 179.7436 41.5733 , 177.4758 41.2333 , -178.7858 40.7852))',4326) .STArea()/1000000.0 - */ - - bg::read_wkt("POLYGON((-178.7858 0.7852, 177.4758 1.2333, 179.7436 1.5733, -178.7858 0.7852))", geometry); - area = bg::area(geometry, spherical_earth); - BOOST_CHECK_CLOSE(area, 14136.09946, 0.001); // SQL Server gives: 14064.1902284513 - - - bg::read_wkt("POLYGON((-178.7858 10.7852, 177.4758 11.2333, 179.7436 11.5733, -178.7858 10.7852))", geometry); - area = bg::area(geometry, spherical_earth); - BOOST_CHECK_CLOSE(area, 13760.2456, 0.001); // SQL Server gives: 13697.0941155193 - - bg::read_wkt("POLYGON((-178.7858 20.7852, 177.4758 21.2333, 179.7436 21.5733, -178.7858 20.7852))", geometry); - area = bg::area(geometry, spherical_earth); - BOOST_CHECK_CLOSE(area, 12987.8682, 0.001); // SQL Server gives: 12944.3970990317 -> -39m^2 - - bg::read_wkt("POLYGON((-178.7858 30.7852, 177.4758 31.2333, 179.7436 31.5733, -178.7858 30.7852))", geometry); - area = bg::area(geometry, spherical_earth); - BOOST_CHECK_CLOSE(area, 11856.3935, 0.001); // SQL Server gives: 11838.5338423574 -> -18m^2 - - bg::read_wkt("POLYGON((-178.7858 40.7852, 177.4758 41.2333, 179.7436 41.5733, -178.7858 40.7852))", geometry); - area = bg::area(geometry, spherical_earth); - BOOST_CHECK_CLOSE(area, 10404.627685523914, 0.001); // SQL Server gives: 10412.0607137119, -> +8m^2 - - // Concave - bg::read_wkt("POLYGON((0 40,1 42,0 44,2 43,4 44,3 42,4 40,2 41,0 40))", geometry); - area = bg::area(geometry, spherical_earth); - BOOST_CHECK_CLOSE(area, 73538.2958, 0.001); // SQL Server gives: 73604.2047689719 - - // With hole POLYGON((0 40,4 40,4 44,0 44,0 40),(1 41,2 43,3 42,1 41)) - bg::read_wkt("POLYGON((0 40,0 44,4 44,4 40,0 40),(1 41,3 42,2 43,1 41))", geometry); - area = bg::area(geometry, spherical_earth); - BOOST_CHECK_CLOSE(area, 133233.844876, 0.001); // SQL Server gives: 133353.335 - - // around 0 meridian - { - bg::read_wkt("POLYGON((-10 0,-10 10,0 10,0 0,-10 0))", geometry); - ct area1 = bg::area(geometry); - bg::read_wkt("POLYGON((0 0,0 10,10 10,10 0,0 0))", geometry); - ct area2 = bg::area(geometry); - bg::read_wkt("POLYGON((-5 0,-5 10,5 10,5 0,-5 0))", geometry); - ct area3 = bg::area(geometry); - BOOST_CHECK_CLOSE(area1, area2, 0.001); - BOOST_CHECK_CLOSE(area2, area3, 0.001); - BOOST_CHECK_CLOSE(area1, 0.0303822, 0.001); - } - { - bg::read_wkt("POLYGON((-10 -5,-10 5,0 5,0 -5,-10 -5))", geometry); - ct area1 = bg::area(geometry); - bg::read_wkt("POLYGON((0 -5,0 5,10 5,10 -5,0 -5))", geometry); - ct area2 = bg::area(geometry); - bg::read_wkt("POLYGON((-5 -5,-5 5,5 5,5 -5,-5 -5))", geometry); - ct area3 = bg::area(geometry); - BOOST_CHECK_CLOSE(area1, area2, 0.001); - BOOST_CHECK_CLOSE(area2, area3, 0.001); - BOOST_CHECK_CLOSE(area1, 0.0305, 0.001); - } - // around 180 meridian - { - bg::read_wkt("POLYGON((-180 0,-180 10,-170 10,-170 0,-180 0))", geometry); - ct area1 = bg::area(geometry); - bg::read_wkt("POLYGON((175 0,175 10,-175 10,-175 0,175 0))", geometry); - ct area2 = bg::area(geometry); - bg::read_wkt("POLYGON((170 0,170 10,180 10,180 0,170 0))", geometry); - ct area3 = bg::area(geometry); - bg::read_wkt("POLYGON((170 0,170 10,-180 10,-180 0,170 0))", geometry); - ct area4 = bg::area(geometry); - bg::read_wkt("POLYGON((180 0,180 10,-170 10,-170 0,180 0))", geometry); - ct area5 = bg::area(geometry); - BOOST_CHECK_CLOSE(area1, area2, 0.001); - BOOST_CHECK_CLOSE(area2, area3, 0.001); - BOOST_CHECK_CLOSE(area3, area4, 0.001); - BOOST_CHECK_CLOSE(area4, area5, 0.001); - BOOST_CHECK_CLOSE(area1, 0.0303822, 0.001); - } - { - bg::read_wkt("POLYGON((-180 -5,-180 5,-170 5,-170 -5,-180 -5))", geometry); - ct area1 = bg::area(geometry); - bg::read_wkt("POLYGON((175 -5,175 5,-175 5,-175 -5,175 -5))", geometry); - ct area2 = bg::area(geometry); - bg::read_wkt("POLYGON((170 -5,170 5,180 5,180 -5,170 -5))", geometry); - ct area3 = bg::area(geometry); - bg::read_wkt("POLYGON((170 -5,170 5,-180 5,-180 -5,170 -5))", geometry); - ct area4 = bg::area(geometry); - bg::read_wkt("POLYGON((180 -5,180 5,-170 5,-170 -5,180 -5))", geometry); - ct area5 = bg::area(geometry); - BOOST_CHECK_CLOSE(area1, area2, 0.001); - BOOST_CHECK_CLOSE(area2, area3, 0.001); - BOOST_CHECK_CLOSE(area3, area4, 0.001); - BOOST_CHECK_CLOSE(area4, area5, 0.001); - BOOST_CHECK_CLOSE(area1, 0.0305, 0.001); - } - // around poles -#ifdef BOOST_GEOMETRY_ENABLE_FAILING_TESTS - { - bg::read_wkt("POLYGON((0 80,-90 80,-180 80,90 80,0 80))", geometry); - ct area1 = bg::area(geometry); - bg::read_wkt("POLYGON((0 80,-90 80,180 80,90 80,0 80))", geometry); - ct area2 = bg::area(geometry); - bg::read_wkt("POLYGON((0 -80,90 -80,-180 -80,-90 -80,0 -80))", geometry); - ct area3 = bg::area(geometry); - bg::read_wkt("POLYGON((0 -80,90 -80,180 -80,-90 -80,0 -80))", geometry); - ct area4 = bg::area(geometry); - BOOST_CHECK_CLOSE(area1, area2, 0.001); - BOOST_CHECK_CLOSE(area2, area3, 0.001); - BOOST_CHECK_CLOSE(area3, area4, 0.001); - } -#endif - - { - bg::model::ring aurha; // a'dam-utr-rott.-den haag-a'dam - bg::read_wkt("POLYGON((4.892 52.373,5.119 52.093,4.479 51.930,4.23 52.08,4.892 52.373))", aurha); - if (polar) - { - // Create colatitudes (measured from pole) - BOOST_FOREACH(Point& p, aurha) - { - bg::set<1>(p, ct(90) - bg::get<1>(p)); - } - bg::correct(aurha); - } - bg::strategy::area::huiller - < - typename bg::point_type::type - > huiller(6372.795); - area = bg::area(aurha, huiller); - BOOST_CHECK_CLOSE(area, 1476.645675, 0.0001); - - // SQL Server gives: 1481.55595960659 - // for select geography::STGeomFromText('POLYGON((4.892 52.373,4.23 52.08,4.479 51.930,5.119 52.093,4.892 52.373))',4326).STArea()/1000000.0 - } -} - -template -void test_ccw() -{ - typedef bg::model::polygon ccw_polygon; - // counterclockwise rings (second is wrongly ordered) - test_geometry("POLYGON((1 1,2 2,3 1,2 0,1 1))", -2.0); - test_geometry("POLYGON((1 1,2 0,3 1,2 2,1 1))", +2.0); - test_geometry("POLYGON((0 0,0 7,4 2,2 0,0 0))", -16.0); - test_geometry("POLYGON((0 0,2 0,4 2,0 7,0 0))", +16.0); -} - -template -void test_open() -{ - typedef bg::model::polygon open_polygon; - test_geometry("POLYGON((1 1,2 2,3 1,2 0))", 2.0); - // Note the triangular testcase used in CCW is not sensible for open/close -} - -template -void test_open_ccw() -{ - typedef bg::model::polygon open_polygon; - test_geometry("POLYGON((1 1,2 0,3 1,2 2))", 2.0); - // Note the triangular testcase used in CCW is not sensible for open/close -} - -template -void test_empty_input() -{ - bg::model::polygon

poly_empty; - bg::model::ring

ring_empty; - - test_empty_input(poly_empty); - test_empty_input(ring_empty); -} - -void test_large_integers() -{ - typedef bg::model::point int_point_type; - typedef bg::model::point double_point_type; - - bg::model::polygon int_poly; - bg::model::polygon double_poly; - - std::string const polygon_li = "POLYGON((1872000 528000,1872000 192000,1536119 192000,1536000 528000,1200000 528000,1200000 863880,1536000 863880,1872000 863880,1872000 528000))"; - bg::read_wkt(polygon_li, int_poly); - bg::read_wkt(polygon_li, double_poly); - - double int_area = bg::area(int_poly); - double double_area = bg::area(double_poly); - - BOOST_CHECK_CLOSE(int_area, double_area, 0.0001); -} - -void test_variant() -{ - typedef bg::model::point double_point_type; - typedef bg::model::polygon polygon_type; - typedef bg::model::box box_type; - - polygon_type poly; - std::string const polygon_li = "POLYGON((18 5,18 1,15 1,15 5,12 5,12 8,15 8,18 8,18 5))"; - bg::read_wkt(polygon_li, poly); - - box_type box; - std::string const box_li = "BOX(0 0,2 2)"; - bg::read_wkt(box_li, box); - - boost::variant v; - - v = poly; - BOOST_CHECK_CLOSE(bg::area(v), bg::area(poly), 0.0001); - v = box; - BOOST_CHECK_CLOSE(bg::area(v), bg::area(box), 0.0001); -} - -int test_main(int, char* []) -{ - test_all >(); - test_all >(); - test_all >(); - - test_spherical > >(); - //test_spherical > >(true); - - test_ccw >(); - test_open >(); - test_open_ccw >(); - -#ifdef HAVE_TTMATH - test_all >(); - test_spherical > >(); -#endif - - test_large_integers(); - - test_variant(); - - // test_empty_input >(); - - return 0; -} diff --git a/test/algorithms/area/Jamfile.v2 b/test/algorithms/area/Jamfile.v2 new file mode 100644 index 000000000..f3c868da7 --- /dev/null +++ b/test/algorithms/area/Jamfile.v2 @@ -0,0 +1,18 @@ +# Boost.Geometry (aka GGL, Generic Geometry Library) +# +# Copyright (c) 2016 Oracle and/or its affiliates. +# +# Contributed and/or modified by Vissarion Fisikopoulos, 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) + +test-suite boost-geometry-algorithms-area + : + [ run area.cpp : : : : algorithms_area ] + [ run area_sph_geo.cpp : : : : algorithms_area_sph_geo ] + [ run area_geo.cpp : : : : algorithms_area_geo ] + [ run area_multi.cpp : : : : algorithms_area_multi ] + ; + diff --git a/test/algorithms/area/area.cpp b/test/algorithms/area/area.cpp new file mode 100644 index 000000000..e35e8f709 --- /dev/null +++ b/test/algorithms/area/area.cpp @@ -0,0 +1,239 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// Unit Test + +// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. + +// This file was modified by Oracle on 2015, 2016. +// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. + +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle +// Contributed and/or modified by 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. + +// 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) + + +#include + +#include +#include +#include +#include +#include + +#include +#include +//#define BOOST_GEOMETRY_TEST_DEBUG + +#include + +template +void test_polygon() +{ + // Rotated square, length=sqrt(2) -> area=2 + test_geometry("POLYGON((1 1,2 2,3 1,2 0,1 1))", 2.0); + test_geometry("POLYGON((1 1,2 2,3 1,2 0,1 1))", 2.0); + test_geometry("POLYGON((0 0,0 7,4 2,2 0,0 0))", 16.0); + test_geometry("POLYGON((1 1,2 1,2 2,1 2,1 1))", -1.0); + test_geometry("POLYGON((0 0,0 7,4 2,2 0,0 0), (1 1,2 1,2 2,1 2,1 1))", 15.0); +} + + +template +void test_all() +{ + test_geometry >("POLYGON((0 0,2 2))", 4.0); + test_geometry >("POLYGON((2 2,0 0))", 4.0); + + test_polygon >(); + test_polygon >(); + + // clockwise rings (second is wrongly ordered) + test_geometry >("POLYGON((0 0,0 7,4 2,2 0,0 0))", 16.0); + test_geometry >("POLYGON((0 0,2 0,4 2,0 7,0 0))", -16.0); + + test_geometry >("POLYGON((0 0,0 7,4 2,2 0,0 0))", 16.0); + + // ccw + test_geometry > + ("POLYGON((0 0,0 7,4 2,2 0,0 0), (1 1,2 1,2 2,1 2,1 1))", -15.0); + + test_geometry > + ("POLYGON((1 0,0 1,-1 0,0 -1,1 0))", 2); + + typedef typename bg::coordinate_type

::type coord_type; + if (BOOST_GEOMETRY_CONDITION((boost::is_same::value))) + { + test_geometry > + ("POLYGON((100000001 100000000, 100000000 100000001, \ + 99999999 100000000, 100000000 99999999))", 2); + } + else if (BOOST_GEOMETRY_CONDITION((boost::is_same::value))) + { + test_geometry > + ("POLYGON((100001 100000, 100000 100001, \ + 99999 100000, 100000 99999))", 2); + } +} + +template +void test_ccw() +{ + typedef typename bg::coordinate_type

::type ct; + bg::model::polygon ccw_polygon; + // counterclockwise rings (second is wrongly ordered) + std::string poly1 = "POLYGON((1 1,2 2,3 1,2 0,1 1))"; + std::string poly2 = "POLYGON((1 1,2 0,3 1,2 2,1 1))"; + std::string poly3 = "POLYGON((0 0,0 7,4 2,2 0,0 0))"; + std::string poly4 = "POLYGON((0 0,2 0,4 2,0 7,0 0))"; + + bg::read_wkt(poly1, ccw_polygon); + ct area1 = bg::area(ccw_polygon); + bg::read_wkt(poly2, ccw_polygon); + ct area2 = bg::area(ccw_polygon); + bg::read_wkt(poly3, ccw_polygon); + ct area3 = bg::area(ccw_polygon); + bg::read_wkt(poly4, ccw_polygon); + ct area4 = bg::area(ccw_polygon); + BOOST_CHECK_CLOSE(area1, -1 * area2, 0.001); + BOOST_CHECK_CLOSE(area3, -1 * area4, 0.001); +} + +template +void test_open(CT expected_area) +{ + typedef bg::model::polygon open_polygon; + test_geometry("POLYGON((1 1,2 2,3 1,2 0))", expected_area); + // Note the triangular testcase used in CCW is not sensible for open/close +} + +template +void test_open_ccw(CT expected_area) +{ + typedef bg::model::polygon open_polygon; + test_geometry("POLYGON((1 1,2 0,3 1,2 2))", expected_area); + // Note the triangular testcase used in CCW is not sensible for open/close +} + +template +void test_poles_ccw() +{ + typedef typename bg::coordinate_type

::type ct; + bg::model::polygon polygon; + + std::string poly1 = "POLYGON((45 45,45 95,95 45,45 45))"; + std::string poly2 = "POLYGON((45 45,95 45,45 95,45 45))"; + std::string poly3 = "POLYGON((45 -45,45 -95,95 -45,45 -45))"; + std::string poly4 = "POLYGON((45 -45,95 -45,45 -95,45 -45))"; + + bg::read_wkt(poly1, polygon); + ct area1 = bg::area(polygon); + bg::read_wkt(poly2, polygon); + ct area2 = bg::area(polygon); + bg::read_wkt(poly3, polygon); + ct area3 = bg::area(polygon); + bg::read_wkt(poly4, polygon); + ct area4 = bg::area(polygon); + BOOST_CHECK_CLOSE(area1, -1 * area2, 0.001); + BOOST_CHECK_CLOSE(area3, -1 * area4, 0.001); +} + +template +void test_empty_input() +{ + bg::model::polygon

poly_empty; + bg::model::ring

ring_empty; + + test_empty_input(poly_empty); + test_empty_input(ring_empty); +} + +void test_large_integers() +{ + typedef bg::model::point int_point_type; + typedef bg::model::point double_point_type; + + bg::model::polygon int_poly; + bg::model::polygon double_poly; + + std::string const polygon_li = "POLYGON((1872000 528000,1872000 192000,\ + 1536119 192000,1536000 528000,1200000 528000,\ + 1200000 863880,1536000 863880,1872000 863880,\ + 1872000 528000))"; + bg::read_wkt(polygon_li, int_poly); + bg::read_wkt(polygon_li, double_poly); + + double int_area = bg::area(int_poly); + double double_area = bg::area(double_poly); + + BOOST_CHECK_CLOSE(int_area, double_area, 0.0001); +} + +void test_variant() +{ + typedef bg::model::point double_point_type; + typedef bg::model::polygon polygon_type; + typedef bg::model::box box_type; + + polygon_type poly; + std::string const polygon_li = "POLYGON((18 5,18 1,15 1,15 5,12 5,12 8,15 8,18 8,18 5))"; + bg::read_wkt(polygon_li, poly); + + box_type box; + std::string const box_li = "BOX(0 0,2 2)"; + bg::read_wkt(box_li, box); + + boost::variant v; + + v = poly; + BOOST_CHECK_CLOSE(bg::area(v), bg::area(poly), 0.0001); + v = box; + BOOST_CHECK_CLOSE(bg::area(v), bg::area(box), 0.0001); +} + +int test_main(int, char* []) +{ + + test_all >(); + test_all >(); + test_all >(); + + typedef bg::model::point pt_crt; + typedef bg::model::point > pt_sph; + typedef bg::model::point > pt_geo; + + test_ccw(); + test_ccw(); + test_ccw(); + + test_open(2.0); + test_open(24726179921.523518); + test_open(24615760871.487991); + + test_open_ccw(2.0); + test_open_ccw(24726179921.523518); + test_open_ccw(24615760871.487991); + + test_poles_ccw(); + test_poles_ccw(); + test_poles_ccw(); + +#ifdef HAVE_TTMATH + test_all >(); + test_spherical_geo(); +#endif + + test_large_integers(); + + test_variant(); + + // test_empty_input >(); + + return 0; +} diff --git a/test/algorithms/area/area_geo.cpp b/test/algorithms/area/area_geo.cpp new file mode 100644 index 000000000..9a88eccf9 --- /dev/null +++ b/test/algorithms/area/area_geo.cpp @@ -0,0 +1,284 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// Unit Test + +// This file was modified by Oracle on 2015, 2016. +// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. + +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle + +// 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) + +#include +#include + +namespace bg = boost::geometry; + +//Testing geographic strategies +template +void test_geo_strategies() +{ + std::string poly = "POLYGON((52 0, 41 -74, -23 -43, -26 28, 52 0))"; + + typedef bg::model::point > pt_geo; + + typedef typename bg::point_type::type pt_geo_type; + + bg::strategy::area::geographic + geographic_default; + + bg::strategy::area::geographic + < + pt_geo_type, + bg::formula::andoyer_inverse, + 1, + true + > geographic_andoyer1; + bg::strategy::area::geographic + < + pt_geo_type, + bg::formula::andoyer_inverse, + 2, + true + > geographic_andoyer2; + bg::strategy::area::geographic + < + pt_geo_type, + bg::formula::andoyer_inverse, + 3, + true + > geographic_andoyer3; + bg::strategy::area::geographic + < + pt_geo_type, + bg::formula::andoyer_inverse, + 4, + true + > geographic_andoyer4; + bg::strategy::area::geographic + < + pt_geo_type, + bg::formula::andoyer_inverse, + 5, + true + > geographic_andoyer5; + + bg::strategy::area::geographic + < + pt_geo_type, + bg::formula::thomas_inverse, + 1, + true + > geographic_thomas1; + bg::strategy::area::geographic + < + pt_geo_type, + bg::formula::thomas_inverse, + 2, + true + > geographic_thomas2; + bg::strategy::area::geographic + < + pt_geo_type, + bg::formula::thomas_inverse, + 3, + true + > geographic_thomas3; + bg::strategy::area::geographic + < + pt_geo_type, + bg::formula::thomas_inverse, + 4, + true + > geographic_thomas4; + bg::strategy::area::geographic + < + pt_geo_type, + bg::formula::thomas_inverse, + 5, + true + > geographic_thomas5; + + bg::strategy::area::geographic + < + pt_geo_type, + bg::formula::vincenty_inverse, + 1, + true + > geographic_vincenty1; + bg::strategy::area::geographic + < + pt_geo_type, + bg::formula::vincenty_inverse, + 2, + true + > geographic_vincenty2; + bg::strategy::area::geographic + < + pt_geo_type, + bg::formula::vincenty_inverse, + 3, + true + > geographic_vincenty3; + bg::strategy::area::geographic + < + pt_geo_type, + bg::formula::vincenty_inverse, + 4, + true + > geographic_vincenty4; + bg::strategy::area::geographic + < + pt_geo_type, + bg::formula::vincenty_inverse, + 5, + true + > geographic_vincenty5; + + bg::strategy::area::geographic + < + pt_geo_type, + bg::formula::vincenty_inverse, + 5 + > geographic_vincenty5_default; + + bg::strategy::area::geographic + < + pt_geo_type, + bg::formula::vincenty_inverse + > geographic_vincenty_default; + + bg::model::polygon geometry_geo; + + //GeographicLib 63316536351834.289 + //PostGIS (v2.2.2) 6.33946+13 + //MS SQL SERVER 632930207487035 + + bg::read_wkt(poly, geometry_geo); + CT area; + CT err = 0.0000001; + + CT area_default = bg::area(geometry_geo); + BOOST_CHECK_CLOSE(area_default, 63316536092341.266, err); + area = bg::area(geometry_geo, geographic_default); + BOOST_CHECK_CLOSE(area, 63316536092341.266, err); + + CT area_less_accurate = bg::area(geometry_geo, geographic_andoyer1); + BOOST_CHECK_CLOSE(area_less_accurate, 63316309346280.18, err); + area = bg::area(geometry_geo, geographic_andoyer2); + BOOST_CHECK_CLOSE(area, 63316309224306.5, err); + area = bg::area(geometry_geo, geographic_andoyer3); + BOOST_CHECK_CLOSE(area, 63316309224411.195, err); + area = bg::area(geometry_geo, geographic_andoyer4); + BOOST_CHECK_CLOSE(area, 63316309224411.094, err); + area = bg::area(geometry_geo, geographic_andoyer5); + BOOST_CHECK_CLOSE(area, 63316309224411.094, err); + + area = bg::area(geometry_geo, geographic_thomas1); + BOOST_CHECK_CLOSE(area, 63316536214315.32, err); + area = bg::area(geometry_geo, geographic_thomas2); + BOOST_CHECK_CLOSE(area, 63316536092341.266, err); + area = bg::area(geometry_geo, geographic_thomas3); + BOOST_CHECK_CLOSE(area, 63316536092445.961, err); + area = bg::area(geometry_geo, geographic_thomas4); + BOOST_CHECK_CLOSE(area, 63316536092445.859, err); + area = bg::area(geometry_geo, geographic_thomas5); + BOOST_CHECK_CLOSE(area, 63316536092445.859, err); + + area = bg::area(geometry_geo, geographic_vincenty1); + BOOST_CHECK_CLOSE(area, 63316536473798.984, err); + area = bg::area(geometry_geo, geographic_vincenty2); + BOOST_CHECK_CLOSE(area, 63316536351824.93, err); + area = bg::area(geometry_geo, geographic_vincenty3); + BOOST_CHECK_CLOSE(area, 63316536351929.625, err); + area = bg::area(geometry_geo, geographic_vincenty4); + BOOST_CHECK_CLOSE(area, 63316536351929.523, err); + CT area_most_accurate = bg::area(geometry_geo, geographic_vincenty5); + BOOST_CHECK_CLOSE(area, 63316536351929.523, err); + + area = bg::area(geometry_geo, geographic_vincenty5_default); + BOOST_CHECK_CLOSE(area, 63316536351929.523, err); + area = bg::area(geometry_geo, geographic_vincenty_default); + BOOST_CHECK_CLOSE(area, 63316536351824.93, err); + + BOOST_CHECK_CLOSE(area_most_accurate, area_less_accurate, .001); + BOOST_CHECK_CLOSE(area_most_accurate, area_default, .000001); +/* + // timings and accuracy + std::cout.precision(25); + std::size_t exp_times = 100000; + { clock_t startTime = clock(); + for (int j=0; j < exp_times; j++) area = bg::area(geometry_geo, geographic_andoyer1); + std::cout << double( clock() - startTime ) / (double)CLOCKS_PER_SEC<< " "; + std::cout << area << std::endl;} + { clock_t startTime = clock(); + for (int j=0; j < exp_times; j++) area = bg::area(geometry_geo, geographic_andoyer2); + std::cout << double( clock() - startTime ) / (double)CLOCKS_PER_SEC<< " "; + std::cout << area << std::endl;} + { clock_t startTime = clock(); + for (int j=0; j < exp_times; j++) area = bg::area(geometry_geo, geographic_andoyer3); + std::cout << double( clock() - startTime ) / (double)CLOCKS_PER_SEC<< " "; + std::cout << area << std::endl;} + { clock_t startTime = clock(); + for (int j=0; j < exp_times; j++) area = bg::area(geometry_geo, geographic_andoyer4); + std::cout << double( clock() - startTime ) / (double)CLOCKS_PER_SEC<< " "; + std::cout << area << std::endl;} + { clock_t startTime = clock(); + for (int j=0; j < exp_times; j++) area = bg::area(geometry_geo, geographic_andoyer5); + std::cout << double( clock() - startTime ) / (double)CLOCKS_PER_SEC<< " "; + std::cout << area << std::endl;} + { clock_t startTime = clock(); + for (int j=0; j < exp_times; j++) area = bg::area(geometry_geo, geographic_thomas1); + std::cout << double( clock() - startTime ) / (double)CLOCKS_PER_SEC<< " "; + std::cout << area << std::endl;} + { clock_t startTime = clock(); + for (int j=0; j < exp_times; j++) area = bg::area(geometry_geo, geographic_thomas2); + std::cout << double( clock() - startTime ) / (double)CLOCKS_PER_SEC<< " "; + std::cout << area << std::endl;} + { clock_t startTime = clock(); + for (int j=0; j < exp_times; j++) area = bg::area(geometry_geo, geographic_thomas3); + std::cout << double( clock() - startTime ) / (double)CLOCKS_PER_SEC<< " "; + std::cout << area << std::endl;} + { clock_t startTime = clock(); + for (int j=0; j < exp_times; j++) area = bg::area(geometry_geo, geographic_thomas4); + std::cout << double( clock() - startTime ) / (double)CLOCKS_PER_SEC<< " "; + std::cout << area << std::endl;} + { clock_t startTime = clock(); + for (int j=0; j < exp_times; j++) area = bg::area(geometry_geo, geographic_thomas5); + std::cout << double( clock() - startTime ) / (double)CLOCKS_PER_SEC<< " "; + std::cout << area << std::endl;} + { clock_t startTime = clock(); + for (int j=0; j < exp_times; j++) area = bg::area(geometry_geo, geographic_vincenty1); + std::cout << double( clock() - startTime ) / (double)CLOCKS_PER_SEC<< " "; + std::cout << area << std::endl;} + { clock_t startTime = clock(); + for (int j=0; j < exp_times; j++) area = bg::area(geometry_geo, geographic_vincenty2); + std::cout << double( clock() - startTime ) / (double)CLOCKS_PER_SEC<< " "; + std::cout << area << std::endl;} + { clock_t startTime = clock(); + for (int j=0; j < exp_times; j++) area = bg::area(geometry_geo, geographic_vincenty3); + std::cout << double( clock() - startTime ) / (double)CLOCKS_PER_SEC<< " "; + std::cout << area << std::endl;} + { clock_t startTime = clock(); + for (int j=0; j < exp_times; j++) area = bg::area(geometry_geo, geographic_vincenty4); + std::cout << double( clock() - startTime ) / (double)CLOCKS_PER_SEC<< " "; + std::cout << area << std::endl;} + { clock_t startTime = clock(); + for (int j=0; j < exp_times; j++) area = bg::area(geometry_geo, geographic_vincenty5); + std::cout << double( clock() - startTime ) / (double)CLOCKS_PER_SEC<< " "; + std::cout << area << std::endl;} +*/ +} + +int test_main(int, char* []) +{ + + test_geo_strategies(); + + return 0; +} diff --git a/test/algorithms/area/area_multi.cpp b/test/algorithms/area/area_multi.cpp new file mode 100644 index 000000000..b351a9c01 --- /dev/null +++ b/test/algorithms/area/area_multi.cpp @@ -0,0 +1,52 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// +// This file was modified by Oracle on 2015, 2016. +// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. +// +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle +// +// 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) + + +#include + +#include +#include +#include + +#include + + + + +template +void test_all() +{ + typedef typename bg::model::d2::point_xy pt_crt; + typedef typename bg::model::point > pt_sph; + typedef typename bg::model::point > pt_geo; + + typedef bg::model::multi_polygon > mp_crt; + typedef bg::model::multi_polygon > mp_sph; + typedef bg::model::multi_polygon > mp_geo; + + std::string poly = "MULTIPOLYGON(((0 0,0 7,4 2,2 0,0 0)))"; + test_geometry(poly, 16.0); + test_geometry(poly, 197897454752.69489); + test_geometry(poly, 197022175077.78613); +} + +int test_main( int , char* [] ) +{ + test_all(); + +#ifdef HAVE_TTMATH + test_all >(); +#endif + + return 0; +} diff --git a/test/algorithms/area/area_sph_geo.cpp b/test/algorithms/area/area_sph_geo.cpp new file mode 100644 index 000000000..41e3a86a4 --- /dev/null +++ b/test/algorithms/area/area_sph_geo.cpp @@ -0,0 +1,399 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// Unit Test + +// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. + +// This file was modified by Oracle on 2015, 2016. +// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. + +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle +// Contributed and/or modified by 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. + +// 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) + +#include +#include + +namespace bg = boost::geometry; + +//Testing spherical and geographic strategies +template +void test_spherical_geo() +{ + typedef CT ct; + + //Geographic + + typedef typename bg::model::point< + ct, + 2, + bg::cs::geographic + > pt_geo; + + typedef typename bg::point_type::type pt_geo_type; + + bg::strategy::area::geographic + < + pt_geo_type, + bg::formula::vincenty_inverse, + 5 + > area_geographic; + + bg::model::polygon geometry_geo; + + //Spherical + + typedef typename bg::model::point< + ct, + 2, + bg::cs::spherical_equatorial + > pt; + bg::model::polygon geometry; + + // unit-sphere has area of 4-PI. Polygon covering 1/8 of it: + // calculations splitted for ttmath + std::string poly = "POLYGON((0 0,0 90,90 0,0 0))"; + + bg::strategy::area::spherical + < + typename bg::point_type::type + > strategy_unary(1.0); + + ct const four = 4.0; + ct const eight = 8.0; + ct expected = four * boost::geometry::math::pi() / eight; + bg::read_wkt(poly, geometry); + ct area = bg::area(geometry, strategy_unary); + BOOST_CHECK_CLOSE(area, expected, 0.0001); + + // With strategy, radius 2 -> 4 pi r^2 + bg::strategy::area::spherical + < + typename bg::point_type::type + > strategy(2.0); + + area = bg::area(geometry, strategy); + ct const two = 2.0; + BOOST_CHECK_CLOSE(area, two * two * expected, 0.0001); + + // Geographic total area of earth is about 510065626583900.6 (WGS84 ellipsoid) + // (510072000 in https://en.wikipedia.org/wiki/Earth) + // So the 1/8 is 6.375820332×10^13 and here we get something close to it + bg::read_wkt(poly, geometry_geo); + area = bg::area(geometry_geo, area_geographic); + //GeoGraphicLib gives: 63758202715511.055 + BOOST_CHECK_CLOSE(area, 63758202715509.844, 0.0001); + + + // Wrangel Island (dateline crossing) + // With (spherical) Earth strategy + poly = "POLYGON((-178.7858 70.7852, 177.4758 71.2333, 179.7436 71.5733, -178.7858 70.7852))"; + + bg::strategy::area::spherical + < + typename bg::point_type::type + > spherical_earth(6373); + bg::read_wkt(poly, geometry); + area = bg::area(geometry, spherical_earth); + // SQL Server gives: 4537.9654419375 + // PostGIS gives: 4537.9311668307 + // Note: those are Geographic, this test is Spherical + BOOST_CHECK_CLOSE(area, 4506.6389, 0.001); + + bg::read_wkt(poly, geometry_geo); + area = bg::area(geometry_geo, area_geographic); + BOOST_CHECK_CLOSE(area, 4537929936.5349159, 0.0001); + + // Wrangel, more in detail + poly = "POLYGON((-178.568604 71.564148,-178.017548 71.449692,-177.833313 71.3461,\ + -177.502838 71.277466 ,-177.439453 71.226929,-177.620026 71.116638,\ + -177.9389 71.037491,-178.8186 70.979965,-179.274445 70.907761,\ + -180 70.9972,179.678314 70.895538,179.272766 70.888596,\ + 178.791016 70.7964,178.617737 71.035538,178.872192 71.217484,\ + 179.530273 71.4383 ,-180 71.535843 ,-179.628601 71.577194,\ + -179.305298 71.551361,-179.03421 71.597748,-178.568604 71.564148))"; + bg::read_wkt(poly, geometry); + area = bg::area(geometry, spherical_earth); + // SQL Server gives: 7669.10402181435 + // PostGIS gives: 7669.55565459832 + BOOST_CHECK_CLOSE(area, 7616.523769, 0.001); + + bg::read_wkt(poly, geometry_geo); + area = bg::area(geometry_geo, area_geographic); + BOOST_CHECK_CLOSE(area, 7669498457.4130802, 0.0001); + + // Check more at the equator + /* + select 1,geography::STGeomFromText('POLYGON((-178.7858 10.7852 , 179.7436 11.5733 , \ + 177.4758 11.2333 , -178.7858 10.7852))',4326) .STArea()/1000000.0 + union select 2,geography::STGeomFromText('POLYGON((-178.7858 20.7852 , 179.7436 21.5733 ,\ + 177.4758 21.2333 , -178.7858 20.7852))',4326) .STArea()/1000000.0 + union select 3,geography::STGeomFromText('POLYGON((-178.7858 30.7852 , 179.7436 31.5733 , \ + 177.4758 31.2333 , -178.7858 30.7852))',4326) .STArea()/1000000.0 + union select 0,geography::STGeomFromText('POLYGON((-178.7858 0.7852 , 179.7436 1.5733 , \ + 177.4758 1.2333 , -178.7858 0.7852))',4326) .STArea()/1000000.0 + union select 4,geography::STGeomFromText('POLYGON((-178.7858 40.7852 , 179.7436 41.5733 , \ + 177.4758 41.2333 , -178.7858 40.7852))',4326) .STArea()/1000000.0 + */ + + poly = "POLYGON((-178.7858 0.7852, 177.4758 1.2333, 179.7436 1.5733, -178.7858 0.7852))"; + bg::read_wkt(poly, geometry); + area = bg::area(geometry, spherical_earth); + BOOST_CHECK_CLOSE(area, 14136.09946, 0.001); // SQL Server gives: 14064.1902284513 + bg::read_wkt(poly, geometry_geo); + area = bg::area(geometry_geo, area_geographic); + BOOST_CHECK_CLOSE(area, 14064129044.674297, 0.0001); + + poly = "POLYGON((-178.7858 10.7852, 177.4758 11.2333, 179.7436 11.5733, -178.7858 10.7852))"; + bg::read_wkt(poly, geometry); + area = bg::area(geometry, spherical_earth); + BOOST_CHECK_CLOSE(area, 13760.2456, 0.001); // SQL Server gives: 13697.0941155193 + bg::read_wkt(poly, geometry_geo); + area = bg::area(geometry_geo, area_geographic); + BOOST_CHECK_CLOSE(area, 13696308940.315653, 0.0001); + + poly = "POLYGON((-178.7858 20.7852, 177.4758 21.2333, 179.7436 21.5733, -178.7858 20.7852))"; + bg::read_wkt(poly, geometry); + area = bg::area(geometry, spherical_earth); + BOOST_CHECK_CLOSE(area, 12987.8682, 0.001); // SQL Server gives: 12944.3970990317 -> -39m^2 + bg::read_wkt(poly, geometry_geo); + area = bg::area(geometry_geo, area_geographic); + BOOST_CHECK_CLOSE(area, 12943176284.560806, 0.0001); + + poly = "POLYGON((-178.7858 30.7852, 177.4758 31.2333, 179.7436 31.5733, -178.7858 30.7852))"; + bg::read_wkt(poly, geometry); + area = bg::area(geometry, spherical_earth); + BOOST_CHECK_CLOSE(area, 11856.3935, 0.001); // SQL Server gives: 11838.5338423574 -> -18m^2 + bg::read_wkt(poly, geometry_geo); + area = bg::area(geometry_geo, area_geographic); + BOOST_CHECK_CLOSE(area, 11837280445.349375, 0.0001); + + poly = "POLYGON((-178.7858 40.7852, 177.4758 41.2333, 179.7436 41.5733, -178.7858 40.7852))"; + bg::read_wkt(poly, geometry); + area = bg::area(geometry, spherical_earth); + BOOST_CHECK_CLOSE(area, 10404.627685523914, 0.001); + // SQL Server gives: 10412.0607137119, -> +8m^2 + bg::read_wkt(poly, geometry_geo); + area = bg::area(geometry_geo, area_geographic); + BOOST_CHECK_CLOSE(area, 10411098789.39222, 0.0001); + + // Concave + poly = "POLYGON((0 40,1 42,0 44,2 43,4 44,3 42,4 40,2 41,0 40))"; + bg::read_wkt(poly, geometry); + area = bg::area(geometry, spherical_earth); + BOOST_CHECK_CLOSE(area, 73538.2958, 0.001); // SQL Server gives: 73604.2047689719 + bg::read_wkt(poly, geometry_geo); + area = bg::area(geometry_geo, area_geographic); + BOOST_CHECK_CLOSE(area, 73604208172.719223, 0.0001); + + // With hole POLYGON((0 40,4 40,4 44,0 44,0 40),(1 41,2 43,3 42,1 41)) + poly = "POLYGON((0 40,0 44,4 44,4 40,0 40),(1 41,3 42,2 43,1 41))"; + bg::read_wkt(poly, geometry); + area = bg::area(geometry, spherical_earth); + BOOST_CHECK_CLOSE(area, 133233.844876, 0.001); // SQL Server gives: 133353.335 + bg::read_wkt(poly, geometry_geo); + area = bg::area(geometry_geo, area_geographic); + BOOST_CHECK_CLOSE(area, 133353077343.10347, 0.0001); + + // around 0 meridian + { + std::string poly1 = "POLYGON((-10 0,-10 10,0 10,0 0,-10 0))"; + std::string poly2 = "POLYGON((0 0,0 10,10 10,10 0,0 0))"; + std::string poly3 = "POLYGON((-5 0,-5 10,5 10,5 0,-5 0))"; + bg::read_wkt(poly1, geometry); + ct area1 = bg::area(geometry); + bg::read_wkt(poly2, geometry); + ct area2 = bg::area(geometry); + bg::read_wkt(poly3, geometry); + ct area3 = bg::area(geometry); + BOOST_CHECK_CLOSE(area1, area2, 0.001); + BOOST_CHECK_CLOSE(area2, area3, 0.001); + BOOST_CHECK_CLOSE(area1, 1233204227903.1848, 0.001); + //geographic + bg::read_wkt(poly1, geometry_geo); + area1 = bg::area(geometry_geo, area_geographic); + bg::read_wkt(poly2, geometry_geo); + area2 = bg::area(geometry_geo, area_geographic); + bg::read_wkt(poly3, geometry_geo); + area3 = bg::area(geometry_geo, area_geographic); + BOOST_CHECK_CLOSE(area1, area2, 0.001); + BOOST_CHECK_CLOSE(area2, area3, 0.001); + BOOST_CHECK_CLOSE(area1, 1227877191611.2805, 0.001); + } + { + std::string poly1 = "POLYGON((-10 -5,-10 5,0 5,0 -5,-10 -5))"; + std::string poly2 = "POLYGON((0 -5,0 5,10 5,10 -5,0 -5))"; + std::string poly3 = "POLYGON((-5 -5,-5 5,5 5,5 -5,-5 -5))"; + bg::read_wkt(poly1, geometry); + ct area1 = bg::area(geometry); + bg::read_wkt(poly2, geometry); + ct area2 = bg::area(geometry); + bg::read_wkt(poly3, geometry); + ct area3 = bg::area(geometry); + BOOST_CHECK_CLOSE(area1, area2, 0.001); + BOOST_CHECK_CLOSE(area2, area3, 0.001); + BOOST_CHECK_CLOSE(area1, 1237986107636.0261, 0.001); + //geographic + bg::read_wkt(poly1, geometry_geo); + area1 = bg::area(geometry_geo, area_geographic); + bg::read_wkt(poly2, geometry_geo); + area2 = bg::area(geometry_geo, area_geographic); + bg::read_wkt(poly3, geometry_geo); + area3 = bg::area(geometry_geo, area_geographic); + BOOST_CHECK_CLOSE(area1, area2, 0.001); + BOOST_CHECK_CLOSE(area2, area3, 0.001); + BOOST_CHECK_CLOSE(area1, 1232514639151.6477, 0.001); + } + // around 180 meridian + { + std::string poly1 = "POLYGON((-180 0,-180 10,-170 10,-170 0,-180 0))"; + std::string poly2 = "POLYGON((175 0,175 10,-175 10,-175 0,175 0))"; + std::string poly3 = "POLYGON((170 0,170 10,180 10,180 0,170 0))"; + std::string poly4 = "POLYGON((170 0,170 10,-180 10,-180 0,170 0))"; + std::string poly5 = "POLYGON((180 0,180 10,-170 10,-170 0,180 0))"; + bg::read_wkt(poly1, geometry); + ct area1 = bg::area(geometry); + bg::read_wkt(poly2, geometry); + ct area2 = bg::area(geometry); + bg::read_wkt(poly3, geometry); + ct area3 = bg::area(geometry); + bg::read_wkt(poly4, geometry); + ct area4 = bg::area(geometry); + bg::read_wkt(poly5, geometry); + ct area5 = bg::area(geometry); + BOOST_CHECK_CLOSE(area1, area2, 0.001); + BOOST_CHECK_CLOSE(area2, area3, 0.001); + BOOST_CHECK_CLOSE(area3, area4, 0.001); + BOOST_CHECK_CLOSE(area4, area5, 0.001); + BOOST_CHECK_CLOSE(area1, 1233204227903.1833, 0.001); + //geographic + bg::read_wkt(poly1, geometry_geo); + area1 = bg::area(geometry_geo, area_geographic); + bg::read_wkt(poly2, geometry_geo); + area2 = bg::area(geometry_geo, area_geographic); + bg::read_wkt(poly3, geometry_geo); + area3 = bg::area(geometry_geo, area_geographic); + bg::read_wkt(poly4, geometry_geo); + area4 = bg::area(geometry_geo, area_geographic); + bg::read_wkt(poly5, geometry_geo); + area5 = bg::area(geometry_geo, area_geographic); + BOOST_CHECK_CLOSE(area1, area2, 0.001); + BOOST_CHECK_CLOSE(area2, area3, 0.001); + BOOST_CHECK_CLOSE(area3, area4, 0.001); + BOOST_CHECK_CLOSE(area4, area5, 0.001); + BOOST_CHECK_CLOSE(area1, 1227877191611.2805, 0.001); + } + { + std::string poly1 = "POLYGON((-180 -5,-180 5,-170 5,-170 -5,-180 -5))"; + std::string poly2 = "POLYGON((175 -5,175 5,-175 5,-175 -5,175 -5))"; + std::string poly3 = "POLYGON((170 -5,170 5,180 5,180 -5,170 -5))"; + std::string poly4 = "POLYGON((170 -5,170 5,180 5,180 -5,170 -5))"; + std::string poly5 = "POLYGON((180 -5,180 5,-170 5,-170 -5,180 -5))"; + bg::read_wkt(poly1, geometry); + ct area1 = bg::area(geometry); + bg::read_wkt(poly2, geometry); + ct area2 = bg::area(geometry); + bg::read_wkt(poly3, geometry); + ct area3 = bg::area(geometry); + bg::read_wkt(poly4, geometry); + ct area4 = bg::area(geometry); + bg::read_wkt(poly5, geometry); + ct area5 = bg::area(geometry); + BOOST_CHECK_CLOSE(area1, area2, 0.001); + BOOST_CHECK_CLOSE(area2, area3, 0.001); + BOOST_CHECK_CLOSE(area3, area4, 0.001); + BOOST_CHECK_CLOSE(area4, area5, 0.001); + BOOST_CHECK_CLOSE(area1, 1237986107636.0247, 0.001); + //geographic + bg::read_wkt(poly1, geometry_geo); + area1 = bg::area(geometry_geo, area_geographic); + bg::read_wkt(poly2, geometry_geo); + area2 = bg::area(geometry_geo, area_geographic); + bg::read_wkt(poly3, geometry_geo); + area3 = bg::area(geometry_geo, area_geographic); + bg::read_wkt(poly4, geometry_geo); + area4 = bg::area(geometry_geo, area_geographic); + bg::read_wkt(poly5, geometry_geo); + area5 = bg::area(geometry_geo, area_geographic); + BOOST_CHECK_CLOSE(area1, area2, 0.001); + BOOST_CHECK_CLOSE(area2, area3, 0.001); + BOOST_CHECK_CLOSE(area3, area4, 0.001); + BOOST_CHECK_CLOSE(area4, area5, 0.001); + BOOST_CHECK_CLOSE(area1, 1232514639151.6477, 0.001); + } + // around poles + { + std::string poly1 = "POLYGON((0 80,-90 80,-180 80,90 80,0 80))"; + std::string poly2 = "POLYGON((0 80,-90 80,180 80,90 80,0 80))"; + std::string poly3 = "POLYGON((0 -80,90 -80,-180 -80,-90 -80,0 -80))"; + std::string poly4 = "POLYGON((0 -80,90 -80,180 -80,-90 -80,0 -80))"; + bg::read_wkt(poly1, geometry); + ct area1 = bg::area(geometry); + bg::read_wkt(poly2, geometry); + ct area2 = bg::area(geometry); + bg::read_wkt(poly3, geometry); + ct area3 = bg::area(geometry); + bg::read_wkt(poly4, geometry); + ct area4 = bg::area(geometry); + BOOST_CHECK_CLOSE(area1, area2, 0.001); + BOOST_CHECK_CLOSE(area2, area3, 0.001); + BOOST_CHECK_CLOSE(area3, area4, 0.001); + //geographic + bg::read_wkt(poly1, geometry_geo); + area1 = bg::area(geometry_geo, area_geographic); + bg::read_wkt(poly2, geometry_geo); + area2 = bg::area(geometry_geo, area_geographic); + bg::read_wkt(poly3, geometry_geo); + area3 = bg::area(geometry_geo, area_geographic); + bg::read_wkt(poly4, geometry_geo); + area4 = bg::area(geometry_geo, area_geographic); + BOOST_CHECK_CLOSE(area1, area2, 0.001); + BOOST_CHECK_CLOSE(area2, area3, 0.001); + BOOST_CHECK_CLOSE(area3, area4, 0.001); + } + + { + bg::model::ring aurha; // a'dam-utr-rott.-den haag-a'dam + std::string poly = "POLYGON((4.892 52.373,5.119 52.093,4.479 51.930,\ + 4.23 52.08,4.892 52.373))"; + bg::read_wkt(poly, aurha); + /*if (polar) + { + // Create colatitudes (measured from pole) + BOOST_FOREACH(pt& p, aurha) + { + bg::set<1>(p, ct(90) - bg::get<1>(p)); + } + bg::correct(aurha); + }*/ + bg::strategy::area::spherical + < + typename bg::point_type::type + > area_spherical(6372.795); + area = bg::area(aurha, area_spherical); + BOOST_CHECK_CLOSE(area, 1476.645675, 0.0001); + //geographic + bg::read_wkt(poly, geometry_geo); + area = bg::area(geometry_geo, area_geographic); + BOOST_CHECK_CLOSE(area, 1481555970.0765088, 0.001); + + // SQL Server gives: 1481.55595960659 + // for select geography::STGeomFromText('POLYGON((4.892 52.373,4.23 52.08, + // 4.479 51.930,5.119 52.093,4.892 52.373))',4326).STArea()/1000000.0 + } +} + +int test_main(int, char* []) +{ + + test_spherical_geo(); + + return 0; +} diff --git a/test/algorithms/test_area.hpp b/test/algorithms/area/test_area.hpp similarity index 100% rename from test/algorithms/test_area.hpp rename to test/algorithms/area/test_area.hpp diff --git a/test/algorithms/area_multi.cpp b/test/algorithms/area_multi.cpp deleted file mode 100644 index fdb9ea6d7..000000000 --- a/test/algorithms/area_multi.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// Boost.Geometry (aka GGL, Generic Geometry Library) -// -// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. -// Use, modification and distribution is subject to the Boost Software License, -// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#include - -#include -#include -#include - -#include - - - - -template -void test_all() -{ - typedef bg::model::multi_polygon > mp; - test_geometry("MULTIPOLYGON(((0 0,0 7,4 2,2 0,0 0)))", 16.0); -} - -int test_main( int , char* [] ) -{ - test_all >(); - -#ifdef HAVE_TTMATH - test_all >(); -#endif - - return 0; -} diff --git a/test/algorithms/buffer/test_buffer.hpp b/test/algorithms/buffer/test_buffer.hpp index d2efb397b..875736796 100644 --- a/test/algorithms/buffer/test_buffer.hpp +++ b/test/algorithms/buffer/test_buffer.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2010-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2016. -// Modifications copyright (c) 2016, Oracle and/or its affiliates. +// This file was modified by Oracle on 2016-2017. +// Modifications copyright (c) 2016-2017, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -97,8 +97,10 @@ template<> struct EndTestProperties -template -std::size_t count_self_ips(Geometry const& geometry, RescalePolicy const& rescale_policy) +template +std::size_t count_self_ips(Geometry const& geometry, + Strategy const& strategy, + RescalePolicy const& rescale_policy) { typedef typename bg::point_type::type point_type; typedef bg::detail::overlay::turn_info @@ -113,7 +115,7 @@ std::size_t count_self_ips(Geometry const& geometry, RescalePolicy const& rescal bg::self_turns < bg::detail::overlay::assign_null_policy - >(geometry, rescale_policy, turns, policy); + >(geometry, strategy, rescale_policy, turns, policy); return turns.size(); } @@ -217,10 +219,15 @@ void test_buffer(std::string const& caseid, Geometry const& geometry, typedef typename bg::point_type::type point_type; typedef typename bg::rescale_policy_type::type rescale_policy_type; + typedef typename bg::strategy::intersection::services::default_strategy + < + typename bg::cs_tag::type + >::type strategy_type; // Enlarge the box to get a proper rescale policy bg::buffer(envelope, envelope, distance_strategy.max_distance(join_strategy, end_strategy)); + strategy_type strategy; rescale_policy_type rescale_policy = bg::get_rescale_policy(envelope); @@ -233,6 +240,7 @@ void test_buffer(std::string const& caseid, Geometry const& geometry, join_strategy, end_strategy, point_strategy, + strategy, rescale_policy, visitor); @@ -262,6 +270,7 @@ void test_buffer(std::string const& caseid, Geometry const& geometry, bg::model::box envelope_output; bg::assign_values(envelope_output, 0, 0, 1, 1); bg::envelope(buffered, envelope_output); + rescale_policy_type rescale_policy_output = bg::get_rescale_policy(envelope_output); @@ -316,7 +325,7 @@ void test_buffer(std::string const& caseid, Geometry const& geometry, try { bool has_self_ips = bg::detail::overlay::has_self_intersections( - buffered, rescale_policy_output, false); + buffered, strategy, rescale_policy_output, false); // Be sure resulting polygon does not contain // self-intersections BOOST_CHECK_MESSAGE @@ -372,9 +381,9 @@ void test_buffer(std::string const& caseid, Geometry const& geometry, { std::size_t count = 0; if (bg::detail::overlay::has_self_intersections(buffered, - rescale_policy_output, false)) + strategy, rescale_policy_output, false)) { - count = count_self_ips(buffered, rescale_policy_output); + count = count_self_ips(buffered, strategy, rescale_policy_output); } *self_ip_count += count; diff --git a/test/algorithms/detail/partition.cpp b/test/algorithms/detail/partition.cpp index bf50b880f..94bd87114 100644 --- a/test/algorithms/detail/partition.cpp +++ b/test/algorithms/detail/partition.cpp @@ -1,6 +1,11 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// +// This file was modified by Oracle on 2017. +// Modifications copyright (c) 2017 Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle +// // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -143,8 +148,8 @@ void test_boxes(std::string const& wkt_box_list, double expected_area, int expec box_visitor visitor; bg::partition < - Box, get_box, ovelaps_box - >::apply(boxes, visitor, 1); + Box + >::apply(boxes, visitor, get_box(), ovelaps_box(), 1); BOOST_CHECK_CLOSE(visitor.area, expected_area, 0.001); BOOST_CHECK_EQUAL(visitor.count, expected_count); @@ -221,8 +226,9 @@ void test_points(std::string const& wkt1, std::string const& wkt2, int expected_ point_visitor visitor; bg::partition < - bg::model::box, get_point, ovelaps_point - >::apply(mp1, mp2, visitor, 1); + bg::model::box + >::apply(mp1, mp2, visitor, get_point(), ovelaps_point(), + get_point(), ovelaps_point(), 1); BOOST_CHECK_EQUAL(visitor.count, expected_count); } @@ -369,12 +375,10 @@ void test_many_points(int seed, int size, int count) bg::partition < bg::model::box, - get_point, ovelaps_point, - get_point, ovelaps_point, bg::detail::partition::include_all_policy, - bg::detail::partition::include_all_policy, - box_visitor_type - >::apply(mp1, mp2, visitor, 2, box_visitor); + bg::detail::partition::include_all_policy + >::apply(mp1, mp2, visitor, get_point(), ovelaps_point(), + get_point(), ovelaps_point(), 2, box_visitor); BOOST_CHECK_EQUAL(visitor.count, expected_count); @@ -479,12 +483,10 @@ void test_many_boxes(int seed, int size, int count) bg::partition < box_type, - get_box, ovelaps_box, - get_box, ovelaps_box, bg::detail::partition::include_all_policy, - bg::detail::partition::include_all_policy, - partition_box_visitor_type - >::apply(boxes, visitor, 2, partition_box_visitor); + bg::detail::partition::include_all_policy + >::apply(boxes, visitor, get_box(), ovelaps_box(), + 2, partition_box_visitor); BOOST_CHECK_EQUAL(visitor.count, expected_count); BOOST_CHECK_CLOSE(visitor.area, expected_area, 0.001); @@ -549,12 +551,10 @@ void test_two_collections(int seed1, int seed2, int size, int count) bg::partition < box_type, - get_box, ovelaps_box, - get_box, ovelaps_box, bg::detail::partition::include_all_policy, - bg::detail::partition::include_all_policy, - partition_box_visitor_type - >::apply(boxes1, boxes2, visitor, 2, partition_box_visitor); + bg::detail::partition::include_all_policy + >::apply(boxes1, boxes2, visitor, get_box(), ovelaps_box(), + get_box(), ovelaps_box(), 2, partition_box_visitor); BOOST_CHECK_EQUAL(visitor.count, expected_count); BOOST_CHECK_CLOSE(visitor.area, expected_area, 0.001); @@ -617,23 +617,19 @@ void test_heterogenuous_collections(int seed1, int seed2, int size, int count) bg::partition < box_type, - get_point, ovelaps_point, - get_box, ovelaps_box, bg::detail::partition::include_all_policy, - bg::detail::partition::include_all_policy, - partition_box_visitor_type - >::apply(points, boxes, visitor1, 2, partition_box_visitor); + bg::detail::partition::include_all_policy + >::apply(points, boxes, visitor1, get_point(), ovelaps_point(), + get_box(), ovelaps_box(), 2, partition_box_visitor); reversed_point_in_box_visitor visitor2; bg::partition < box_type, - get_box, ovelaps_box, - get_point, ovelaps_point, bg::detail::partition::include_all_policy, - bg::detail::partition::include_all_policy, - partition_box_visitor_type - >::apply(boxes, points, visitor2, 2, partition_box_visitor); + bg::detail::partition::include_all_policy + >::apply(boxes, points, visitor2, get_box(), ovelaps_box(), + get_point(), ovelaps_point(), 2, partition_box_visitor); BOOST_CHECK_EQUAL(visitor1.count, expected_count); BOOST_CHECK_EQUAL(visitor2.count, expected_count); diff --git a/test/algorithms/distance/distance.cpp b/test/algorithms/distance/distance.cpp index 76471557f..e1aef1896 100644 --- a/test/algorithms/distance/distance.cpp +++ b/test/algorithms/distance/distance.cpp @@ -18,8 +18,9 @@ #include "test_distance.hpp" -#include #include +#include +#include #include #include diff --git a/test/algorithms/distance/test_distance_common.hpp b/test/algorithms/distance/test_distance_common.hpp index 11ef52c40..d3d722012 100644 --- a/test/algorithms/distance/test_distance_common.hpp +++ b/test/algorithms/distance/test_distance_common.hpp @@ -170,6 +170,11 @@ struct test_distance_of_geometries : public test_distance_of_geometries {}; +#ifdef BOOST_GEOMETRY_TEST_DEBUG +#define ENABLE_IF_DEBUG(ID) ID +#else +#define ENABLE_IF_DEBUG(ID) +#endif template class test_distance_of_geometries @@ -184,7 +189,7 @@ private: typename Strategy > static inline - void base_test(std::string const& header, + void base_test(std::string const& ENABLE_IF_DEBUG(header), G1 const& g1, G2 const& g2, DistanceType const& expected_distance, ComparableDistanceType const& expected_comparable_distance, diff --git a/test/algorithms/envelope_expand/envelope.cpp b/test/algorithms/envelope_expand/envelope.cpp index 047851430..7418b27c6 100644 --- a/test/algorithms/envelope_expand/envelope.cpp +++ b/test/algorithms/envelope_expand/envelope.cpp @@ -5,9 +5,10 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2015. +// This file was modified by Oracle on 2015, 2016. // Modifications copyright (c) 2015, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library diff --git a/test/algorithms/envelope_expand/envelope_on_spheroid.cpp b/test/algorithms/envelope_expand/envelope_on_spheroid.cpp index f479e7b7f..a6336132a 100644 --- a/test/algorithms/envelope_expand/envelope_on_spheroid.cpp +++ b/test/algorithms/envelope_expand/envelope_on_spheroid.cpp @@ -3,15 +3,19 @@ // Copyright (c) 2015-2016, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // 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 +#include +#include +#include #ifndef BOOST_TEST_MODULE -#define BOOST_TEST_MODULE test_envelope_on_spheroid +#define BOOST_TEST_MODULE test_envelope_on_sphere_or_spheroid #endif #include @@ -46,8 +50,42 @@ #include "test_envelope_expand_on_spheroid.hpp" +template < + template class Inverse, + typename CS_Tag + > +struct test_envelope +{ + template + static inline void apply(Geometry& geometry, Box& detected) + { + bg::envelope(geometry, detected); + } +}; -template +template