diff --git a/doc/doxy/Doxyfile b/doc/doxy/Doxyfile index cbb016757..fd23c3815 100644 --- a/doc/doxy/Doxyfile +++ b/doc/doxy/Doxyfile @@ -177,10 +177,12 @@ WARN_LOGFILE = INPUT = . .. ../../../../boost/geometry/core \ ../../../../boost/geometry/algorithms \ ../../../../boost/geometry/algorithms/detail \ + ../../../../boost/geometry/algorithms/detail/buffer \ ../../../../boost/geometry/algorithms/detail/comparable_distance \ ../../../../boost/geometry/algorithms/detail/disjoint \ ../../../../boost/geometry/algorithms/detail/distance \ ../../../../boost/geometry/algorithms/detail/equals \ + ../../../../boost/geometry/algorithms/detail/intersection \ ../../../../boost/geometry/algorithms/detail/is_simple \ ../../../../boost/geometry/algorithms/detail/is_valid \ ../../../../boost/geometry/algorithms/detail/overlay \ diff --git a/doc/doxy/doxygen_input/groups/groups.hpp b/doc/doxy/doxygen_input/groups/groups.hpp index 01b5333b2..56d10bfd1 100644 --- a/doc/doxy/doxygen_input/groups/groups.hpp +++ b/doc/doxy/doxygen_input/groups/groups.hpp @@ -48,6 +48,7 @@ \defgroup num_geometries number of geometries: calculate the number of geometries in a multi-geometry \defgroup num_interior_rings number of interior rings: calculate the number of interior rings \defgroup num_points number of points: calculate number of points of a geometry +\defgroup num_segments number of segments: calculate number of segments of a geometry \defgroup overlaps overlaps: detect overlap between two geometries \defgroup perimeter perimeter: calculate perimeter of a geometry \defgroup projection projection: Projection struct's, classes diff --git a/doc/imports.qbk b/doc/imports.qbk index 7acbe5124..072e0bcd8 100644 --- a/doc/imports.qbk +++ b/doc/imports.qbk @@ -50,6 +50,7 @@ [import src/examples/algorithms/num_geometries.cpp] [import src/examples/algorithms/num_interior_rings.cpp] [import src/examples/algorithms/num_points.cpp] +[import src/examples/algorithms/num_segments.cpp] [import src/examples/algorithms/reverse.cpp] [import src/examples/algorithms/return_envelope.cpp] [import src/examples/algorithms/simplify.cpp] diff --git a/doc/make_qbk.py b/doc/make_qbk.py index 93e4d04ad..7031f0e5c 100755 --- a/doc/make_qbk.py +++ b/doc/make_qbk.py @@ -85,9 +85,9 @@ algorithms = ["append", "assign", "make", "clear" , "convex_hull", "crosses", "difference", "disjoint", "distance" , "envelope", "equals", "expand", "for_each", "is_simple", "is_valid" , "intersection", "intersects", "length", "num_geometries" - , "num_interior_rings", "num_points", "overlaps", "perimeter" - , "reverse", "simplify", "sym_difference", "touches", "transform" - , "union", "unique", "within"] + , "num_interior_rings", "num_points", "num_segments", "overlaps" + , "perimeter", "reverse", "simplify", "sym_difference", "touches" + , "transform", "union", "unique", "within"] access_functions = ["get", "set", "exterior_ring", "interior_rings" , "num_points", "num_interior_rings", "num_geometries"] diff --git a/doc/quickref.xml b/doc/quickref.xml index aed650baa..232451723 100644 --- a/doc/quickref.xml +++ b/doc/quickref.xml @@ -424,6 +424,7 @@ num_interior_rings num_geometries num_points + num_segments diff --git a/doc/reference.qbk b/doc/reference.qbk index 40c51b5db..bfc3711bd 100644 --- a/doc/reference.qbk +++ b/doc/reference.qbk @@ -136,6 +136,7 @@ [include generated/num_geometries.qbk] [include generated/num_interior_rings.qbk] [include generated/num_points.qbk] +[include generated/num_segments.qbk] [include generated/overlaps.qbk] diff --git a/doc/reference/algorithms/num_segments.qbk b/doc/reference/algorithms/num_segments.qbk new file mode 100644 index 000000000..9e9ea7cec --- /dev/null +++ b/doc/reference/algorithms/num_segments.qbk @@ -0,0 +1,35 @@ +[/============================================================================ + Boost.Geometry (aka GGL, Generic Geometry Library) + + Copyright (c) 2014, Oracle and/or its affiliates. + + Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + + Licensed under the Boost Software License version 1.0. + http://www.boost.org/users/license.html +=============================================================================/] + +[def __this_function__ num_segments] + +[heading_conformance_no_ogc __this_function__] + +[heading Behavior] +[table +[[Case] [Behavior] ] +[[__point__][[qbk_ret 0]]] +[[__segment__][[qbk_ret 1]]] +[[__box__][[qbk_ret 4]]] +[[__range__][[qbk_ret boost::size(geometry) - 1]]] +[[__other__][[qbk_ret the sum of the number of segments of its elements]]] +[[Open geometries][[qbk_ret the sum of the number of segments of its elements, it adds one for open (per ring) if specified]]] +[[Closed geometries][[qbk_ret the sum of the number of segments of its elements]]] +] + + +[heading Complexity] +Constant or Linear + +[heading Examples] +[num_segments] +[num_segments_output] + diff --git a/doc/release_notes.qbk b/doc/release_notes.qbk index 6ae4c9c53..bdee4d07e 100644 --- a/doc/release_notes.qbk +++ b/doc/release_notes.qbk @@ -39,14 +39,18 @@ [*Solved tickets] * [@https://svn.boost.org/trac/boost/ticket/8310 8310] Wrong results with overlapping polygons (fixed using point_on_surface for disjoint) +* [@https://svn.boost.org/trac/boost/ticket/8375 8375] sym_difference of non-closed polygons returns closed polygon +* [@https://svn.boost.org/trac/boost/ticket/8376 8376] difference of non-closed polygons returns closed polygon * [@https://svn.boost.org/trac/boost/ticket/9081 9081] Booleans create self-intersecting polygons from non-self-intersecting polygons * [@https://svn.boost.org/trac/boost/ticket/9245 9245] Check for process errors in make_qbk.py * [@https://svn.boost.org/trac/boost/ticket/9563 9563] (Sym)difference not successful, fixed by rescaling to robust type * [@https://svn.boost.org/trac/boost/ticket/9628 9628] Wrong result of within() due to the winding strategy not working correctly for nearly-horizontal segments +* [@https://svn.boost.org/trac/boost/ticket/9828 9828] boost::geometry::union_(...) creates redundant closing point * [@https://svn.boost.org/trac/boost/ticket/9871 9871] Remove spike in polygon with only a spike * [@https://svn.boost.org/trac/boost/ticket/9947 9947] Missing info about WKT in documentation * [@https://svn.boost.org/trac/boost/ticket/10019 10019] Difference of Linestring and Box returns their intersection * [@https://svn.boost.org/trac/boost/ticket/10077 10077] Wrong types in concept checks in boost/geometry/arithmetic/arithmetic.hpp +* [@https://svn.boost.org/trac/boost/ticket/10234 10234] Wrong results of covered_by() for nearly-horizontal segments [*Bugfixes] diff --git a/doc/src/docutils/tools/support_status/support_status.cpp b/doc/src/docutils/tools/support_status/support_status.cpp index 4cf636d74..9372a1967 100644 --- a/doc/src/docutils/tools/support_status/support_status.cpp +++ b/doc/src/docutils/tools/support_status/support_status.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -129,6 +130,7 @@ DECLARE_UNARY_ALGORITHM(length) DECLARE_UNARY_ALGORITHM(num_geometries) DECLARE_UNARY_ALGORITHM(num_interior_rings) DECLARE_UNARY_ALGORITHM(num_points) +DECLARE_UNARY_ALGORITHM(num_segments) DECLARE_BINARY_ALGORITHM(overlaps) DECLARE_UNARY_ALGORITHM(perimeter) DECLARE_UNARY_ALGORITHM(reverse) diff --git a/doc/src/examples/algorithms/Jamfile.v2 b/doc/src/examples/algorithms/Jamfile.v2 index d8e25d9fb..946e66f39 100644 --- a/doc/src/examples/algorithms/Jamfile.v2 +++ b/doc/src/examples/algorithms/Jamfile.v2 @@ -66,6 +66,7 @@ exe make_inverse : make_inverse.cpp ; exe num_geometries : num_geometries.cpp ; exe num_interior_rings : num_interior_rings.cpp ; exe num_points : num_points.cpp ; +exe num_segments : num_segments.cpp ; exe return_envelope : return_envelope.cpp ; diff --git a/doc/src/examples/algorithms/num_segments.cpp b/doc/src/examples/algorithms/num_segments.cpp new file mode 100644 index 000000000..40a244cfe --- /dev/null +++ b/doc/src/examples/algorithms/num_segments.cpp @@ -0,0 +1,46 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// QuickBook Example + +// Copyright (c) 2014, Oracle and/or its affiliates + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +//[num_segments +//` Get the number of segments in a geometry + +#include + +#include +#include + + +int main() +{ + boost::geometry::model::multi_polygon + < + boost::geometry::model::polygon + < + boost::geometry::model::d2::point_xy, true, false // cw, open polygon + > + > mp; + boost::geometry::read_wkt("MULTIPOLYGON(((0 0,0 10,10 0),(1 1,8 1,1 8)),((10 10,10 20,20 10)))", mp); + std::cout << "Number of segments: " << boost::geometry::num_segments(mp) << std::endl; + std::cout << "Number of segments (add_to_open <- true): " << boost::geometry::num_segments(mp, true) << std::endl; + return 0; +} + +//] + + +//[num_segments_output +/*` +Output: +[pre + Number of segments: 6 +Number of segments (add_to_open <- true): 9 +] +*/ +//] diff --git a/include/boost/geometry/algorithms/append.hpp b/include/boost/geometry/algorithms/append.hpp index 1dafac04b..1a8828ba4 100644 --- a/include/boost/geometry/algorithms/append.hpp +++ b/include/boost/geometry/algorithms/append.hpp @@ -8,6 +8,7 @@ // Modifications copyright (c) 2014, 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. @@ -20,6 +21,10 @@ #define BOOST_GEOMETRY_ALGORITHMS_APPEND_HPP +#include +#include +#include + #include #include #include @@ -28,9 +33,7 @@ #include #include #include -#include -#include -#include +#include namespace boost { namespace geometry @@ -98,7 +101,7 @@ struct point_to_polygon else if (ring_index < int(num_interior_rings(polygon))) { append_point::apply( - interior_rings(polygon)[ring_index], point); + range::at(interior_rings(polygon), ring_index), point); } } }; @@ -120,7 +123,7 @@ struct range_to_polygon else if (ring_index < int(num_interior_rings(polygon))) { append_range::apply( - interior_rings(polygon)[ring_index], range); + range::at(interior_rings(polygon), ring_index), range); } } }; @@ -202,6 +205,71 @@ struct append } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace append +{ + +template +struct append_to_multigeometry +{ + static inline void apply(MultiGeometry& multigeometry, + RangeOrPoint const& range_or_point, + int ring_index, int multi_index) + { + + dispatch::append + < + typename boost::range_value::type, + RangeOrPoint + >::apply(range::at(multigeometry, multi_index), range_or_point, ring_index); + } +}; + +}} // namespace detail::append +#endif // DOXYGEN_NO_DETAIL + +#ifndef DOXYGEN_NO_DISPATCH +namespace dispatch +{ + +namespace splitted_dispatch +{ + +template +struct append_point + : detail::append::append_point +{}; + +template +struct append_range + : detail::append::append_range +{}; + +template +struct append_point + : detail::append::append_to_multigeometry +{}; + +template +struct append_range + : detail::append::append_to_multigeometry +{}; + +template +struct append_point + : detail::append::append_to_multigeometry +{}; + +template +struct append_range + : detail::append::append_to_multigeometry +{}; + +} // namespace splitted_dispatch + +} // namespace dispatch +#endif // DOXYGEN_NO_DISPATCH + namespace resolve_variant { diff --git a/include/boost/geometry/algorithms/convert.hpp b/include/boost/geometry/algorithms/convert.hpp index f8685af2d..914ef8f42 100644 --- a/include/boost/geometry/algorithms/convert.hpp +++ b/include/boost/geometry/algorithms/convert.hpp @@ -41,6 +41,8 @@ #include #include +#include + #include #include #include @@ -111,7 +113,7 @@ struct box_to_range assign_box_corners_oriented(box, range); if (Close) { - range[4] = range[0]; + range::at(range, 4) = range::at(range, 0); } } }; @@ -160,13 +162,17 @@ struct range_to_range // point for open output. view_type view(rview); - int n = boost::size(view); + typedef typename boost::range_size::type size_type; + size_type n = boost::size(view); if (geometry::closure::value == geometry::open) { n--; } - int i = 0; + // If size == 0 && geometry::open <=> n = numeric_limits::max() + // but ok, sice below it == end() + + size_type i = 0; for (typename boost::range_iterator::type it = boost::begin(view); it != boost::end(view) && i < n; diff --git a/include/boost/geometry/algorithms/detail/assign_box_corners.hpp b/include/boost/geometry/algorithms/detail/assign_box_corners.hpp index f1bc59613..669d6d365 100644 --- a/include/boost/geometry/algorithms/detail/assign_box_corners.hpp +++ b/include/boost/geometry/algorithms/detail/assign_box_corners.hpp @@ -19,7 +19,7 @@ #include #include - +#include namespace boost { namespace geometry @@ -80,12 +80,16 @@ inline void assign_box_corners_oriented(Box const& box, Range& corners) if (Reverse) { // make counterclockwise ll,lr,ur,ul - assign_box_corners(box, corners[0], corners[1], corners[3], corners[2]); + assign_box_corners(box, + range::at(corners, 0), range::at(corners, 1), + range::at(corners, 3), range::at(corners, 2)); } else { // make clockwise ll,ul,ur,lr - assign_box_corners(box, corners[0], corners[3], corners[1], corners[2]); + assign_box_corners(box, + range::at(corners, 0), range::at(corners, 3), + range::at(corners, 1), range::at(corners, 2)); } } #if defined(_MSC_VER) diff --git a/include/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp b/include/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp index 0ace72f63..182f5af6a 100644 --- a/include/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include @@ -42,7 +42,11 @@ struct turn_ovelaps_box template static inline bool apply(Box const& box, Turn const& turn) { - return ! geometry::disjoint(box, turn.robust_point); + return ! dispatch::disjoint + < + typename Turn::robust_point_type, + Box + >::apply(turn.robust_point, box); } }; diff --git a/include/boost/geometry/algorithms/detail/distance/segment_to_box.hpp b/include/boost/geometry/algorithms/detail/distance/segment_to_box.hpp index 695f3a2be..b085da513 100644 --- a/include/boost/geometry/algorithms/detail/distance/segment_to_box.hpp +++ b/include/boost/geometry/algorithms/detail/distance/segment_to_box.hpp @@ -14,9 +14,10 @@ #include #include +#include +#include #include #include -#include #include #include @@ -103,7 +104,7 @@ public: < Strategy >::apply(strategy); - boost::ignore_unused_variable_warning(cstrategy); + boost::ignore_unused(cstrategy); // get segment points segment_point p[2]; @@ -181,7 +182,7 @@ public: < Strategy >::apply(strategy); - boost::ignore_unused_variable_warning(cstrategy); + boost::ignore_unused(cstrategy); // get segment points segment_point p[2]; @@ -199,7 +200,7 @@ public: } point_box_comparable_strategy pb_cstrategy; - boost::ignore_unused_variable_warning(pb_cstrategy); + boost::ignore_unused(pb_cstrategy); cd[4] = pb_cstrategy.apply(p[0], box); cd[5] = pb_cstrategy.apply(p[1], box); @@ -281,6 +282,8 @@ private: PPStrategy const& pp_strategy, PSStrategy const& ps_strategy) { + boost::ignore_unused(pp_strategy, ps_strategy); + // the implementation below is written for non-negative slope // segments // @@ -325,6 +328,8 @@ private: BoxPoint const& top_left, PSStrategy const& ps_strategy) { + boost::ignore_unused(ps_strategy); + // the segment lies above the box typedef cast_to_result cast; diff --git a/include/boost/geometry/algorithms/detail/extreme_points.hpp b/include/boost/geometry/algorithms/detail/extreme_points.hpp index c6a47bb8f..055bc1acb 100644 --- a/include/boost/geometry/algorithms/detail/extreme_points.hpp +++ b/include/boost/geometry/algorithms/detail/extreme_points.hpp @@ -280,7 +280,8 @@ struct extreme_points_on_ring template static inline bool right_turn(Ring const& ring, Iterator it) { - int const index = std::distance(boost::begin(ring), it); + typename std::iterator_traits::difference_type const index + = std::distance(boost::begin(ring), it); geometry::ever_circling_range_iterator left(ring); geometry::ever_circling_range_iterator right(ring); left += index; @@ -328,7 +329,8 @@ struct extreme_points_on_ring return false; } - int const index = std::distance(boost::begin(ring), max_it); + typename std::iterator_traits::difference_type const + index = std::distance(boost::begin(ring), max_it); //std::cout << "Extreme point lies at " << index << " having " << geometry::wkt(*max_it) << std::endl; geometry::ever_circling_range_iterator left(ring); diff --git a/include/boost/geometry/algorithms/detail/intersection/box_box.hpp b/include/boost/geometry/algorithms/detail/intersection/box_box.hpp new file mode 100644 index 000000000..30c31ff1e --- /dev/null +++ b/include/boost/geometry/algorithms/detail/intersection/box_box.hpp @@ -0,0 +1,54 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// 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. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_BOX_BOX_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_BOX_BOX_HPP + + +#include +#include + + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_DISPATCH +namespace dispatch +{ + + +template +< + typename Box1, typename Box2, bool Reverse +> +struct intersection + < + Box1, Box2, + box_tag, box_tag, + Reverse + > : public detail::intersection::intersection_box_box + < + 0, geometry::dimension::value + > +{}; + + +} // namespace dispatch +#endif // DOXYGEN_NO_DISPATCH + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_BOX_BOX_HPP diff --git a/include/boost/geometry/algorithms/detail/intersection/implementation.hpp b/include/boost/geometry/algorithms/detail/intersection/implementation.hpp new file mode 100644 index 000000000..d8fb2ec38 --- /dev/null +++ b/include/boost/geometry/algorithms/detail/intersection/implementation.hpp @@ -0,0 +1,22 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// 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. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_IMPLEMENTATION_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_IMPLEMENTATION_HPP + + +#include +#include + + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_IMPLEMENTATION_HPP diff --git a/include/boost/geometry/algorithms/detail/intersection/interface.hpp b/include/boost/geometry/algorithms/detail/intersection/interface.hpp new file mode 100644 index 000000000..323ab7c85 --- /dev/null +++ b/include/boost/geometry/algorithms/detail/intersection/interface.hpp @@ -0,0 +1,309 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// 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. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_INTERFACE_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_INTERFACE_HPP + + +// TODO: those headers probably may be removed +#include +#include + +#include +#include + + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_DISPATCH +namespace dispatch +{ + +// By default, all is forwarded to the intersection_insert-dispatcher +template +< + typename Geometry1, typename Geometry2, + typename Tag1 = typename geometry::tag::type, + typename Tag2 = typename geometry::tag::type, + bool Reverse = reverse_dispatch::type::value +> +struct intersection +{ + template + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + RobustPolicy const& robust_policy, + GeometryOut& geometry_out, + Strategy const& strategy) + { + typedef typename boost::range_value::type OneOut; + + intersection_insert + < + Geometry1, Geometry2, OneOut, + overlay_intersection + >::apply(geometry1, geometry2, robust_policy, std::back_inserter(geometry_out), strategy); + + return true; + } + +}; + + +// If reversal is needed, perform it +template +< + typename Geometry1, typename Geometry2, + typename Tag1, typename Tag2 +> +struct intersection +< + Geometry1, Geometry2, + Tag1, Tag2, + true +> + : intersection +{ + template + static inline bool apply( + Geometry1 const& g1, + Geometry2 const& g2, + RobustPolicy const& robust_policy, + GeometryOut& out, + Strategy const& strategy) + { + return intersection< + Geometry2, Geometry1, + Tag2, Tag1, + false + >::apply(g2, g1, robust_policy, out, strategy); + } +}; + + +} // namespace dispatch +#endif // DOXYGEN_NO_DISPATCH + + +namespace resolve_variant +{ + +template +struct intersection +{ + template + static inline bool + apply( + const Geometry1& geometry1, + const Geometry2& geometry2, + GeometryOut& geometry_out) + { + concept::check(); + concept::check(); + + typedef typename geometry::rescale_overlay_policy_type + < + Geometry1, + Geometry2 + >::type rescale_policy_type; + + rescale_policy_type robust_policy + = geometry::get_rescale_policy(geometry1, geometry2); + + typedef strategy_intersection + < + typename cs_tag::type, + Geometry1, + Geometry2, + typename geometry::point_type::type, + rescale_policy_type + > strategy; + + return dispatch::intersection + < + Geometry1, + Geometry2 + >::apply(geometry1, geometry2, robust_policy, geometry_out, strategy()); + } +}; + + +template +struct intersection, Geometry2> +{ + template + struct visitor: static_visitor + { + Geometry2 const& m_geometry2; + GeometryOut& m_geometry_out; + + visitor(Geometry2 const& geometry2, + GeometryOut& geometry_out) + : m_geometry2(geometry2), + m_geometry_out(geometry_out) + {} + + template + result_type operator()(Geometry1 const& geometry1) const + { + return intersection + < + Geometry1, + Geometry2 + >::template apply + < + GeometryOut + > + (geometry1, m_geometry2, m_geometry_out); + } + }; + + template + static inline bool + apply(variant const& geometry1, + Geometry2 const& geometry2, + GeometryOut& geometry_out) + { + return apply_visitor(visitor(geometry2, geometry_out), geometry1); + } +}; + + +template +struct intersection > +{ + template + struct visitor: static_visitor + { + Geometry1 const& m_geometry1; + GeometryOut& m_geometry_out; + + visitor(Geometry1 const& geometry1, + GeometryOut& geometry_out) + : m_geometry1(geometry1), + m_geometry_out(geometry_out) + {} + + template + result_type operator()(Geometry2 const& geometry2) const + { + return intersection + < + Geometry1, + Geometry2 + >::template apply + < + GeometryOut + > + (m_geometry1, geometry2, m_geometry_out); + } + }; + + template + static inline bool + apply( + Geometry1 const& geometry1, + const variant& geometry2, + GeometryOut& geometry_out) + { + return apply_visitor(visitor(geometry1, geometry_out), geometry2); + } +}; + + +template +struct intersection, variant > +{ + template + struct visitor: static_visitor + { + GeometryOut& m_geometry_out; + + visitor(GeometryOut& geometry_out) + : m_geometry_out(geometry_out) + {} + + template + result_type operator()( + Geometry1 const& geometry1, + Geometry2 const& geometry2) const + { + return intersection + < + Geometry1, + Geometry2 + >::template apply + < + GeometryOut + > + (geometry1, geometry2, m_geometry_out); + } + }; + + template + static inline bool + apply( + const variant& geometry1, + const variant& geometry2, + GeometryOut& geometry_out) + { + return apply_visitor(visitor(geometry_out), geometry1, geometry2); + } +}; + +} // namespace resolve_variant + + +/*! +\brief \brief_calc2{intersection} +\ingroup intersection +\details \details_calc2{intersection, spatial set theoretic intersection}. +\tparam Geometry1 \tparam_geometry +\tparam Geometry2 \tparam_geometry +\tparam GeometryOut Collection of geometries (e.g. std::vector, std::deque, boost::geometry::multi*) of which + the value_type fulfills a \p_l_or_c concept, or it is the output geometry (e.g. for a box) +\param geometry1 \param_geometry +\param geometry2 \param_geometry +\param geometry_out The output geometry, either a multi_point, multi_polygon, + multi_linestring, or a box (for intersection of two boxes) + +\qbk{[include reference/algorithms/intersection.qbk]} +*/ +template +< + typename Geometry1, + typename Geometry2, + typename GeometryOut +> +inline bool intersection(Geometry1 const& geometry1, + Geometry2 const& geometry2, + GeometryOut& geometry_out) +{ + return resolve_variant::intersection + < + Geometry1, + Geometry2 + >::template apply + < + GeometryOut + > + (geometry1, geometry2, geometry_out); +} + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_INTERFACE_HPP diff --git a/include/boost/geometry/algorithms/detail/intersection/multi.hpp b/include/boost/geometry/algorithms/detail/intersection/multi.hpp new file mode 100644 index 000000000..b1f13862f --- /dev/null +++ b/include/boost/geometry/algorithms/detail/intersection/multi.hpp @@ -0,0 +1,423 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// 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. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_MULTI_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_MULTI_HPP + +#include +#include +#include +#include +#include +#include + +// TODO: those headers probably may be removed +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +// TODO: remove this after moving num_point from multi directory +#include + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace intersection +{ + + +template +struct intersection_multi_linestring_multi_linestring_point +{ + template + < + typename MultiLinestring1, typename MultiLinestring2, + typename RobustPolicy, + typename OutputIterator, typename Strategy + > + static inline OutputIterator apply(MultiLinestring1 const& ml1, + MultiLinestring2 const& ml2, + RobustPolicy const& robust_policy, + OutputIterator out, + Strategy const& strategy) + { + // Note, this loop is quadratic w.r.t. number of linestrings per input. + // Future Enhancement: first do the sections of each, then intersect. + for (typename boost::range_iterator + < + MultiLinestring1 const + >::type it1 = boost::begin(ml1); + it1 != boost::end(ml1); + ++it1) + { + for (typename boost::range_iterator + < + MultiLinestring2 const + >::type it2 = boost::begin(ml2); + it2 != boost::end(ml2); + ++it2) + { + out = intersection_linestring_linestring_point + ::apply(*it1, *it2, robust_policy, out, strategy); + } + } + + return out; + } +}; + + +template +struct intersection_linestring_multi_linestring_point +{ + template + < + typename Linestring, typename MultiLinestring, + typename RobustPolicy, + typename OutputIterator, typename Strategy + > + static inline OutputIterator apply(Linestring const& linestring, + MultiLinestring const& ml, + RobustPolicy const& robust_policy, + OutputIterator out, + Strategy const& strategy) + { + for (typename boost::range_iterator + < + MultiLinestring const + >::type it = boost::begin(ml); + it != boost::end(ml); + ++it) + { + out = intersection_linestring_linestring_point + ::apply(linestring, *it, robust_policy, out, strategy); + } + + return out; + } +}; + + +// This loop is quite similar to the loop above, but beacuse the iterator +// is second (above) or first (below) argument, it is not trivial to merge them. +template +< + bool ReverseAreal, + typename LineStringOut, + overlay_type OverlayType +> +struct intersection_of_multi_linestring_with_areal +{ + template + < + typename MultiLinestring, typename Areal, + typename RobustPolicy, + typename OutputIterator, typename Strategy + > + static inline OutputIterator apply(MultiLinestring const& ml, Areal const& areal, + RobustPolicy const& robust_policy, + OutputIterator out, + Strategy const& strategy) + { + for (typename boost::range_iterator + < + MultiLinestring const + >::type it = boost::begin(ml); + it != boost::end(ml); + ++it) + { + out = intersection_of_linestring_with_areal + < + ReverseAreal, LineStringOut, OverlayType + >::apply(*it, areal, robust_policy, out, strategy); + } + + return out; + + } +}; + +// This one calls the one above with reversed arguments +template +< + bool ReverseAreal, + typename LineStringOut, + overlay_type OverlayType +> +struct intersection_of_areal_with_multi_linestring +{ + template + < + typename Areal, typename MultiLinestring, + typename RobustPolicy, + typename OutputIterator, typename Strategy + > + static inline OutputIterator apply(Areal const& areal, MultiLinestring const& ml, + RobustPolicy const& robust_policy, + OutputIterator out, + Strategy const& strategy) + { + return intersection_of_multi_linestring_with_areal + < + ReverseAreal, LineStringOut, OverlayType + >::apply(ml, areal, robust_policy, out, strategy); + } +}; + + + +template +struct clip_multi_linestring +{ + template + < + typename MultiLinestring, typename Box, + typename RobustPolicy, + typename OutputIterator, typename Strategy + > + static inline OutputIterator apply(MultiLinestring const& multi_linestring, + Box const& box, + RobustPolicy const& robust_policy, + OutputIterator out, Strategy const& ) + { + typedef typename point_type::type point_type; + strategy::intersection::liang_barsky lb_strategy; + for (typename boost::range_iterator::type it + = boost::begin(multi_linestring); + it != boost::end(multi_linestring); ++it) + { + out = detail::intersection::clip_range_with_box + (box, *it, robust_policy, out, lb_strategy); + } + return out; + } +}; + + +}} // namespace detail::intersection +#endif // DOXYGEN_NO_DETAIL + + +#ifndef DOXYGEN_NO_DISPATCH +namespace dispatch +{ + + +// Linear +template +< + typename MultiLinestring1, typename MultiLinestring2, + typename GeometryOut, + overlay_type OverlayType, + bool Reverse1, bool Reverse2, bool ReverseOut +> +struct intersection_insert + < + MultiLinestring1, MultiLinestring2, + GeometryOut, + OverlayType, + Reverse1, Reverse2, ReverseOut, + multi_linestring_tag, multi_linestring_tag, point_tag, + false, false, false + > : detail::intersection::intersection_multi_linestring_multi_linestring_point + < + GeometryOut + > +{}; + + +template +< + typename Linestring, typename MultiLinestring, + typename GeometryOut, + overlay_type OverlayType, + bool Reverse1, bool Reverse2, bool ReverseOut +> +struct intersection_insert + < + Linestring, MultiLinestring, + GeometryOut, + OverlayType, + Reverse1, Reverse2, ReverseOut, + linestring_tag, multi_linestring_tag, point_tag, + false, false, false + > : detail::intersection::intersection_linestring_multi_linestring_point + < + GeometryOut + > +{}; + + +template +< + typename MultiLinestring, typename Box, + typename GeometryOut, + overlay_type OverlayType, + bool Reverse1, bool Reverse2, bool ReverseOut +> +struct intersection_insert + < + MultiLinestring, Box, + GeometryOut, + OverlayType, + Reverse1, Reverse2, ReverseOut, + multi_linestring_tag, box_tag, linestring_tag, + false, true, false + > : detail::intersection::clip_multi_linestring + < + GeometryOut + > +{}; + + +template +< + typename Linestring, typename MultiPolygon, + typename GeometryOut, + overlay_type OverlayType, + bool ReverseLinestring, bool ReverseMultiPolygon, bool ReverseOut +> +struct intersection_insert + < + Linestring, MultiPolygon, + GeometryOut, + OverlayType, + ReverseLinestring, ReverseMultiPolygon, ReverseOut, + linestring_tag, multi_polygon_tag, linestring_tag, + false, true, false + > : detail::intersection::intersection_of_linestring_with_areal + < + ReverseMultiPolygon, + GeometryOut, + OverlayType + > +{}; + + +// Derives from areal/mls because runtime arguments are in that order. +// areal/mls reverses it itself to mls/areal +template +< + typename Polygon, typename MultiLinestring, + typename GeometryOut, + overlay_type OverlayType, + bool ReversePolygon, bool ReverseMultiLinestring, bool ReverseOut +> +struct intersection_insert + < + Polygon, MultiLinestring, + GeometryOut, + OverlayType, + ReversePolygon, ReverseMultiLinestring, ReverseOut, + polygon_tag, multi_linestring_tag, linestring_tag, + true, false, false + > : detail::intersection::intersection_of_areal_with_multi_linestring + < + ReversePolygon, + GeometryOut, + OverlayType + > +{}; + + +template +< + typename MultiLinestring, typename Ring, + typename GeometryOut, + overlay_type OverlayType, + bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut +> +struct intersection_insert + < + MultiLinestring, Ring, + GeometryOut, + OverlayType, + ReverseMultiLinestring, ReverseRing, ReverseOut, + multi_linestring_tag, ring_tag, linestring_tag, + false, true, false + > : detail::intersection::intersection_of_multi_linestring_with_areal + < + ReverseRing, + GeometryOut, + OverlayType + > +{}; + +template +< + typename MultiLinestring, typename Polygon, + typename GeometryOut, + overlay_type OverlayType, + bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut +> +struct intersection_insert + < + MultiLinestring, Polygon, + GeometryOut, + OverlayType, + ReverseMultiLinestring, ReverseRing, ReverseOut, + multi_linestring_tag, polygon_tag, linestring_tag, + false, true, false + > : detail::intersection::intersection_of_multi_linestring_with_areal + < + ReverseRing, + GeometryOut, + OverlayType + > +{}; + + + +template +< + typename MultiLinestring, typename MultiPolygon, + typename GeometryOut, + overlay_type OverlayType, + bool ReverseMultiLinestring, bool ReverseMultiPolygon, bool ReverseOut +> +struct intersection_insert + < + MultiLinestring, MultiPolygon, + GeometryOut, + OverlayType, + ReverseMultiLinestring, ReverseMultiPolygon, ReverseOut, + multi_linestring_tag, multi_polygon_tag, linestring_tag, + false, true, false + > : detail::intersection::intersection_of_multi_linestring_with_areal + < + ReverseMultiPolygon, + GeometryOut, + OverlayType + > +{}; + + +} // namespace dispatch +#endif + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_MULTI_HPP + diff --git a/include/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp b/include/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp index 4040fbe6b..5ee9b031e 100644 --- a/include/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -95,8 +96,8 @@ struct copy_segment_point_polygon >::apply ( seg_id.ring_index < 0 - ? geometry::exterior_ring(polygon) - : geometry::interior_rings(polygon)[seg_id.ring_index], + ? geometry::exterior_ring(polygon) + : range::at(geometry::interior_rings(polygon), seg_id.ring_index), seg_id, second, point ); @@ -146,7 +147,7 @@ struct copy_segment_point_multi ); // Call the single-version - return Policy::apply(multi[seg_id.multi_index], seg_id, second, point); + return Policy::apply(range::at(multi, seg_id.multi_index), seg_id, second, point); } }; diff --git a/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp b/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp index d4bf0a90f..5aae862ce 100644 --- a/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp @@ -6,6 +6,7 @@ // Modifications copyright (c) 2014 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 @@ -39,6 +40,8 @@ #include #include +#include + namespace boost { namespace geometry { @@ -155,18 +158,18 @@ public: // Sanity check if ( from_index > to_index || from_index < 0 - || to_index >= int(boost::size(ls)) ) + || to_index >= static_cast(boost::size(ls)) ) { return; } - typedef typename boost::range_difference::type size_type; - size_type const count = to_index - from_index + 1; + typedef typename boost::range_difference::type diff_t; + diff_t const count = to_index - from_index + 1; typename boost::range_iterator::type it = boost::begin(ls) + from_index; - for (size_type i = 0; i < count; ++i, ++it) + for (diff_t i = 0; i < count; ++i, ++it) { append_to_output(current_output, *it, robust_policy, boost::integral_constant()); @@ -193,8 +196,8 @@ struct copy_segments_polygon copy_segments_ring::apply ( seg_id.ring_index < 0 - ? geometry::exterior_ring(polygon) - : geometry::interior_rings(polygon)[seg_id.ring_index], + ? geometry::exterior_ring(polygon) + : range::at(geometry::interior_rings(polygon), seg_id.ring_index), seg_id, to_index, robust_policy, current_output @@ -265,10 +268,10 @@ struct copy_segments_multi ); // Call the single-version - Policy::apply(multi_geometry[seg_id.multi_index], - seg_id, to_index, - robust_policy, - current_output); + Policy::apply(range::at(multi_geometry, seg_id.multi_index), + seg_id, to_index, + robust_policy, + current_output); } }; diff --git a/include/boost/geometry/algorithms/detail/overlay/follow.hpp b/include/boost/geometry/algorithms/detail/overlay/follow.hpp index 632f79f40..83aa4ce6e 100644 --- a/include/boost/geometry/algorithms/detail/overlay/follow.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/follow.hpp @@ -494,8 +494,10 @@ public : detail::copy_segments::copy_segments_linestring < false, RemoveSpikes - >::apply(linestring, current_segment_id, - boost::size(linestring) - 1, robust_policy, + >::apply(linestring, + current_segment_id, + static_cast(boost::size(linestring) - 1), + robust_policy, current_piece); } diff --git a/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp b/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp index 851162bda..2954921a0 100644 --- a/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp @@ -263,8 +263,10 @@ protected: detail::copy_segments::copy_segments_linestring < false, false // do not reverse; do not remove spikes - >::apply(linestring, current_segment_id, - boost::size(linestring) - 1, robust_policy, + >::apply(linestring, + current_segment_id, + static_cast(boost::size(linestring) - 1), + robust_policy, current_piece); } diff --git a/include/boost/geometry/algorithms/detail/overlay/get_ring.hpp b/include/boost/geometry/algorithms/detail/overlay/get_ring.hpp index ab9219a3d..131d58d58 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_ring.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_ring.hpp @@ -19,6 +19,7 @@ #include #include #include +#include namespace boost { namespace geometry @@ -34,16 +35,16 @@ template struct get_ring {}; -// A container of rings (multi-ring but that does not exist) +// A range of rings (multi-ring but that does not exist) // gets the "void" tag and is dispatched here. template<> struct get_ring { - template - static inline typename boost::range_value::type const& - apply(ring_identifier const& id, Container const& container) + template + static inline typename boost::range_value::type const& + apply(ring_identifier const& id, Range const& container) { - return container[id.multi_index]; + return range::at(container, id.multi_index); } }; @@ -88,7 +89,7 @@ struct get_ring ); return id.ring_index < 0 ? exterior_ring(polygon) - : interior_rings(polygon)[id.ring_index]; + : range::at(interior_rings(polygon), id.ring_index); } }; @@ -107,7 +108,7 @@ struct get_ring && id.multi_index < int(boost::size(multi_polygon)) ); return get_ring::apply(id, - multi_polygon[id.multi_index]); + range::at(multi_polygon, id.multi_index)); } }; diff --git a/include/boost/geometry/algorithms/detail/sections/range_by_section.hpp b/include/boost/geometry/algorithms/detail/sections/range_by_section.hpp index 4ef11175f..63feb12a7 100644 --- a/include/boost/geometry/algorithms/detail/sections/range_by_section.hpp +++ b/include/boost/geometry/algorithms/detail/sections/range_by_section.hpp @@ -7,8 +7,8 @@ // 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 2013. -// Modifications copyright (c) 2013, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014. +// Modifications copyright (c) 2013, 2014, Oracle and/or its affiliates. // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -30,6 +30,7 @@ #include #include #include +#include namespace boost { namespace geometry @@ -57,7 +58,7 @@ struct full_section_polygon { return section.ring_id.ring_index < 0 ? geometry::exterior_ring(polygon) - : geometry::interior_rings(polygon)[section.ring_id.ring_index]; + : range::at(geometry::interior_rings(polygon), section.ring_id.ring_index); } }; @@ -79,7 +80,7 @@ struct full_section_multi && section.ring_id.multi_index < int(boost::size(multi)) ); - return Policy::apply(multi[section.ring_id.multi_index], section); + return Policy::apply(range::at(multi, section.ring_id.multi_index), section); } }; diff --git a/include/boost/geometry/algorithms/intersection.hpp b/include/boost/geometry/algorithms/intersection.hpp index b066e8150..0169f12db 100644 --- a/include/boost/geometry/algorithms/intersection.hpp +++ b/include/boost/geometry/algorithms/intersection.hpp @@ -2,6 +2,11 @@ // 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. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -10,310 +15,8 @@ #define BOOST_GEOMETRY_ALGORITHMS_INTERSECTION_HPP -#include -#include -#include -#include -#include - - -namespace boost { namespace geometry -{ - - -#ifndef DOXYGEN_NO_DISPATCH -namespace dispatch -{ - -// By default, all is forwarded to the intersection_insert-dispatcher -template -< - typename Geometry1, typename Geometry2, - typename Tag1 = typename geometry::tag::type, - typename Tag2 = typename geometry::tag::type, - bool Reverse = reverse_dispatch::type::value -> -struct intersection -{ - template - static inline bool apply(Geometry1 const& geometry1, - Geometry2 const& geometry2, - RobustPolicy const& robust_policy, - GeometryOut& geometry_out, - Strategy const& strategy) - { - typedef typename boost::range_value::type OneOut; - - intersection_insert - < - Geometry1, Geometry2, OneOut, - overlay_intersection - >::apply(geometry1, geometry2, robust_policy, std::back_inserter(geometry_out), strategy); - - return true; - } - -}; - - -// If reversal is needed, perform it -template -< - typename Geometry1, typename Geometry2, - typename Tag1, typename Tag2 -> -struct intersection -< - Geometry1, Geometry2, - Tag1, Tag2, - true -> - : intersection -{ - template - static inline bool apply( - Geometry1 const& g1, - Geometry2 const& g2, - RobustPolicy const& robust_policy, - GeometryOut& out, - Strategy const& strategy) - { - return intersection< - Geometry2, Geometry1, - Tag2, Tag1, - false - >::apply(g2, g1, robust_policy, out, strategy); - } -}; - - -template -< - typename Box1, typename Box2, bool Reverse -> -struct intersection - < - Box1, Box2, - box_tag, box_tag, - Reverse - > : public detail::intersection::intersection_box_box - < - 0, geometry::dimension::value - > -{}; - - -} // namespace dispatch -#endif // DOXYGEN_NO_DISPATCH - - -namespace resolve_variant -{ - -template -struct intersection -{ - template - static inline bool - apply( - const Geometry1& geometry1, - const Geometry2& geometry2, - GeometryOut& geometry_out) - { - concept::check(); - concept::check(); - - typedef typename geometry::rescale_overlay_policy_type - < - Geometry1, - Geometry2 - >::type rescale_policy_type; - - rescale_policy_type robust_policy - = geometry::get_rescale_policy(geometry1, geometry2); - - typedef strategy_intersection - < - typename cs_tag::type, - Geometry1, - Geometry2, - typename geometry::point_type::type, - rescale_policy_type - > strategy; - - return dispatch::intersection - < - Geometry1, - Geometry2 - >::apply(geometry1, geometry2, robust_policy, geometry_out, strategy()); - } -}; - - -template -struct intersection, Geometry2> -{ - template - struct visitor: static_visitor - { - Geometry2 const& m_geometry2; - GeometryOut& m_geometry_out; - - visitor(Geometry2 const& geometry2, - GeometryOut& geometry_out) - : m_geometry2(geometry2), - m_geometry_out(geometry_out) - {} - - template - result_type operator()(Geometry1 const& geometry1) const - { - return intersection - < - Geometry1, - Geometry2 - >::template apply - < - GeometryOut - > - (geometry1, m_geometry2, m_geometry_out); - } - }; - - template - static inline bool - apply(variant const& geometry1, - Geometry2 const& geometry2, - GeometryOut& geometry_out) - { - return apply_visitor(visitor(geometry2, geometry_out), geometry1); - } -}; - - -template -struct intersection > -{ - template - struct visitor: static_visitor - { - Geometry1 const& m_geometry1; - GeometryOut& m_geometry_out; - - visitor(Geometry1 const& geometry1, - GeometryOut& geometry_out) - : m_geometry1(geometry1), - m_geometry_out(geometry_out) - {} - - template - result_type operator()(Geometry2 const& geometry2) const - { - return intersection - < - Geometry1, - Geometry2 - >::template apply - < - GeometryOut - > - (m_geometry1, geometry2, m_geometry_out); - } - }; - - template - static inline bool - apply( - Geometry1 const& geometry1, - const variant& geometry2, - GeometryOut& geometry_out) - { - return apply_visitor(visitor(geometry1, geometry_out), geometry2); - } -}; - - -template -struct intersection, variant > -{ - template - struct visitor: static_visitor - { - GeometryOut& m_geometry_out; - - visitor(GeometryOut& geometry_out) - : m_geometry_out(geometry_out) - {} - - template - result_type operator()( - Geometry1 const& geometry1, - Geometry2 const& geometry2) const - { - return intersection - < - Geometry1, - Geometry2 - >::template apply - < - GeometryOut - > - (geometry1, geometry2, m_geometry_out); - } - }; - - template - static inline bool - apply( - const variant& geometry1, - const variant& geometry2, - GeometryOut& geometry_out) - { - return apply_visitor(visitor(geometry_out), geometry1, geometry2); - } -}; - -} // namespace resolve_variant - - -/*! -\brief \brief_calc2{intersection} -\ingroup intersection -\details \details_calc2{intersection, spatial set theoretic intersection}. -\tparam Geometry1 \tparam_geometry -\tparam Geometry2 \tparam_geometry -\tparam GeometryOut Collection of geometries (e.g. std::vector, std::deque, boost::geometry::multi*) of which - the value_type fulfills a \p_l_or_c concept, or it is the output geometry (e.g. for a box) -\param geometry1 \param_geometry -\param geometry2 \param_geometry -\param geometry_out The output geometry, either a multi_point, multi_polygon, - multi_linestring, or a box (for intersection of two boxes) - -\qbk{[include reference/algorithms/intersection.qbk]} -*/ -template -< - typename Geometry1, - typename Geometry2, - typename GeometryOut -> -inline bool intersection(Geometry1 const& geometry1, - Geometry2 const& geometry2, - GeometryOut& geometry_out) -{ - return resolve_variant::intersection - < - Geometry1, - Geometry2 - >::template apply - < - GeometryOut - > - (geometry1, geometry2, geometry_out); -} - - -}} // namespace boost::geometry +#include +#include #endif // BOOST_GEOMETRY_ALGORITHMS_INTERSECTION_HPP diff --git a/include/boost/geometry/algorithms/num_interior_rings.hpp b/include/boost/geometry/algorithms/num_interior_rings.hpp index e815f5981..034b918cb 100644 --- a/include/boost/geometry/algorithms/num_interior_rings.hpp +++ b/include/boost/geometry/algorithms/num_interior_rings.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 2014. +// Modifications copyright (c) 2014, 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. @@ -54,6 +59,28 @@ struct num_interior_rings }; +template +struct num_interior_rings +{ + static inline std::size_t apply(MultiPolygon const& multi_polygon) + { + std::size_t n = 0; + for (typename boost::range_iterator::type + it = boost::begin(multi_polygon); + it != boost::end(multi_polygon); + ++it) + { + n += num_interior_rings + < + typename boost::range_value::type + >::apply(*it); + } + return n; + } + +}; + + } // namespace dispatch #endif diff --git a/include/boost/geometry/algorithms/num_segments.hpp b/include/boost/geometry/algorithms/num_segments.hpp new file mode 100644 index 000000000..4f9d1257a --- /dev/null +++ b/include/boost/geometry/algorithms/num_segments.hpp @@ -0,0 +1,262 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_ALGORITHMS_NUM_SEGMENTS_HPP +#define BOOST_GEOMETRY_ALGORITHMS_NUM_SEGMENTS_HPP + +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + + +namespace boost { namespace geometry +{ + + + +#ifndef DOXYGEN_NO_DISPATCH +namespace dispatch +{ + +template +< + typename Geometry, + typename Tag = typename tag::type +> +struct num_segments + : not_implemented +{}; + +} // namespace dispatch +#endif // DOXYGEN_NO_DISPATCH + + + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace num_segments +{ + + +struct range_count +{ + template + static inline std::size_t apply(Range const& range, bool add_for_open) + { + std::size_t n = boost::size(range); + if ( n <= 1 ) + { + return 0; + } + if (add_for_open + && geometry::closure::value == open + && geometry::disjoint(range::front(range), range::at(range, n - 1)) + ) + { + return n; + } + return static_cast(n - 1); + } +}; + + +struct polygon_count + : private range_count +{ + template + static inline std::size_t apply(Polygon const& poly, bool add_for_open) + { + std::size_t n = range_count::apply(exterior_ring(poly), add_for_open); + + typename interior_return_type::type + rings = interior_rings(poly); + for (typename detail::interior_iterator::type + it = boost::begin(rings); it != boost::end(rings); ++it) + { + n += range_count::apply(*it, add_for_open); + } + + return n; + } +}; + + +struct multi_count +{ + template + static inline + std::size_t apply(MultiGeometry const& geometry, bool add_for_open) + { + typedef typename boost::range_value::type geometry_type; + typedef typename boost::range_iterator + < + MultiGeometry const + >::type iterator_type; + + std::size_t n = 0; + for (iterator_type it = boost::begin(geometry); + it != boost::end(geometry); ++it) + { + n += dispatch::num_segments + < + geometry_type + >::apply(*it, add_for_open); + } + return n; + } +}; + + +}} // namespace detail::num_segments +#endif // DOXYGEN_NO_DETAIL + + + +#ifndef DOXYGEN_NO_DISPATCH +namespace dispatch +{ + + +template +struct num_segments + : detail::num_points::other_count<0> +{}; + +template +struct num_segments + : detail::num_points::other_count<4> +{}; + +template +struct num_segments + : detail::num_points::other_count<1> +{}; + +template +struct num_segments + : detail::num_segments::range_count +{}; + +template +struct num_segments + : detail::num_segments::range_count +{}; + +template +struct num_segments + : detail::num_segments::polygon_count +{}; + +template +struct num_segments + : detail::num_points::other_count<0> +{}; + +template +struct num_segments + : detail::num_segments::multi_count +{}; + +template +struct num_segments + : detail::num_segments::multi_count +{}; + + +} // namespace dispatch +#endif // DOXYGEN_NO_DISPATCH + + + +namespace resolve_variant +{ + + +template +struct num_segments + : dispatch::num_segments +{}; + + +template +struct num_segments > +{ + struct visitor: boost::static_visitor + { + bool m_add_for_open; + + visitor(bool add_for_open): m_add_for_open(add_for_open) {} + + template + typename std::size_t operator()(Geometry const& geometry) const + { + return num_segments::apply(geometry, m_add_for_open); + } + }; + + static inline std::size_t + apply(boost::variant const& geometry, + bool add_for_open) + { + return boost::apply_visitor(visitor(add_for_open), geometry); + } +}; + + +} // namespace resolve_variant + + + +/*! +\brief \brief_calc{number of segments} +\ingroup num_segments +\details \details_calc{num_segments, number of segments}. +\tparam Geometry \tparam_geometry +\param geometry \param_geometry +\param add_for_open add one for open geometries (i.e. polygon types which are not closed) +\return \return_calc{number of segments} + +\qbk{[include reference/algorithms/num_segments.qbk]} +*/ +template +inline std::size_t num_segments(Geometry const& geometry, + bool add_for_open = false) +{ + concept::check(); + + return resolve_variant::num_segments + < + Geometry + >::apply(geometry, add_for_open); +} + + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_NUM_SEGMENTS_HPP diff --git a/include/boost/geometry/geometry.hpp b/include/boost/geometry/geometry.hpp index 35fb9b80f..110f0e60f 100644 --- a/include/boost/geometry/geometry.hpp +++ b/include/boost/geometry/geometry.hpp @@ -70,6 +70,7 @@ #include #include #include +#include #include #include #include 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 89dd5e5ff..7a96986a2 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-2013 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2014 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 @@ -54,12 +54,6 @@ public: // children are leafs if ( node_relative_level <= 1 ) { - /*if ( 0 < parameters.get_overlap_cost_threshold() && - parameters.get_overlap_cost_threshold() < children.size() ) - return choose_by_nearly_minimum_overlap_cost(children, indexable, parameters.get_overlap_cost_threshold()); - else - return choose_by_minimum_overlap_cost(children, indexable);*/ - return choose_by_minimum_overlap_cost(children, indexable, parameters.get_overlap_cost_threshold()); } // children are internal nodes @@ -112,31 +106,36 @@ private: if ( min_content_diff < -std::numeric_limits::epsilon() || std::numeric_limits::epsilon() < min_content_diff ) { + size_t first_n_children_count = children_count; if ( 0 < overlap_cost_threshold && overlap_cost_threshold < children.size() ) { - // calculate nearly minimum overlap cost - - // sort by content_diff - std::partial_sort(children_contents.begin(), children_contents.begin() + overlap_cost_threshold, children_contents.end(), content_diff_less); - choosen_index = choose_by_minimum_overlap_cost_sorted_by_content(children, indexable, children_count, overlap_cost_threshold, children_contents); + 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); } - else - { - // calculate minimum overlap cost - choosen_index = choose_by_minimum_overlap_cost_unsorted_by_content(children, indexable, children_count, children_contents); - } + // calculate minimum or nearly minimum overlap cost + choosen_index = choose_by_minimum_overlap_cost_first_n(children, indexable, first_n_children_count, children_count, children_contents); } return choosen_index; } - template - static inline size_t choose_by_minimum_overlap_cost_unsorted_by_content(children_type const& children, - Indexable const& indexable, - size_t children_count, - ChildrenContents const& children_contents) + static inline bool content_diff_less(boost::tuple const& p1, boost::tuple const& p2) { + return boost::get<1>(p1) < boost::get<1>(p2) || + (boost::get<1>(p1) == boost::get<1>(p2) && boost::get<2>(p1) < boost::get<2>(p2)); + } + + template + static inline size_t choose_by_minimum_overlap_cost_first_n(children_type const& children, + Indexable const& indexable, + size_t const first_n_children_count, + size_t const children_count, + ChildrenContents const& children_contents) + { + BOOST_GEOMETRY_INDEX_ASSERT(first_n_children_count <= children_count, "unexpected value"); BOOST_GEOMETRY_INDEX_ASSERT(children_contents.size() == children_count, "unexpected number of elements"); // choose index with smallest overlap change value, or content change or smallest content @@ -146,7 +145,7 @@ private: content_type smallest_content = (std::numeric_limits::max)(); // for each child node - for (size_t i = 0 ; i < children_count ; ++i ) + for (size_t i = 0 ; i < first_n_children_count ; ++i ) { child_type const& ch_i = children[i]; @@ -189,198 +188,6 @@ private: return choosen_index; } - - template - static inline size_t choose_by_minimum_overlap_cost_sorted_by_content(children_type const& children, - Indexable const& indexable, - size_t children_count, - size_t overlap_cost_threshold, - ChildrenContents const& children_contents) - { - BOOST_GEOMETRY_INDEX_ASSERT(overlap_cost_threshold < children_count, "unexpected value"); - BOOST_GEOMETRY_INDEX_ASSERT(children_count == children_contents.size(), "unexpected number of elements"); - - // for overlap_cost_threshold child nodes find the one with smallest overlap value - size_t choosen_index = 0; - content_type smallest_overlap_diff = (std::numeric_limits::max)(); - - // for each node - for (size_t i = 0 ; i < overlap_cost_threshold ; ++i ) - { - size_t child_index = boost::get<0>(children_contents[i]); - - typedef typename children_type::value_type child_type; - child_type const& ch_i = children[child_index]; - - Box box_exp(ch_i.first); - // calculate expanded box of child node ch_i - geometry::expand(box_exp, indexable); - - content_type overlap_diff = 0; - - // calculate overlap - for ( size_t j = 0 ; j < children_count ; ++j ) - { - if ( child_index != j ) - { - child_type const& ch_j = children[j]; - - content_type overlap_exp = index::detail::intersection_content(box_exp, ch_j.first); - if ( overlap_exp < -std::numeric_limits::epsilon() || std::numeric_limits::epsilon() < overlap_exp ) - { - overlap_diff += overlap_exp - index::detail::intersection_content(ch_i.first, ch_j.first); - } - } - } - - // update result - if ( overlap_diff < smallest_overlap_diff ) - { - smallest_overlap_diff = overlap_diff; - choosen_index = child_index; - } - } - - return choosen_index; - } - - //template - //static inline size_t choose_by_minimum_overlap_cost(children_type const& children, - // Indexable const& indexable) - //{ - // size_t children_count = children.size(); - - // // choose index with smallest overlap change value, or content change or smallest content - // size_t choosen_index = 0; - // content_type smallest_overlap_diff = (std::numeric_limits::max)(); - // content_type smallest_content_diff = (std::numeric_limits::max)(); - // content_type smallest_content = (std::numeric_limits::max)(); - - // // for each child node - // for (size_t i = 0 ; i < children_count ; ++i ) - // { - // child_type const& ch_i = children[i]; - - // Box box_exp(ch_i.first); - // // calculate expanded box of child node ch_i - // geometry::expand(box_exp, indexable); - - // // calculate content and content diff - // content_type content = index::detail::content(box_exp); - // content_type content_diff = content - index::detail::content(ch_i.first); - - // content_type overlap_diff = 0; - // - // // calculate overlap - // for ( size_t j = 0 ; j < children_count ; ++j ) - // { - // if ( i != j ) - // { - // child_type const& ch_j = children[j]; - - // content_type overlap_exp = index::detail::intersection_content(box_exp, ch_j.first); - // if ( overlap_exp < -std::numeric_limits::epsilon() || std::numeric_limits::epsilon() < overlap_exp ) - // { - // overlap_diff += overlap_exp - index::detail::intersection_content(ch_i.first, ch_j.first); - // } - // } - // } - - // // update result - // if ( overlap_diff < smallest_overlap_diff || - // ( overlap_diff == smallest_overlap_diff && ( content_diff < smallest_content_diff || - // ( content_diff == smallest_content_diff && content < smallest_content ) ) - // ) ) - // { - // smallest_overlap_diff = overlap_diff; - // smallest_content_diff = content_diff; - // smallest_content = content; - // choosen_index = i; - // } - // } - - // return choosen_index; - //} - - //template - //static inline size_t choose_by_nearly_minimum_overlap_cost(children_type const& children, - // Indexable const& indexable, - // size_t overlap_cost_threshold) - //{ - // const size_t children_count = children.size(); - - // // create container of children sorted by content enlargement needed to include the new value - // std::vector< boost::tuple > sorted_children(children_count); - // for ( size_t i = 0 ; i < children_count ; ++i ) - // { - // child_type const& ch_i = children[i]; - - // // expanded child node's box - // Box box_exp(ch_i.first); - // geometry::expand(box_exp, indexable); - - // // areas difference - // content_type content = index::detail::content(box_exp); - // content_type content_diff = content - index::detail::content(ch_i.first); - - // sorted_children[i] = boost::make_tuple(i, content_diff, content); - // } - - // BOOST_GEOMETRY_INDEX_ASSERT(overlap_cost_threshold <= children_count, "there is not enough children"); - - // // sort by content_diff - // //std::sort(sorted_children.begin(), sorted_children.end(), content_diff_less); - // std::partial_sort(sorted_children.begin(), sorted_children.begin() + overlap_cost_threshold, sorted_children.end(), content_diff_less); - - // // for overlap_cost_threshold child nodes find the one with smallest overlap value - // size_t choosen_index = 0; - // content_type smallest_overlap_diff = (std::numeric_limits::max)(); - - // // for each node - // for (size_t i = 0 ; i < overlap_cost_threshold ; ++i ) - // { - // size_t child_index = boost::get<0>(sorted_children[i]); - - // typedef typename children_type::value_type child_type; - // child_type const& ch_i = children[child_index]; - - // Box box_exp(ch_i.first); - // // calculate expanded box of child node ch_i - // geometry::expand(box_exp, indexable); - - // content_type overlap_diff = 0; - - // // calculate overlap - // for ( size_t j = 0 ; j < children_count ; ++j ) - // { - // if ( child_index != j ) - // { - // child_type const& ch_j = children[j]; - - // content_type overlap_exp = index::detail::intersection_content(box_exp, ch_j.first); - // if ( overlap_exp < -std::numeric_limits::epsilon() || std::numeric_limits::epsilon() < overlap_exp ) - // { - // overlap_diff += overlap_exp - index::detail::intersection_content(ch_i.first, ch_j.first); - // } - // } - // } - - // // update result - // if ( overlap_diff < smallest_overlap_diff ) - // { - // smallest_overlap_diff = overlap_diff; - // choosen_index = child_index; - // } - // } - - // return choosen_index; - //} - - static inline bool content_diff_less(boost::tuple const& p1, boost::tuple const& p2) - { - return boost::get<1>(p1) < boost::get<1>(p2) || - (boost::get<1>(p1) == boost::get<1>(p2) && boost::get<2>(p1) < boost::get<2>(p2)); - } template static inline size_t choose_by_minimum_content_cost(children_type const& children, Indexable const& indexable) 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 0caf53f94..21bdc986d 100644 --- a/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp +++ b/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp @@ -113,19 +113,28 @@ struct choose_split_axis_and_index_for_corner // copy elements Elements elements_copy(elements); // MAY THROW, STRONG (alloc, copy) + size_t const index_first = parameters.get_min_elements(); + size_t const index_last = parameters.get_max_elements() - parameters.get_min_elements() + 2; + // sort elements element_axis_corner_less elements_less(translator); std::sort(elements_copy.begin(), elements_copy.end(), elements_less); // MAY THROW, BASIC (copy) +// { +// 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) +// std::sort(f, l, elements_less); // MAY THROW, BASIC (copy) +// } // init outputs - choosen_index = parameters.get_min_elements(); + choosen_index = index_first; sum_of_margins = 0; smallest_overlap = (std::numeric_limits::max)(); smallest_content = (std::numeric_limits::max)(); // calculate sum of margins for all distributions - size_t index_last = parameters.get_max_elements() - parameters.get_min_elements() + 2; - for ( size_t i = parameters.get_min_elements() ; i < index_last ; ++i ) + for ( size_t i = index_first ; i < index_last ; ++i ) { // TODO - awulkiew: may be optimized - box of group 1 may be initialized with // box of min_elems number of elements and expanded for each iteration by another element @@ -320,50 +329,39 @@ struct choose_split_axis_and_index } }; -template -struct partial_sort +template +struct nth_element { BOOST_STATIC_ASSERT(0 < Dimension); + BOOST_STATIC_ASSERT(I < Dimension); template static inline void apply(Elements & elements, const size_t axis, const size_t index, Translator const& tr) { - if ( axis < Dimension - 1 ) + //BOOST_GEOMETRY_INDEX_ASSERT(axis < Dimension, "unexpected axis value"); + + if ( axis != I ) { - partial_sort::apply(elements, axis, index, tr); // MAY THROW, BASIC (copy) + nth_element::apply(elements, axis, index, tr); // MAY THROW, BASIC (copy) } else { - BOOST_GEOMETRY_INDEX_ASSERT(axis == Dimension - 1, "unexpected axis value"); - typedef typename Elements::value_type element_type; typedef typename rtree::element_indexable_type::type indexable_type; typedef typename tag::type indexable_tag; - element_axis_corner_less less(tr); - std::partial_sort(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy) + element_axis_corner_less less(tr); + std::nth_element(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy) } } }; -template -struct partial_sort +template +struct nth_element { template - static inline void apply(Elements & elements, - const size_t BOOST_GEOMETRY_INDEX_ASSERT_UNUSED_PARAM(axis), - const size_t index, - Translator const& tr) - { - BOOST_GEOMETRY_INDEX_ASSERT(axis == 0, "unexpected axis value"); - - typedef typename Elements::value_type element_type; - typedef typename rtree::element_indexable_type::type indexable_type; - typedef typename tag::type indexable_tag; - - element_axis_corner_less less(tr); - std::partial_sort(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy) - } + static inline void apply(Elements & /*elements*/, const size_t /*axis*/, const size_t /*index*/, Translator const& /*tr*/) + {} }; } // namespace rstar @@ -431,12 +429,12 @@ struct redistribute_elements(min_corner) ) { - rstar::partial_sort + rstar::nth_element ::apply(elements_copy, split_axis, split_index, translator); // MAY THROW, BASIC (copy) } else { - rstar::partial_sort + rstar::nth_element ::apply(elements_copy, split_axis, split_index, translator); // MAY THROW, BASIC (copy) } diff --git a/include/boost/geometry/multi/algorithms/append.hpp b/include/boost/geometry/multi/algorithms/append.hpp index 2a2596c54..d1589aca8 100644 --- a/include/boost/geometry/multi/algorithms/append.hpp +++ b/include/boost/geometry/multi/algorithms/append.hpp @@ -8,6 +8,7 @@ // Modifications copyright (c) 2014, 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. @@ -19,88 +20,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_APPEND_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_APPEND_HPP + #include -#include -#include - - -namespace boost { namespace geometry -{ - - -#ifndef DOXYGEN_NO_DETAIL -namespace detail { namespace append -{ - - -template -struct append_to_multigeometry -{ - static inline void apply(MultiGeometry& multigeometry, - RangeOrPoint const& range_or_point, - int ring_index, int multi_index) - { - - dispatch::append - < - typename boost::range_value::type, - RangeOrPoint - >::apply(multigeometry[multi_index], range_or_point, ring_index); - } -}; - - -}} // namespace detail::append -#endif // DOXYGEN_NO_DETAIL - - - -#ifndef DOXYGEN_NO_DISPATCH -namespace dispatch -{ - -namespace splitted_dispatch -{ - -template -struct append_point - : detail::append::append_point -{}; - -template -struct append_range - : detail::append::append_range -{}; - -template -struct append_point - : detail::append::append_to_multigeometry -{}; - -template -struct append_range - : detail::append::append_to_multigeometry -{}; - -template -struct append_point - : detail::append::append_to_multigeometry -{}; - -template -struct append_range - : detail::append::append_to_multigeometry -{}; - -} - - -} // namespace dispatch -#endif // DOXYGEN_NO_DISPATCH - - -}} // namespace boost::geometry - #endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_APPEND_HPP diff --git a/include/boost/geometry/multi/algorithms/intersection.hpp b/include/boost/geometry/multi/algorithms/intersection.hpp index e0f3592e8..f43446325 100644 --- a/include/boost/geometry/multi/algorithms/intersection.hpp +++ b/include/boost/geometry/multi/algorithms/intersection.hpp @@ -2,6 +2,11 @@ // 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. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -9,407 +14,9 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_INTERSECTION_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_INTERSECTION_HPP -#include -#include -#include -#include -#include -#include - -// TODO: those headers probably may be removed -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include - -namespace boost { namespace geometry -{ - -#ifndef DOXYGEN_NO_DETAIL -namespace detail { namespace intersection -{ - - -template -struct intersection_multi_linestring_multi_linestring_point -{ - template - < - typename MultiLinestring1, typename MultiLinestring2, - typename RobustPolicy, - typename OutputIterator, typename Strategy - > - static inline OutputIterator apply(MultiLinestring1 const& ml1, - MultiLinestring2 const& ml2, - RobustPolicy const& robust_policy, - OutputIterator out, - Strategy const& strategy) - { - // Note, this loop is quadratic w.r.t. number of linestrings per input. - // Future Enhancement: first do the sections of each, then intersect. - for (typename boost::range_iterator - < - MultiLinestring1 const - >::type it1 = boost::begin(ml1); - it1 != boost::end(ml1); - ++it1) - { - for (typename boost::range_iterator - < - MultiLinestring2 const - >::type it2 = boost::begin(ml2); - it2 != boost::end(ml2); - ++it2) - { - out = intersection_linestring_linestring_point - ::apply(*it1, *it2, robust_policy, out, strategy); - } - } - - return out; - } -}; - - -template -struct intersection_linestring_multi_linestring_point -{ - template - < - typename Linestring, typename MultiLinestring, - typename RobustPolicy, - typename OutputIterator, typename Strategy - > - static inline OutputIterator apply(Linestring const& linestring, - MultiLinestring const& ml, - RobustPolicy const& robust_policy, - OutputIterator out, - Strategy const& strategy) - { - for (typename boost::range_iterator - < - MultiLinestring const - >::type it = boost::begin(ml); - it != boost::end(ml); - ++it) - { - out = intersection_linestring_linestring_point - ::apply(linestring, *it, robust_policy, out, strategy); - } - - return out; - } -}; - - -// This loop is quite similar to the loop above, but beacuse the iterator -// is second (above) or first (below) argument, it is not trivial to merge them. -template -< - bool ReverseAreal, - typename LineStringOut, - overlay_type OverlayType -> -struct intersection_of_multi_linestring_with_areal -{ - template - < - typename MultiLinestring, typename Areal, - typename RobustPolicy, - typename OutputIterator, typename Strategy - > - static inline OutputIterator apply(MultiLinestring const& ml, Areal const& areal, - RobustPolicy const& robust_policy, - OutputIterator out, - Strategy const& strategy) - { - for (typename boost::range_iterator - < - MultiLinestring const - >::type it = boost::begin(ml); - it != boost::end(ml); - ++it) - { - out = intersection_of_linestring_with_areal - < - ReverseAreal, LineStringOut, OverlayType - >::apply(*it, areal, robust_policy, out, strategy); - } - - return out; - - } -}; - -// This one calls the one above with reversed arguments -template -< - bool ReverseAreal, - typename LineStringOut, - overlay_type OverlayType -> -struct intersection_of_areal_with_multi_linestring -{ - template - < - typename Areal, typename MultiLinestring, - typename RobustPolicy, - typename OutputIterator, typename Strategy - > - static inline OutputIterator apply(Areal const& areal, MultiLinestring const& ml, - RobustPolicy const& robust_policy, - OutputIterator out, - Strategy const& strategy) - { - return intersection_of_multi_linestring_with_areal - < - ReverseAreal, LineStringOut, OverlayType - >::apply(ml, areal, robust_policy, out, strategy); - } -}; - - - -template -struct clip_multi_linestring -{ - template - < - typename MultiLinestring, typename Box, - typename RobustPolicy, - typename OutputIterator, typename Strategy - > - static inline OutputIterator apply(MultiLinestring const& multi_linestring, - Box const& box, - RobustPolicy const& robust_policy, - OutputIterator out, Strategy const& ) - { - typedef typename point_type::type point_type; - strategy::intersection::liang_barsky lb_strategy; - for (typename boost::range_iterator::type it - = boost::begin(multi_linestring); - it != boost::end(multi_linestring); ++it) - { - out = detail::intersection::clip_range_with_box - (box, *it, robust_policy, out, lb_strategy); - } - return out; - } -}; - - -}} // namespace detail::intersection -#endif // DOXYGEN_NO_DETAIL - - -#ifndef DOXYGEN_NO_DISPATCH -namespace dispatch -{ - - -// Linear -template -< - typename MultiLinestring1, typename MultiLinestring2, - typename GeometryOut, - overlay_type OverlayType, - bool Reverse1, bool Reverse2, bool ReverseOut -> -struct intersection_insert - < - MultiLinestring1, MultiLinestring2, - GeometryOut, - OverlayType, - Reverse1, Reverse2, ReverseOut, - multi_linestring_tag, multi_linestring_tag, point_tag, - false, false, false - > : detail::intersection::intersection_multi_linestring_multi_linestring_point - < - GeometryOut - > -{}; - - -template -< - typename Linestring, typename MultiLinestring, - typename GeometryOut, - overlay_type OverlayType, - bool Reverse1, bool Reverse2, bool ReverseOut -> -struct intersection_insert - < - Linestring, MultiLinestring, - GeometryOut, - OverlayType, - Reverse1, Reverse2, ReverseOut, - linestring_tag, multi_linestring_tag, point_tag, - false, false, false - > : detail::intersection::intersection_linestring_multi_linestring_point - < - GeometryOut - > -{}; - - -template -< - typename MultiLinestring, typename Box, - typename GeometryOut, - overlay_type OverlayType, - bool Reverse1, bool Reverse2, bool ReverseOut -> -struct intersection_insert - < - MultiLinestring, Box, - GeometryOut, - OverlayType, - Reverse1, Reverse2, ReverseOut, - multi_linestring_tag, box_tag, linestring_tag, - false, true, false - > : detail::intersection::clip_multi_linestring - < - GeometryOut - > -{}; - - -template -< - typename Linestring, typename MultiPolygon, - typename GeometryOut, - overlay_type OverlayType, - bool ReverseLinestring, bool ReverseMultiPolygon, bool ReverseOut -> -struct intersection_insert - < - Linestring, MultiPolygon, - GeometryOut, - OverlayType, - ReverseLinestring, ReverseMultiPolygon, ReverseOut, - linestring_tag, multi_polygon_tag, linestring_tag, - false, true, false - > : detail::intersection::intersection_of_linestring_with_areal - < - ReverseMultiPolygon, - GeometryOut, - OverlayType - > -{}; - - -// Derives from areal/mls because runtime arguments are in that order. -// areal/mls reverses it itself to mls/areal -template -< - typename Polygon, typename MultiLinestring, - typename GeometryOut, - overlay_type OverlayType, - bool ReversePolygon, bool ReverseMultiLinestring, bool ReverseOut -> -struct intersection_insert - < - Polygon, MultiLinestring, - GeometryOut, - OverlayType, - ReversePolygon, ReverseMultiLinestring, ReverseOut, - polygon_tag, multi_linestring_tag, linestring_tag, - true, false, false - > : detail::intersection::intersection_of_areal_with_multi_linestring - < - ReversePolygon, - GeometryOut, - OverlayType - > -{}; - - -template -< - typename MultiLinestring, typename Ring, - typename GeometryOut, - overlay_type OverlayType, - bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut -> -struct intersection_insert - < - MultiLinestring, Ring, - GeometryOut, - OverlayType, - ReverseMultiLinestring, ReverseRing, ReverseOut, - multi_linestring_tag, ring_tag, linestring_tag, - false, true, false - > : detail::intersection::intersection_of_multi_linestring_with_areal - < - ReverseRing, - GeometryOut, - OverlayType - > -{}; - -template -< - typename MultiLinestring, typename Polygon, - typename GeometryOut, - overlay_type OverlayType, - bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut -> -struct intersection_insert - < - MultiLinestring, Polygon, - GeometryOut, - OverlayType, - ReverseMultiLinestring, ReverseRing, ReverseOut, - multi_linestring_tag, polygon_tag, linestring_tag, - false, true, false - > : detail::intersection::intersection_of_multi_linestring_with_areal - < - ReverseRing, - GeometryOut, - OverlayType - > -{}; - - - -template -< - typename MultiLinestring, typename MultiPolygon, - typename GeometryOut, - overlay_type OverlayType, - bool ReverseMultiLinestring, bool ReverseMultiPolygon, bool ReverseOut -> -struct intersection_insert - < - MultiLinestring, MultiPolygon, - GeometryOut, - OverlayType, - ReverseMultiLinestring, ReverseMultiPolygon, ReverseOut, - multi_linestring_tag, multi_polygon_tag, linestring_tag, - false, true, false - > : detail::intersection::intersection_of_multi_linestring_with_areal - < - ReverseMultiPolygon, - GeometryOut, - OverlayType - > -{}; - - -} // namespace dispatch -#endif - -}} // namespace boost::geometry - #endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_INTERSECTION_HPP diff --git a/include/boost/geometry/multi/algorithms/num_interior_rings.hpp b/include/boost/geometry/multi/algorithms/num_interior_rings.hpp index 5b52508b7..fbaa113af 100644 --- a/include/boost/geometry/multi/algorithms/num_interior_rings.hpp +++ b/include/boost/geometry/multi/algorithms/num_interior_rings.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 2014. +// Modifications copyright (c) 2014, 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,48 +19,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_INTERIOR_RINGS_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_INTERIOR_RINGS_HPP -#include - -#include - -#include -#include -#include #include -namespace boost { namespace geometry -{ - -#ifndef DOXYGEN_NO_DISPATCH -namespace dispatch -{ - - -template -struct num_interior_rings -{ - static inline std::size_t apply(MultiPolygon const& multi_polygon) - { - std::size_t n = 0; - for (typename boost::range_iterator::type - it = boost::begin(multi_polygon); - it != boost::end(multi_polygon); - ++it) - { - n += geometry::num_interior_rings(*it); - } - return n; - } - -}; - -} // namespace dispatch -#endif - - -}} // namespace boost::geometry - - #endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_INTERIOR_RINGS_HPP diff --git a/include/boost/geometry/multi/multi.hpp b/include/boost/geometry/multi/multi.hpp index 24e39c3c7..815c25331 100644 --- a/include/boost/geometry/multi/multi.hpp +++ b/include/boost/geometry/multi/multi.hpp @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -39,8 +40,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -49,9 +52,6 @@ #include #include -#include -#include -#include #include #include diff --git a/include/boost/geometry/views/box_view.hpp b/include/boost/geometry/views/box_view.hpp index 3f448efe8..4ecb941ec 100644 --- a/include/boost/geometry/views/box_view.hpp +++ b/include/boost/geometry/views/box_view.hpp @@ -68,7 +68,11 @@ private : inline void apply(point_type* points) const { - detail::assign_box_corners_oriented(m_box, points); + // assign_box_corners_oriented requires a range + // an alternative for this workaround would be to pass a range here, + // e.g. use boost::array in points_view instead of c-array + std::pair rng = std::make_pair(points, points + 5); + detail::assign_box_corners_oriented(m_box, rng); points[4] = points[0]; } private : diff --git a/include/boost/geometry/views/detail/points_view.hpp b/include/boost/geometry/views/detail/points_view.hpp index 3f6fdc609..a06084216 100644 --- a/include/boost/geometry/views/detail/points_view.hpp +++ b/include/boost/geometry/views/detail/points_view.hpp @@ -36,6 +36,7 @@ class points_view // to have it lightweight). Probably there is already an // equivalent of this within Boost. If so, TODO: use that one. // This used to be "box_iterator" and "segment_iterator". + // ALTERNATIVE: use boost:array and its iterators struct points_iterator : public boost::iterator_facade < @@ -105,7 +106,7 @@ class points_view } Point const* m_points; - int m_index; + difference_type m_index; }; public : diff --git a/test/algorithms/Jamfile.v2 b/test/algorithms/Jamfile.v2 index 0be34e556..3abb5d24f 100644 --- a/test/algorithms/Jamfile.v2 +++ b/test/algorithms/Jamfile.v2 @@ -16,13 +16,13 @@ test-suite boost-geometry-algorithms : [ run append.cpp : : : msvc:/bigobj ] - [ run area.cpp ] + [ run area.cpp : : : msvc:/bigobj ] [ run assign.cpp ] [ run buffer.cpp ] [ run centroid.cpp : : : msvc:/bigobj ] - [ run comparable_distance.cpp ] + [ run comparable_distance.cpp : : : msvc:/bigobj ] [ run convex_hull.cpp : : : msvc:/bigobj ] - [ run correct.cpp ] + [ run correct.cpp : : : msvc:/bigobj ] [ run convert.cpp : : : msvc:/bigobj ] [ run covered_by.cpp ] [ run crosses.cpp : : : msvc:/bigobj ] @@ -30,10 +30,10 @@ test-suite boost-geometry-algorithms [ run difference_linear_linear.cpp ] [ run difference_pl_pl.cpp ] [ run disjoint.cpp : : : msvc:/bigobj ] - [ run disjoint_coverage.cpp ] + [ run disjoint_coverage.cpp : : : msvc:/bigobj ] [ run distance.cpp : : : msvc:/bigobj ] - [ run distance_areal_areal.cpp ] - [ run distance_linear_areal.cpp ] + [ run distance_areal_areal.cpp : : : msvc:/bigobj ] + [ run distance_linear_areal.cpp : : : msvc:/bigobj ] [ run distance_linear_linear.cpp ] [ run distance_pointlike_areal.cpp ] [ run distance_pointlike_linear.cpp ] @@ -46,11 +46,12 @@ test-suite boost-geometry-algorithms [ run intersection_linear_linear.cpp ] [ run intersection_pl_pl.cpp ] [ run intersects.cpp : : : msvc:/bigobj ] - [ run is_simple.cpp ] - [ run is_valid.cpp ] + [ run is_simple.cpp : : : msvc:/bigobj ] + [ run is_valid.cpp : : : msvc:/bigobj ] [ run length.cpp ] [ run make.cpp ] [ run num_points.cpp ] + [ run num_segments.cpp ] [ run overlaps.cpp : : : msvc:/bigobj ] [ run perimeter.cpp ] [ run point_on_surface.cpp ] diff --git a/test/algorithms/from_wkt.hpp b/test/algorithms/from_wkt.hpp index 5c78afdea..a12dc051d 100644 --- a/test/algorithms/from_wkt.hpp +++ b/test/algorithms/from_wkt.hpp @@ -13,6 +13,8 @@ #ifndef BOOST_GEOMETRY_TEST_FROM_WKT_HPP #define BOOST_GEOMETRY_TEST_FROM_WKT_HPP +#include + #include #include diff --git a/test/algorithms/num_segments.cpp b/test/algorithms/num_segments.cpp new file mode 100644 index 000000000..cc2e791b8 --- /dev/null +++ b/test/algorithms/num_segments.cpp @@ -0,0 +1,277 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// Unit Test + +// Copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_TEST_MODULE +#define BOOST_TEST_MODULE test_num_segments +#endif + +#include + +#include + +#include + +#include +#include +#include +#include + +namespace bg = boost::geometry; + + +typedef bg::model::point point; +typedef bg::model::linestring linestring; +typedef bg::model::segment segment; +typedef bg::model::box box; +typedef bg::model::ring ring_cw_closed; +typedef bg::model::ring ring_cw_open; +typedef bg::model::ring ring_ccw_closed; +typedef bg::model::ring ring_ccw_open; +typedef bg::model::polygon polygon_cw_closed; +typedef bg::model::polygon polygon_cw_open; +typedef bg::model::polygon polygon_ccw_closed; +typedef bg::model::polygon polygon_ccw_open; +typedef bg::model::multi_point multi_point; +typedef bg::model::multi_linestring multi_linestring; +typedef bg::model::multi_polygon multi_polygon_cw_closed; +typedef bg::model::multi_polygon multi_polygon_cw_open; +typedef bg::model::multi_polygon multi_polygon_ccw_closed; +typedef bg::model::multi_polygon multi_polygon_ccw_open; + + +template +struct test_num_segments +{ + static inline void apply(Geometry const& geometry, + std::size_t expected_closed, + std::size_t expected_open) + { + std::size_t detected = bg::num_segments(geometry); + BOOST_CHECK_MESSAGE( detected == expected_closed, + "Expected: " << expected_closed + << " detected: " << detected + << " wkt: " << bg::wkt(geometry) ); + + detected = bg::num_segments(geometry, true); + BOOST_CHECK_MESSAGE( detected == expected_open, + "Expected (add for open): " << expected_open + << " detected (add for open): " << detected + << " wkt: " << bg::wkt(geometry) ); + + } + + static inline void apply(Geometry const& geometry, + std::size_t expected_closed) + { + apply(geometry, expected_closed, expected_closed); + } + + static inline void apply(std::string const& wkt, + std::size_t expected_closed, + std::size_t expected_open) + { + Geometry geometry; + bg::read_wkt(wkt, geometry); + apply(geometry, expected_closed, expected_open); + } + + static inline void apply(std::string const& wkt, + std::size_t expected_closed) + { + apply(wkt, expected_closed, expected_closed); + } +}; + +BOOST_AUTO_TEST_CASE( test_point ) +{ + test_num_segments::apply("POINT(0 0)", 0); +} + +BOOST_AUTO_TEST_CASE( test_segment ) +{ + test_num_segments::apply("SEGMENT(0 0,1 1)", 1); +} + +BOOST_AUTO_TEST_CASE( test_box ) +{ + test_num_segments::apply("BOX(0 0,1 1)", 4); +} + +BOOST_AUTO_TEST_CASE( test_linestring ) +{ + typedef test_num_segments tester; + + tester::apply("LINESTRING()", 0); + tester::apply("LINESTRING(0 0)", 0); + tester::apply("LINESTRING(0 0,0 0)", 1); + tester::apply("LINESTRING(0 0,0 0,1 1)", 2); + tester::apply("LINESTRING(0 0,0 0,0 0,1 1)", 3); +} + +BOOST_AUTO_TEST_CASE( test_multipoint ) +{ + typedef test_num_segments tester; + + tester::apply("MULTIPOINT()", 0); + tester::apply("MULTIPOINT(0 0)", 0); + tester::apply("MULTIPOINT(0 0,0 0)", 0); + tester::apply("MULTIPOINT(0 0,0 0,1 1)", 0); +} + +BOOST_AUTO_TEST_CASE( test_multilinestring ) +{ + typedef test_num_segments tester; + + tester::apply("MULTILINESTRING()", 0); + tester::apply("MULTILINESTRING((),(0 0))", 0); + tester::apply("MULTILINESTRING((0 0))", 0); + tester::apply("MULTILINESTRING((0 0,1 0))", 1); + tester::apply("MULTILINESTRING((),(),(0 0,1 0))", 1); + tester::apply("MULTILINESTRING((0 0,1 0,0 1),(0 0,1 0,0 1,0 0))", 5); +} + +template +void test_open_ring() +{ + typedef test_num_segments tester; + + tester::apply("POLYGON(())", 0); + tester::apply("POLYGON((0 0))", 0); + tester::apply("POLYGON((0 0,1 0))", 1, 2); + tester::apply("POLYGON((0 0,1 0,0 1))", 2, 3); + tester::apply("POLYGON((0 0,0 0,1 0,0 1))", 3, 4); +} + +template +void test_closed_ring() +{ + typedef test_num_segments tester; + + tester::apply("POLYGON(())", 0); + tester::apply("POLYGON((0 0))", 0); + tester::apply("POLYGON((0 0,0 0))", 1); + tester::apply("POLYGON((0 0,1 0,0 0))", 2); + tester::apply("POLYGON((0 0,1 0,0 1,0 0))", 3); + tester::apply("POLYGON((0 0,1 0,1 0,0 1,0 0))", 4); +} + +BOOST_AUTO_TEST_CASE( test_ring ) +{ + test_open_ring(); + test_open_ring(); + test_closed_ring(); + test_closed_ring(); +} + +template +void test_open_polygon() +{ + typedef test_num_segments tester; + + tester::apply("POLYGON(())", 0); + tester::apply("POLYGON((0 0))", 0); + tester::apply("POLYGON((0 0,10 0),(0 0))", 1, 2); + tester::apply("POLYGON((0 0,10 0),(1 1,2 1))", 2, 4); + tester::apply("POLYGON((0 0,10 0,0 10))", 2, 3); + tester::apply("POLYGON((0 0,10 0,0 10),())", 2, 3); + tester::apply("POLYGON((0 0,10 0,0 10),(1 1))", 2, 3); + tester::apply("POLYGON((0 0,10 0,0 10),(1 1,2 1))", 3, 5); + tester::apply("POLYGON((0 0,10 0,0 10),(1 1,2 1,1 2))", 4, 6); + tester::apply("POLYGON((0 0,10 0,10 10,0 10),(1 1,2 1,1 2))", 5, 7); + tester::apply("POLYGON((0 0,10 0,10 10,0 10),(1 1,2 1,2 2,1 2))", 6, 8); + tester::apply("POLYGON((0 0,10 0,10 10,0 10),(1 1,2 1,2 2,1 2),(5 5,6 5,6 6,5 6))", 9, 12); +} + +template +void test_closed_polygon() +{ + typedef test_num_segments tester; + + tester::apply("POLYGON(())", 0); + tester::apply("POLYGON((0 0))", 0); + tester::apply("POLYGON((0 0,10 0,0 0),(0 0))", 2); + tester::apply("POLYGON((0 0,10 0,0 0),(1 1,2 1,1 1))", 4); + tester::apply("POLYGON((0 0,10 0,0 10,0 0))", 3); + tester::apply("POLYGON((0 0,10 0,0 10,0 0),())", 3); + tester::apply("POLYGON((0 0,10 0,0 10,0 0),(1 1))", 3); + tester::apply("POLYGON((0 0,10 0,0 10,0 0),(1 1,2 1,1 1))", 5); + tester::apply("POLYGON((0 0,10 0,0 10,0 0),(1 1,2 1,1 2,1 1))", 6); + tester::apply("POLYGON((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,1 2,1 1))", 7); + tester::apply("POLYGON((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,2 2,1 2,1 1))", 8); + tester::apply("POLYGON((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,2 2,1 2,1 1),(5 5,6 5,6 6,5 6,5 5))", 12); +} + +BOOST_AUTO_TEST_CASE( test_polygon ) +{ + test_open_polygon(); + test_open_polygon(); + test_closed_polygon(); + test_closed_polygon(); +} + +template +void test_open_multipolygon() +{ + typedef test_num_segments tester; + + tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10),(1 1,2 1,1 2)))", 5, 7); + tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10),(1 1,2 1,2 2,1 2),(5 5,6 5,6 6,5 6)))", 9, 12); + tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10),(1 1,2 1,1 2)),((100 100,110 100,110 110),(101 101,102 101,102 102)))", 9, 13); + tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10),(1 1,2 1,2 2,1 2),(5 5,6 5,6 6,5 6)),((100 100,110 100,110 110),(101 101,102 101,102 102),(105 105,106 105,106 106,105 106)))", 16, 22); +} + +template +void test_closed_multipolygon() +{ + typedef test_num_segments tester; + + tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,1 2,1 1)))", 7); + tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,2 2,1 2,1 1),(5 5,6 5,6 6,5 6,5 5)))", 12); + tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,1 2,1 1)),((100 100,110 100,110 110,100 100),(101 101,102 101,102 102,101 101)))", 13); + tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,2 2,1 2,1 1),(5 5,6 5,6 6,5 6,5 5)),((100 100,110 100,110 110,100 100),(101 101,102 101,102 102,101 101),(105 105,106 105,106 106,105 106,105 105)))", 22); +} + +BOOST_AUTO_TEST_CASE( test_multipolygon ) +{ + test_open_multipolygon(); + test_open_multipolygon(); + test_closed_multipolygon(); + test_closed_multipolygon(); +} + +BOOST_AUTO_TEST_CASE( test_variant ) +{ + typedef boost::variant + < + linestring, polygon_cw_open, polygon_cw_closed + > variant_geometry_type; + + typedef test_num_segments tester; + + linestring ls; + bg::read_wkt("LINESTRING(0 0,1 1,2 2)", ls); + + polygon_cw_open p_open; + bg::read_wkt("POLYGON((0 0,0 1,1 0))", p_open); + + polygon_cw_closed p_closed; + bg::read_wkt("POLYGON((0 0,0 1,1 1,1 0,0 0))", p_closed); + + variant_geometry_type variant_geometry; + + variant_geometry = ls; + tester::apply(variant_geometry, 2); + + variant_geometry = p_open; + tester::apply(variant_geometry, 2, 3); + + variant_geometry = p_closed; + tester::apply(variant_geometry, 4); +} diff --git a/test/algorithms/test_difference.hpp b/test/algorithms/test_difference.hpp index 4520cd311..f97c6860f 100644 --- a/test/algorithms/test_difference.hpp +++ b/test/algorithms/test_difference.hpp @@ -107,7 +107,7 @@ void test_difference(std::string const& caseid, G1 const& g1, G2 const& g2, } typename bg::default_area_result::type area = 0; - int n = 0; + std::size_t n = 0; for (typename std::vector::iterator it = clip.begin(); it != clip.end(); ++it) @@ -157,7 +157,7 @@ void test_difference(std::string const& caseid, G1 const& g1, G2 const& g2, #if ! defined(BOOST_GEOMETRY_NO_BOOST_TEST) if (expected_point_count >= 0) { - BOOST_CHECK_MESSAGE(bg::math::abs(n - expected_point_count) < 3, + BOOST_CHECK_MESSAGE(bg::math::abs(int(n) - expected_point_count) < 3, "difference: " << caseid << " #points expected: " << expected_point_count << " detected: " << n diff --git a/test/algorithms/within_pointlike_xxx.cpp b/test/algorithms/within_pointlike_xxx.cpp index aa0a96929..392ee5f78 100644 --- a/test/algorithms/within_pointlike_xxx.cpp +++ b/test/algorithms/within_pointlike_xxx.cpp @@ -219,6 +219,18 @@ void test_tickets() bool within = boost::geometry::within(p, r); BOOST_CHECK_EQUAL(within, false); } + + // https://svn.boost.org/trac/boost/ticket/10234 + { + pt p; + ring r; + bg::read_wkt("POINT(0.1377 5.00)", p); + bg::read_wkt("POLYGON((0.1277 4.97, 0.1277 5.00, 0.1278 4.9999999999999982, 0.1278 4.97, 0.1277 4.97))", r); + bool within = boost::geometry::within(p, r); + BOOST_CHECK_EQUAL(within, false); + bool covered_by = boost::geometry::covered_by(p, r); + BOOST_CHECK_EQUAL(covered_by, false); + } } int test_main( int , char* [] ) diff --git a/test/robustness/overlay/buffer/recursive_polygons_buffer.cpp b/test/robustness/overlay/buffer/recursive_polygons_buffer.cpp index 6516e7e24..d62e83a2b 100644 --- a/test/robustness/overlay/buffer/recursive_polygons_buffer.cpp +++ b/test/robustness/overlay/buffer/recursive_polygons_buffer.cpp @@ -28,15 +28,9 @@ #include #include -#include -#include - #include -#include // TODO: more specific - #include -#include #include #include @@ -197,28 +191,31 @@ bool test_buffer(MultiPolygon& result, int& index, typedef bg::strategy::buffer::distance_asymmetric distance_strategy_type; distance_strategy_type distance_strategy(settings.distance, settings.distance); - typedef bg::strategy::buffer::join_round join_strategy_type; - join_strategy_type join_strategy; - typedef typename boost::range_value::type polygon_type; MultiPolygon buffered; std::ostringstream out; out << "recursive_polygons_buffer_" << index++ << "_" << level; + bg::strategy::buffer::end_round end_strategy; + bg::strategy::buffer::point_circle point_strategy; + bg::strategy::buffer::side_straight side_strategy; + try { switch(settings.join_code) { case 1 : - bg::buffer_inserter(mp, std::back_inserter(buffered), - distance_strategy, - bg::strategy::buffer::join_round()); + bg::buffer(mp, buffered, + distance_strategy, side_strategy, + bg::strategy::buffer::join_round(), + end_strategy, point_strategy); break; case 2 : - bg::buffer_inserter(mp, std::back_inserter(buffered), - distance_strategy, - bg::strategy::buffer::join_miter()); + bg::buffer(mp, buffered, + distance_strategy, side_strategy, + bg::strategy::buffer::join_miter(), + end_strategy, point_strategy); break; default : return false; diff --git a/test/test_geometries/wrapped_boost_array.hpp b/test/test_geometries/wrapped_boost_array.hpp index cb4aadafa..8f4d8e39b 100644 --- a/test/test_geometries/wrapped_boost_array.hpp +++ b/test/test_geometries/wrapped_boost_array.hpp @@ -30,7 +30,7 @@ struct wrapped_boost_array inline wrapped_boost_array() : size(0) {} boost::array array; - int size; + std::size_t size; };