diff --git a/doc/geometry.qbk b/doc/geometry.qbk index 214636142..d282a7b2a 100644 --- a/doc/geometry.qbk +++ b/doc/geometry.qbk @@ -113,6 +113,7 @@ Boost.Geometry contains contributions by: * Federico Fern\u00E1ndez (preliminary version of R-tree spatial index) * Karsten Ahnert (patch for cross-track distance) * Mats Taraldsvik (documentation: adapting a legacy model) +* Matt Amos (fixes for point_on_surface) * Samuel Debionne (variant support for distance, assign, crosses, intersection, ...) [include imports.qbk] diff --git a/doc/release_notes.qbk b/doc/release_notes.qbk index 7fd40cdd0..70c726f54 100644 --- a/doc/release_notes.qbk +++ b/doc/release_notes.qbk @@ -22,18 +22,31 @@ [*Improvements] * The support of parameters convertible to value_type in rtree insert(), remove() and count() functions +* Support for counterclockwise input/output in algorithm buffer +* Support for open-geometry input in algorithm buffer (open output not yet supported) +* Support for degenerate input (point-like linestrings, polygons) in algorithm buffer [*Solved tickets] -* [@https://svn.boost.org/trac/boost/ticket/8402 8402] Implicit casts warnings +* [@https://svn.boost.org/trac/boost/ticket/8402 8402] Implicit conversion warnings * [@https://svn.boost.org/trac/boost/ticket/9354 9354] Bug in winding strategy affecting within() and covered_by() for non-cartesian coordinate systems * [@https://svn.boost.org/trac/boost/ticket/10177 10177] Missing include +* [@https://svn.boost.org/trac/boost/ticket/10345 10345] Distance fails to compile for some coordinate types * [@https://svn.boost.org/trac/boost/ticket/10398 10398] Wrong neighbour check in buffer, calculating turns +* [@https://svn.boost.org/trac/boost/ticket/10421 10421] Invalid Point-Box distance for spherical CS * [@https://svn.boost.org/trac/boost/ticket/10615 10615] Rtree constructor feature request * [@https://svn.boost.org/trac/boost/ticket/10643 10643] Invalid point_on_surface() result for big coordinates +* [@https://svn.boost.org/trac/boost/ticket/10668 10668] Implicit conversion warnings (duplicated 8402) [*Bugfixes] +* Several fixes of bugs in algorithm buffer +* Bug in point_on_surface() for CCW Polygons (extreme_points()) and numerical issue (thanks to Matt Amos) +* Bug in disjoint() for A/A fixed by replacement of point_on_surface() with point_on_border() (thanks to Matt Amos) +* The result of convex_hull(), duplicated Point in open output, too small number of Points for 1- and 2-Point input +* Imprecision for big coordinates in centroid(), fixed by Points translation (related with ticket 10643) +* for_each_segment() not taking into account the last segment of open Geometry + [/=================] [heading Boost 1.56] [/=================] @@ -41,7 +54,7 @@ [*Additional functionality] * New algorithm buffer for inflating/deflating geometries (buffer itself already existed but that was only to enlarge a box) -* New algorithm remove_spikes, algorithm to remove spikes from a ring, polygon or multi_polygon. +* New algorithm remove_spikes, algorithm to remove spikes from a ring, polygon or multi_polygon * New algorithm point_on_surface, generating a point lying on the surface (interior) of the polygon * New algorithm is_simple, returning true if a geometry is simple according to the OGC standard * New algorithm is_valid, returning true if a geometry is valid according to the OGC standard diff --git a/include/boost/geometry/algorithms/centroid.hpp b/include/boost/geometry/algorithms/centroid.hpp index 2d8a737a1..65dc9c375 100644 --- a/include/boost/geometry/algorithms/centroid.hpp +++ b/include/boost/geometry/algorithms/centroid.hpp @@ -5,6 +5,11 @@ // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland. +// 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. @@ -19,7 +24,6 @@ #include #include -#include #include #include #include @@ -36,6 +40,7 @@ #include +#include #include #include #include @@ -50,6 +55,8 @@ #include #include +#include + namespace boost { namespace geometry { @@ -188,17 +195,19 @@ inline bool range_ok(Range const& range, Point& centroid) return true; } - /*! - \brief Calculate the centroid of a ring. + \brief Calculate the centroid of a Ring or a Linestring. */ template struct centroid_range_state { - template + template static inline void apply(Ring const& ring, - Strategy const& strategy, typename Strategy::state_type& state) + PointTransformer const& transformer, + Strategy const& strategy, + typename Strategy::state_type& state) { + typedef typename geometry::point_type::type point_type; typedef typename closeable_view::type view_type; typedef typename boost::range_iterator::type iterator_type; @@ -207,11 +216,19 @@ struct centroid_range_state iterator_type it = boost::begin(view); iterator_type end = boost::end(view); - for (iterator_type previous = it++; - it != end; - ++previous, ++it) + typename PointTransformer::result_type + previous_pt = transformer.apply(*it); + + for ( ++it ; it != end ; ++it) { - strategy.apply(*previous, *it, state); + typename PointTransformer::result_type + pt = transformer.apply(*it); + + strategy.apply(static_cast(previous_pt), + static_cast(pt), + state); + + previous_pt = pt; } } }; @@ -221,13 +238,20 @@ struct centroid_range { template static inline void apply(Range const& range, Point& centroid, - Strategy const& strategy) + Strategy const& strategy) { if (range_ok(range, centroid)) { + // prepare translation transformer + translating_transformer transformer(*boost::begin(range)); + typename Strategy::state_type state; - centroid_range_state::apply(range, strategy, state); + centroid_range_state::apply(range, transformer, + strategy, state); strategy.result(state, centroid); + + // translate the result back + transformer.apply_reverse(centroid); } } }; @@ -240,14 +264,16 @@ struct centroid_range */ struct centroid_polygon_state { - template + template static inline void apply(Polygon const& poly, - Strategy const& strategy, typename Strategy::state_type& state) + PointTransformer const& transformer, + Strategy const& strategy, + typename Strategy::state_type& state) { typedef typename ring_type::type ring_type; typedef centroid_range_state::value> per_ring; - per_ring::apply(exterior_ring(poly), strategy, state); + per_ring::apply(exterior_ring(poly), transformer, strategy, state); typename interior_return_type::type rings = interior_rings(poly); @@ -255,7 +281,7 @@ struct centroid_polygon_state for (typename detail::interior_iterator::type it = boost::begin(rings); it != boost::end(rings); ++it) { - per_ring::apply(*it, strategy, state); + per_ring::apply(*it, transformer, strategy, state); } } }; @@ -268,9 +294,16 @@ struct centroid_polygon { if (range_ok(exterior_ring(poly), centroid)) { + // prepare translation transformer + translating_transformer + transformer(*boost::begin(exterior_ring(poly))); + typename Strategy::state_type state; - centroid_polygon_state::apply(poly, strategy, state); + centroid_polygon_state::apply(poly, transformer, strategy, state); strategy.result(state, centroid); + + // translate the result back + transformer.apply_reverse(centroid); } } }; @@ -282,11 +315,14 @@ struct centroid_polygon */ struct centroid_multi_point_state { - template + template static inline void apply(Point const& point, - Strategy const& strategy, typename Strategy::state_type& state) + PointTransformer const& transformer, + Strategy const& strategy, + typename Strategy::state_type& state) { - strategy.apply(point, state); + strategy.apply(static_cast(transformer.apply(point)), + state); } }; @@ -303,8 +339,9 @@ template struct centroid_multi { template - static inline void apply(Multi const& multi, Point& centroid, - Strategy const& strategy) + static inline void apply(Multi const& multi, + Point& centroid, + Strategy const& strategy) { #if ! defined(BOOST_GEOMETRY_CENTROID_NO_THROW) // If there is nothing in any of the ranges, it is not possible @@ -315,6 +352,9 @@ struct centroid_multi } #endif + // prepare translation transformer + translating_transformer transformer(multi); + typename Strategy::state_type state; for (typename boost::range_iterator::type @@ -322,9 +362,12 @@ struct centroid_multi it != boost::end(multi); ++it) { - Policy::apply(*it, strategy, state); + Policy::apply(*it, transformer, strategy, state); } Strategy::result(state, centroid); + + // translate the result back + transformer.apply_reverse(centroid); } }; diff --git a/include/boost/geometry/algorithms/convex_hull.hpp b/include/boost/geometry/algorithms/convex_hull.hpp index d5bd4d92a..09f4c5142 100644 --- a/include/boost/geometry/algorithms/convex_hull.hpp +++ b/include/boost/geometry/algorithms/convex_hull.hpp @@ -4,6 +4,11 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 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. @@ -21,6 +26,7 @@ #include #include +#include #include #include @@ -44,7 +50,7 @@ namespace boost { namespace geometry namespace detail { namespace convex_hull { -template +template struct hull_insert { @@ -57,7 +63,7 @@ struct hull_insert typename Strategy::state_type state; strategy.apply(geometry, state); - strategy.result(state, out, Order == clockwise); + strategy.result(state, out, Order == clockwise, Closure != open); return out; } }; @@ -70,7 +76,8 @@ struct hull_to_geometry { hull_insert < - geometry::point_order::value + geometry::point_order::value, + geometry::closure::value >::apply(geometry, std::back_inserter( // Handle linestring, ring and polygon the same: @@ -124,9 +131,9 @@ struct convex_hull -template +template struct convex_hull_insert - : detail::convex_hull::hull_insert + : detail::convex_hull::hull_insert {}; @@ -171,7 +178,8 @@ struct convex_hull_insert BOOST_CONCEPT_ASSERT( (geometry::concept::ConvexHullStrategy) ); return dispatch::convex_hull_insert< - geometry::point_order::value + geometry::point_order::value, + geometry::closure::value >::apply(geometry, out, strategy); } @@ -189,7 +197,7 @@ struct convex_hull_insert } }; -}; // namespace resolve_strategy +} // namespace resolve_strategy namespace resolve_variant { diff --git a/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp b/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp index 7a901c869..b2e316837 100644 --- a/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp @@ -12,10 +12,12 @@ #include #include +#include #include #include +#include #include #include @@ -29,6 +31,8 @@ #include +#include + #if defined(BOOST_GEOMETRY_BUFFER_SIMPLIFY_WITH_AX) #include #endif @@ -87,6 +91,13 @@ inline void simplify_input(Range const& range, geometry::simplify(range, simplified, max_distance, strategy); #endif + + if (boost::size(simplified) == 2 + && geometry::equals(geometry::range::front(simplified), + geometry::range::back(simplified))) + { + traits::resize::apply(simplified, 1); + } } @@ -202,7 +213,7 @@ struct buffer_range typename EndStrategy, typename RobustPolicy > - static inline void iterate(Collection& collection, + static inline bool iterate(Collection& collection, Iterator begin, Iterator end, strategy::buffer::buffer_side_selector side, DistanceStrategy const& distance_strategy, @@ -215,6 +226,8 @@ struct buffer_range output_point_type& last_p1, output_point_type& last_p2) { + boost::ignore_unused(side_strategy); + typedef typename std::iterator_traits < Iterator @@ -246,6 +259,7 @@ struct buffer_range * pup: penultimate_point */ + bool result = false; bool first = true; Iterator it = begin; @@ -259,14 +273,21 @@ struct buffer_range { robust_point_type robust_input; geometry::recalculate(robust_input, *it, robust_policy); - // Check on equality - however, if input is simplified, this is highly - // unlikely (though possible by rescaling) + // Check on equality - however, if input is simplified, this is + // unlikely (though possible by rescaling or for degenerated pointlike polygons) if (! detail::equals::equals_point_point(previous_robust_input, robust_input)) { generated_side.clear(); side_strategy.apply(*prev, *it, side, distance_strategy, generated_side); + if (generated_side.empty()) + { + break; + } + + result = true; + if (! first) { add_join(collection, @@ -295,6 +316,7 @@ struct buffer_range } previous_robust_input = robust_input; } + return result; } }; @@ -345,6 +367,26 @@ struct visit_pieces_default_policy {} }; +template +< + typename OutputPointType, + typename Point, + typename Collection, + typename DistanceStrategy, + typename PointStrategy +> +inline void buffer_point(Point const& point, Collection& collection, + DistanceStrategy const& distance_strategy, + PointStrategy const& point_strategy) +{ + collection.start_new_ring(); + std::vector range_out; + point_strategy.apply(point, distance_strategy, range_out); + collection.add_piece(strategy::buffer::buffered_point, range_out, false); + collection.finish_ring(); +} + + }} // namespace detail::buffer #endif // DOXYGEN_NO_DETAIL @@ -389,13 +431,10 @@ struct buffer_inserter PointStrategy const& point_strategy, RobustPolicy const& ) { - typedef typename point_type::type output_point_type; - - collection.start_new_ring(); - std::vector range_out; - point_strategy.apply(point, distance_strategy, range_out); - collection.add_piece(strategy::buffer::buffered_point, range_out, false); - collection.finish_ring(); + detail::buffer::buffer_point + < + typename point_type::type + >(point, collection, distance_strategy, point_strategy); } }; @@ -419,7 +458,7 @@ struct buffer_inserter typename EndStrategy, typename RobustPolicy > - static inline void iterate(Collection& collection, + static inline bool iterate(Collection& collection, Iterator begin, Iterator end, strategy::buffer::buffer_side_selector side, DistanceStrategy const& distance_strategy, @@ -432,21 +471,25 @@ struct buffer_inserter typedef detail::buffer::buffer_range buffer_range; - buffer_range::iterate(collection, begin, end, + bool result = buffer_range::iterate(collection, begin, end, side, distance_strategy, side_strategy, join_strategy, end_strategy, robust_policy, first_p1, first_p2, last_p1, last_p2); // Generate closing join - buffer_range::add_join(collection, - *(end - 2), - *(end - 1), last_p1, last_p2, - *(begin + 1), first_p1, first_p2, - side, - distance_strategy, join_strategy, end_strategy, - robust_policy); + if (result) + { + buffer_range::add_join(collection, + *(end - 2), + *(end - 1), last_p1, last_p2, + *(begin + 1), first_p1, first_p2, + side, + distance_strategy, join_strategy, end_strategy, + robust_policy); + } // Buffer is closed automatically by last closing corner + return result; } template @@ -465,30 +508,48 @@ struct buffer_inserter SideStrategy const& side_strategy, JoinStrategy const& join_strategy, EndStrategy const& end_strategy, - PointStrategy const& , + PointStrategy const& point_strategy, RobustPolicy const& robust_policy) { - if (boost::size(ring) > 3) - { - RingOutput simplified; - detail::buffer::simplify_input(ring, distance, simplified); + RingInput simplified; + detail::buffer::simplify_input(ring, distance, simplified); + bool has_output = false; + + std::size_t n = boost::size(simplified); + std::size_t const min_points = core_detail::closure::minimum_ring_size + < + geometry::closure::value + >::value; + + if (n >= min_points) + { + detail::normalized_view view(simplified); if (distance.negative()) { // Walk backwards (rings will be reversed afterwards) // It might be that this will be changed later. // TODO: decide this. - iterate(collection, boost::rbegin(simplified), boost::rend(simplified), + has_output = iterate(collection, boost::rbegin(view), boost::rend(view), strategy::buffer::buffer_side_right, distance, side_strategy, join_strategy, end_strategy, robust_policy); } else { - iterate(collection, boost::begin(simplified), boost::end(simplified), + has_output = iterate(collection, boost::begin(view), boost::end(view), strategy::buffer::buffer_side_left, distance, side_strategy, join_strategy, end_strategy, robust_policy); } + } + if (! has_output && n >= 1) + { + // Use point_strategy to buffer degenerated ring + detail::buffer::buffer_point + ( + geometry::range::front(simplified), + collection, distance, point_strategy + ); } } }; @@ -505,19 +566,6 @@ struct buffer_inserter typedef typename point_type::type output_point_type; typedef typename point_type::type input_point_type; - template - static inline output_point_type first_perpendicular_point( - input_point_type const& p1, input_point_type const& p2, - DistanceStrategy const& distance_strategy, - SideStrategy const& side_strategy) - { - std::vector generated_side; - side_strategy.apply(p1, p2, - strategy::buffer::buffer_side_right, - distance_strategy, generated_side); - return generated_side.front(); - } - template < typename Collection, @@ -528,7 +576,7 @@ struct buffer_inserter typename EndStrategy, typename RobustPolicy > - static inline void iterate(Collection& collection, + static inline bool iterate(Collection& collection, Iterator begin, Iterator end, strategy::buffer::buffer_side_selector side, DistanceStrategy const& distance_strategy, @@ -545,10 +593,23 @@ struct buffer_inserter // other side of the linestring. If it is the second pass (right), // we have it already from the first phase (left). // But for the first pass, we have to generate it - output_point_type reverse_p1 - = side == strategy::buffer::buffer_side_right - ? first_p1 - : first_perpendicular_point(ultimate_point, penultimate_point, distance_strategy, side_strategy); + output_point_type reverse_p1; + if (side == strategy::buffer::buffer_side_right) + { + reverse_p1 = first_p1; + } + else + { + std::vector generated_side; + side_strategy.apply(ultimate_point, penultimate_point, + strategy::buffer::buffer_side_right, + distance_strategy, generated_side); + if (generated_side.empty()) + { + return false; + } + reverse_p1 = generated_side.front(); + } output_point_type first_p2, last_p1, last_p2; @@ -560,6 +621,7 @@ struct buffer_inserter std::vector range_out; end_strategy.apply(penultimate_point, last_p2, ultimate_point, reverse_p1, side, distance_strategy, range_out); collection.add_endcap(end_strategy, range_out, ultimate_point); + return true; } template @@ -577,30 +639,41 @@ struct buffer_inserter SideStrategy const& side_strategy, JoinStrategy const& join_strategy, EndStrategy const& end_strategy, - PointStrategy const& , + PointStrategy const& point_strategy, RobustPolicy const& robust_policy) { - if (boost::size(linestring) > 1) - { - Linestring simplified; - detail::buffer::simplify_input(linestring, distance, simplified); + Linestring simplified; + detail::buffer::simplify_input(linestring, distance, simplified); + bool has_output = false; + std::size_t n = boost::size(simplified); + if (n > 1) + { collection.start_new_ring(); output_point_type first_p1; - iterate(collection, boost::begin(simplified), boost::end(simplified), + has_output = iterate(collection, + boost::begin(simplified), boost::end(simplified), strategy::buffer::buffer_side_left, distance, side_strategy, join_strategy, end_strategy, robust_policy, first_p1); - iterate(collection, boost::rbegin(simplified), boost::rend(simplified), - strategy::buffer::buffer_side_right, - distance, side_strategy, join_strategy, end_strategy, robust_policy, - first_p1); + if (has_output) + { + iterate(collection, boost::rbegin(simplified), boost::rend(simplified), + strategy::buffer::buffer_side_right, + distance, side_strategy, join_strategy, end_strategy, robust_policy, + first_p1); + } collection.finish_ring(); } - else + if (! has_output && n >= 1) { // Use point_strategy to buffer degenerated linestring + detail::buffer::buffer_point + ( + geometry::range::front(simplified), + collection, distance, point_strategy + ); } } }; @@ -769,6 +842,8 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator VisitPiecesPolicy& visit_pieces_policy ) { + boost::ignore_unused(visit_pieces_policy); + typedef detail::buffer::buffered_piece_collection < typename geometry::ring_type::type, @@ -800,7 +875,7 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator collection.get_turns(); if (areal) { - collection.check_remaining_points(distance_strategy.factor()); + collection.check_remaining_points(distance_strategy); } // Visit the piece collection. This does nothing (by default), but @@ -814,7 +889,16 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator collection.enrich(); collection.traverse(); - if (distance_strategy.negative() && areal) + // Reverse all offsetted rings / traversed rings if: + // - they were generated on the negative side (deflate) of polygons + // - the output is counter clockwise + // and avoid reversing twice + bool reverse = distance_strategy.negative() && areal; + if (geometry::point_order::value == counterclockwise) + { + reverse = ! reverse; + } + if (reverse) { collection.reverse(); } diff --git a/include/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp b/include/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp index 6a2e6b32c..67845861d 100644 --- a/include/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp @@ -35,7 +35,7 @@ namespace detail { namespace buffer enum intersection_location_type { - location_ok, inside_buffer, inside_original + location_ok, inside_buffer, location_discard }; class backtrack_for_buffer diff --git a/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp b/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp index 3a002601c..c9a91905a 100644 --- a/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp @@ -12,8 +12,9 @@ #include #include #include -#include +#include +#include #include #include @@ -117,6 +118,8 @@ struct buffered_piece_collection point_type, RobustPolicy >::type robust_point_type; + + // Robust ring/polygon type, always clockwise typedef geometry::model::ring robust_ring_type; typedef geometry::model::polygon robust_polygon_type; @@ -392,32 +395,60 @@ struct buffered_piece_collection // will never start a new ring from this type of points. it->selectable_start = false; } - } } - inline void check_remaining_points(int factor) + template + inline void check_point_in_original(buffer_turn_info_type& turn, + DistanceStrategy const& distance_strategy) { - // TODO: use partition + strategy::within::winding winding; + + for (std::size_t i = 0; i < robust_polygons.size(); i++) + { + int const code = detail::within::point_in_geometry(turn.robust_point, + robust_polygons[i], winding); + + switch (code) + { + case 0 : + // On border of original: always discard + turn.location = location_discard; + return; + case 1 : + // Inside original + if (distance_strategy.negative()) + { + // For deflate: it is inside the (multi)polygon + // OK, no action, we can return + } + else + { + // For inflate: it is inside, discard + turn.location = location_discard; + } + return; + } + } + + if (distance_strategy.negative()) + { + // For deflate: it was not found in one of the polygons, discard + turn.location = location_discard; + } + } + + template + inline void check_remaining_points(DistanceStrategy const& distance_strategy) + { + // TODO: partition: this one is, together with the overlay, quadratic for (typename boost::range_iterator::type it = boost::begin(m_turns); it != boost::end(m_turns); ++it) { if (it->location == location_ok) { - int code = -1; - for (std::size_t i = 0; i < robust_polygons.size(); i++) - { - if (geometry::covered_by(it->robust_point, robust_polygons[i])) - { - code = 1; - break; - } - } - if (code * factor == 1) - { - it->location = inside_original; - } + check_point_in_original(*it, distance_strategy); } } } @@ -571,7 +602,11 @@ struct buffered_piece_collection inline void finish_ring(bool is_interior = false) { - BOOST_ASSERT(m_first_piece_index != -1); + if (m_first_piece_index == -1) + { + return; + } + if (m_first_piece_index < static_cast(boost::size(m_pieces))) { // If piece was added @@ -628,6 +663,7 @@ struct buffered_piece_collection std::size_t const n = boost::size(offsetted_rings.back()); pc.first_seg_id.segment_index = decrease_segment_index_by_one ? n - 1 : n; + pc.last_segment_index = pc.first_seg_id.segment_index; m_pieces.push_back(pc); return m_pieces.back(); @@ -724,10 +760,7 @@ struct buffered_piece_collection template inline void add_range_to_piece(piece& pc, Range const& range, bool add_front) { - if (boost::size(range) == 0u) - { - return; - } + BOOST_ASSERT(boost::size(range) != 0u); typename Range::const_iterator it = boost::begin(range); @@ -750,7 +783,11 @@ struct buffered_piece_collection inline void add_piece(strategy::buffer::piece_type type, Range const& range, bool decrease_segment_index_by_one) { piece& pc = create_piece(type, decrease_segment_index_by_one); - add_range_to_piece(pc, range, offsetted_rings.back().empty()); + + if (boost::size(range) > 0u) + { + add_range_to_piece(pc, range, offsetted_rings.back().empty()); + } finish_piece(pc); } @@ -770,9 +807,9 @@ struct buffered_piece_collection { piece& pc = create_piece(type, true); - add_range_to_piece(pc, range, offsetted_rings.back().empty()); - if (boost::size(range) > 0) + if (boost::size(range) > 0u) { + add_range_to_piece(pc, range, offsetted_rings.back().empty()); finish_piece(pc, range.back(), p, range.front()); } else @@ -784,6 +821,8 @@ struct buffered_piece_collection template inline void add_endcap(EndcapStrategy const& strategy, Range const& range, point_type const& end_point) { + boost::ignore_unused(strategy); + if (range.empty()) { return; diff --git a/include/boost/geometry/algorithms/detail/centroid/translating_transformer.hpp b/include/boost/geometry/algorithms/detail/centroid/translating_transformer.hpp new file mode 100644 index 000000000..56a7e3ec9 --- /dev/null +++ b/include/boost/geometry/algorithms/detail/centroid/translating_transformer.hpp @@ -0,0 +1,119 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland. + +// 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_CENTROID_TRANSLATING_TRANSFORMER_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CENTROID_TRANSLATING_TRANSFORMER_HPP + + +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#include + + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace centroid +{ + + +// NOTE: There is no need to translate in other coordinate systems than +// cartesian. But if it was needed then one should translate using +// CS-specific technique, e.g. in spherical/geographic a translation +// vector should contain coordinates being multiplies of 2PI or 360 deg. +template ::type, + areal_tag + >::type, + typename CSTag = typename cs_tag::type> +struct translating_transformer +{ + typedef typename geometry::point_type::type point_type; + typedef boost::reference_wrapper result_type; + + explicit translating_transformer(Geometry const&) {} + explicit translating_transformer(point_type const&) {} + + result_type apply(point_type const& pt) const + { + return result_type(pt); + } + + template + void apply_reverse(ResPt &) const {} +}; + +// Specialization for Areal Geometries in cartesian CS +template +struct translating_transformer +{ + typedef typename geometry::point_type::type point_type; + typedef point_type result_type; + + explicit translating_transformer(Geometry const& geom) + : m_origin(NULL) + { + geometry::point_iterator + pt_it = geometry::points_begin(geom); + if ( pt_it != geometry::points_end(geom) ) + { + m_origin = boost::addressof(*pt_it); + } + } + + explicit translating_transformer(point_type const& origin) + : m_origin(boost::addressof(origin)) + {} + + result_type apply(point_type const& pt) const + { + point_type res = pt; + if ( m_origin ) + geometry::subtract_point(res, *m_origin); + return res; + } + + template + void apply_reverse(ResPt & res_pt) const + { + if ( m_origin ) + geometry::add_point(res_pt, *m_origin); + } + + const point_type * m_origin; +}; + + +}} // namespace detail::centroid +#endif // DOXYGEN_NO_DETAIL + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CENTROID_TRANSLATING_TRANSFORMER_HPP diff --git a/include/boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp b/include/boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp new file mode 100644 index 000000000..04fa9ee86 --- /dev/null +++ b/include/boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp @@ -0,0 +1,146 @@ +// 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_DETAIL_CLOSEST_FEATURE_GEOMETRY_TO_RANGE_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_GEOMETRY_TO_RANGE_HPP + +#include + +#include + +#include +#include +#include + +#include + + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace closest_feature +{ + + + +// returns the range iterator the realizes the closest +// distance between the geometry and the element of the range +class geometry_to_range +{ +private: + template + < + typename Geometry, + typename RangeIterator, + typename Strategy, + typename Distance + > + static inline void apply(Geometry const& geometry, + RangeIterator first, + RangeIterator last, + Strategy const& strategy, + RangeIterator& it_min, + Distance& dist_min) + { + BOOST_ASSERT( first != last ); + + Distance const zero = Distance(0); + + // start with first distance + it_min = first; + dist_min = dispatch::distance + < + Geometry, + typename std::iterator_traits::value_type, + Strategy + >::apply(geometry, *it_min, strategy); + + // check if other elements in the range are closer + for (RangeIterator it = ++first; it != last; ++it) + { + Distance dist = dispatch::distance + < + Geometry, + typename std::iterator_traits::value_type, + Strategy + >::apply(geometry, *it, strategy); + + if (geometry::math::equals(dist, zero)) + { + dist_min = dist; + it_min = it; + return; + } + else if (dist < dist_min) + { + dist_min = dist; + it_min = it; + } + } + } + +public: + template + < + typename Geometry, + typename RangeIterator, + typename Strategy, + typename Distance + > + static inline RangeIterator apply(Geometry const& geometry, + RangeIterator first, + RangeIterator last, + Strategy const& strategy, + Distance& dist_min) + { + RangeIterator it_min; + apply(geometry, first, last, strategy, it_min, dist_min); + + return it_min; + } + + + template + < + typename Geometry, + typename RangeIterator, + typename Strategy + > + static inline RangeIterator apply(Geometry const& geometry, + RangeIterator first, + RangeIterator last, + Strategy const& strategy) + { + typename strategy::distance::services::return_type + < + Strategy, + typename point_type::type, + typename point_type + < + typename std::iterator_traits + < + RangeIterator + >::value_type + >::type + >::type dist_min; + + return apply(geometry, first, last, strategy, dist_min); + } +}; + + + +}} // namespace detail::closest_feature +#endif // DOXYGEN_NO_DETAIL + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_GEOMETRY_TO_RANGE_HPP diff --git a/include/boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp b/include/boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp new file mode 100644 index 000000000..91be6b0ad --- /dev/null +++ b/include/boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp @@ -0,0 +1,250 @@ +// 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_DETAIL_CLOSEST_FEATURE_POINT_TO_RANGE_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_POINT_TO_RANGE_HPP + +#include + +#include +#include + +#include +#include +#include + + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace closest_feature +{ + + +// returns the segment (pair of iterators) that realizes the closest +// distance of the point to the range +template +< + typename Point, + typename Range, + closure_selector Closure, + typename Strategy +> +class point_to_point_range +{ +protected: + typedef typename boost::range_iterator::type iterator_type; + + template + static inline void apply(Point const& point, + iterator_type first, + iterator_type last, + Strategy const& strategy, + iterator_type& it_min1, + iterator_type& it_min2, + Distance& dist_min) + { + BOOST_ASSERT( first != last ); + + Distance const zero = Distance(0); + + iterator_type it = first; + iterator_type prev = it++; + if (it == last) + { + it_min1 = it_min2 = first; + dist_min = strategy.apply(point, *first, *first); + return; + } + + // start with first segment distance + dist_min = strategy.apply(point, *prev, *it); + iterator_type prev_min_dist = prev; + + // check if other segments are closer + for (++prev, ++it; it != last; ++prev, ++it) + { + Distance dist = strategy.apply(point, *prev, *it); + if (geometry::math::equals(dist, zero)) + { + dist_min = zero; + it_min1 = prev; + it_min2 = it; + return; + } + else if (dist < dist_min) + { + dist_min = dist; + prev_min_dist = prev; + } + } + + it_min1 = it_min2 = prev_min_dist; + ++it_min2; + } + +public: + typedef typename std::pair return_type; + + template + static inline return_type apply(Point const& point, + iterator_type first, + iterator_type last, + Strategy const& strategy, + Distance& dist_min) + { + iterator_type it_min1, it_min2; + apply(point, first, last, strategy, it_min1, it_min2, dist_min); + + return std::make_pair(it_min1, it_min2); + } + + static inline return_type apply(Point const& point, + iterator_type first, + iterator_type last, + Strategy const& strategy) + { + typename strategy::distance::services::return_type + < + Strategy, + Point, + typename boost::range_value::type + >::type dist_min; + + return apply(point, first, last, strategy, dist_min); + } + + template + static inline return_type apply(Point const& point, + Range const& range, + Strategy const& strategy, + Distance& dist_min) + { + return apply(point, + boost::begin(range), + boost::end(range), + strategy, + dist_min); + } + + static inline return_type apply(Point const& point, + Range const& range, + Strategy const& strategy) + { + return apply(point, boost::begin(range), boost::end(range), strategy); + } +}; + + + +// specialization for open ranges +template +class point_to_point_range + : point_to_point_range +{ +private: + typedef point_to_point_range base_type; + typedef typename base_type::iterator_type iterator_type; + + template + static inline void apply(Point const& point, + iterator_type first, + iterator_type last, + Strategy const& strategy, + iterator_type& it_min1, + iterator_type& it_min2, + Distance& dist_min) + { + BOOST_ASSERT( first != last ); + + base_type::apply(point, first, last, strategy, + it_min1, it_min2, dist_min); + + iterator_type it_back = --last; + Distance const zero = Distance(0); + Distance dist = strategy.apply(point, *it_back, *first); + + if (geometry::math::equals(dist, zero)) + { + dist_min = zero; + it_min1 = it_back; + it_min2 = first; + } + else if (dist < dist_min) + { + dist_min = dist; + it_min1 = it_back; + it_min2 = first; + } + } + +public: + typedef typename std::pair return_type; + + template + static inline return_type apply(Point const& point, + iterator_type first, + iterator_type last, + Strategy const& strategy, + Distance& dist_min) + { + iterator_type it_min1, it_min2; + + apply(point, first, last, strategy, it_min1, it_min2, dist_min); + + return std::make_pair(it_min1, it_min2); + } + + static inline return_type apply(Point const& point, + iterator_type first, + iterator_type last, + Strategy const& strategy) + { + typedef typename strategy::distance::services::return_type + < + Strategy, + Point, + typename boost::range_value::type + >::type distance_return_type; + + distance_return_type dist_min; + + return apply(point, first, last, strategy, dist_min); + } + + template + static inline return_type apply(Point const& point, + Range const& range, + Strategy const& strategy, + Distance& dist_min) + { + return apply(point, + boost::begin(range), + boost::end(range), + strategy, + dist_min); + } + + static inline return_type apply(Point const& point, + Range const& range, + Strategy const& strategy) + { + return apply(point, boost::begin(range), boost::end(range), strategy); + } +}; + + +}} // namespace detail::closest_feature +#endif // DOXYGEN_NO_DETAIL + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_POINT_TO_RANGE_HPP diff --git a/include/boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp b/include/boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp new file mode 100644 index 000000000..90248767e --- /dev/null +++ b/include/boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp @@ -0,0 +1,196 @@ +// 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_DETAIL_CLOSEST_FEATURE_RANGE_TO_RANGE_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_RANGE_TO_RANGE_HPP + +#include + +#include +#include + +#include + +#include +#include +#include +#include + + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace closest_feature +{ + + +// returns a pair of a objects where the first is an object of the +// r-tree range and the second an object of the query range that +// realizes the closest feature of the two ranges +class range_to_range_rtree +{ +private: + template + < + typename RTreeRangeIterator, + typename QueryRangeIterator, + typename Strategy, + typename RTreeValueType, + typename Distance + > + static inline void apply(RTreeRangeIterator rtree_first, + RTreeRangeIterator rtree_last, + QueryRangeIterator queries_first, + QueryRangeIterator queries_last, + Strategy const& strategy, + RTreeValueType& rtree_min, + QueryRangeIterator& qit_min, + Distance& dist_min) + { + typedef index::rtree > rtree_type; + + BOOST_ASSERT( rtree_first != rtree_last ); + BOOST_ASSERT( queries_first != queries_last ); + + Distance const zero = Distance(0); + + // create -- packing algorithm + rtree_type rt(rtree_first, rtree_last); + + RTreeValueType t_v; + bool first = true; + + for (QueryRangeIterator qit = queries_first; + qit != queries_last; ++qit, first = false) + { + std::size_t n = rt.query(index::nearest(*qit, 1), &t_v); + + BOOST_ASSERT( n > 0 ); + // n above is unused outside BOOST_ASSERT, hence the call + // to boost::ignore_unused below + // + // however, t_v (initialized by the call to rt.query(...)) + // is used below, which is why we cannot put the call to + // rt.query(...) inside BOOST_ASSERT + boost::ignore_unused(n); + + Distance dist = dispatch::distance + < + RTreeValueType, + typename std::iterator_traits + < + QueryRangeIterator + >::value_type, + Strategy + >::apply(t_v, *qit, strategy); + + if (first || dist < dist_min) + { + dist_min = dist; + rtree_min = t_v; + qit_min = qit; + if ( math::equals(dist_min, zero) ) + { + return; + } + } + } + } + +public: + template + struct return_type + { + typedef std::pair + < + typename std::iterator_traits::value_type, + QueryRangeIterator + > type; + }; + + + template + < + typename RTreeRangeIterator, + typename QueryRangeIterator, + typename Strategy, + typename Distance + > + static inline typename return_type + < + RTreeRangeIterator, QueryRangeIterator + >::type apply(RTreeRangeIterator rtree_first, + RTreeRangeIterator rtree_last, + QueryRangeIterator queries_first, + QueryRangeIterator queries_last, + Strategy const& strategy, + Distance& dist_min) + { + typedef typename std::iterator_traits + < + RTreeRangeIterator + >::value_type rtree_value_type; + + rtree_value_type rtree_min; + QueryRangeIterator qit_min; + + apply(rtree_first, rtree_last, queries_first, queries_last, + strategy, rtree_min, qit_min, dist_min); + + return std::make_pair(rtree_min, qit_min); + } + + + template + < + typename RTreeRangeIterator, + typename QueryRangeIterator, + typename Strategy + > + static inline typename return_type + < + RTreeRangeIterator, QueryRangeIterator + >::type apply(RTreeRangeIterator rtree_first, + RTreeRangeIterator rtree_last, + QueryRangeIterator queries_first, + QueryRangeIterator queries_last, + Strategy const& strategy) + { + typedef typename std::iterator_traits + < + RTreeRangeIterator + >::value_type rtree_value_type; + + typename strategy::distance::services::return_type + < + Strategy, + typename point_type::type, + typename point_type + < + typename std::iterator_traits + < + QueryRangeIterator + >::value_type + >::type + >::type dist_min; + + return apply(rtree_first, rtree_last, queries_first, queries_last, + strategy, dist_min); + } +}; + + +}} // namespace detail::closest_feature +#endif // DOXYGEN_NO_DETAIL + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_RANGE_TO_RANGE_HPP diff --git a/include/boost/geometry/algorithms/detail/course.hpp b/include/boost/geometry/algorithms/detail/course.hpp new file mode 100644 index 000000000..e1a74c0fe --- /dev/null +++ b/include/boost/geometry/algorithms/detail/course.hpp @@ -0,0 +1,56 @@ +// 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_COURSE_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_COURSE_HPP + +#include +#include +#include +#include + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail +{ + +/// Calculate course (bearing) between two points. +template +inline ReturnType course(Point1 const& p1, Point2 const& p2) +{ + // http://williams.best.vwh.net/avform.htm#Crs + ReturnType dlon = get_as_radian<0>(p2) - get_as_radian<0>(p1); + ReturnType cos_p2lat = cos(get_as_radian<1>(p2)); + + // An optimization which should kick in often for Boxes + //if ( math::equals(dlon, ReturnType(0)) ) + //if ( get<0>(p1) == get<0>(p2) ) + //{ + // return - sin(get_as_radian<1>(p1)) * cos_p2lat); + //} + + // "An alternative formula, not requiring the pre-computation of d" + // In the formula below dlon is used as "d" + return atan2(sin(dlon) * cos_p2lat, + cos(get_as_radian<1>(p1)) * sin(get_as_radian<1>(p2)) + - sin(get_as_radian<1>(p1)) * cos_p2lat * cos(dlon)); +} + +} // namespace detail +#endif // DOXYGEN_NO_DETAIL + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_COURSE_HPP diff --git a/include/boost/geometry/algorithms/detail/disjoint/areal_areal.hpp b/include/boost/geometry/algorithms/detail/disjoint/areal_areal.hpp index 140d87daf..284858a13 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/areal_areal.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/areal_areal.hpp @@ -23,9 +23,9 @@ #include -#include +#include #include -#include +#include #include @@ -42,21 +42,21 @@ namespace detail { namespace disjoint template struct check_each_ring_for_within { - bool has_within; + bool not_disjoint; Geometry const& m_geometry; inline check_each_ring_for_within(Geometry const& g) - : has_within(false) + : not_disjoint(false) , m_geometry(g) {} template inline void apply(Range const& range) { - if ( geometry::within(geometry::return_point_on_surface(range), m_geometry) ) - { - has_within = true; - } + typename point_type::type pt; + not_disjoint = not_disjoint + || ( geometry::point_on_border(pt, range) + && geometry::covered_by(pt, m_geometry) ); } }; @@ -68,7 +68,7 @@ inline bool rings_containing(FirstGeometry const& geometry1, { check_each_ring_for_within checker(geometry1); geometry::detail::for_each_range(geometry2, checker); - return checker.has_within; + return checker.not_disjoint; } @@ -87,8 +87,8 @@ struct general_areal // If there is no intersection of segments, they might located // inside each other - // We check that using a point on the surface, and see if that is inside - // the other geometry. And vice versa. + // We check that using a point on the border (external boundary), + // and see if that is contained in the other geometry. And vice versa. if ( rings_containing(geometry1, geometry2) || rings_containing(geometry2, geometry1) ) diff --git a/include/boost/geometry/algorithms/detail/distance/backward_compatibility.hpp b/include/boost/geometry/algorithms/detail/distance/backward_compatibility.hpp index 363439d20..5b49e571d 100644 --- a/include/boost/geometry/algorithms/detail/distance/backward_compatibility.hpp +++ b/include/boost/geometry/algorithms/detail/distance/backward_compatibility.hpp @@ -20,8 +20,6 @@ #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_BACKWARD_COMPATIBILITY_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_BACKWARD_COMPATIBILITY_HPP -#include - #include #include #include @@ -35,8 +33,7 @@ #include #include -#include -#include +#include namespace boost { namespace geometry @@ -106,7 +103,10 @@ struct distance > { - static inline typename return_type::type>::type + static inline typename strategy::distance::services::return_type + < + Strategy, Point, typename point_type::type + >::type apply(Point const& point, Linestring const& linestring, Strategy const&) @@ -151,15 +151,12 @@ struct distance Strategy >::type ps_strategy_type; - std::pair - dc = detail::distance::point_to_ring + return detail::distance::point_to_ring < Point, Ring, geometry::closure::value, ps_strategy_type >::apply(point, ring, ps_strategy_type()); - - return dc.second ? return_type(0) : dc.first; } }; @@ -179,8 +176,8 @@ struct distance >::type return_type; static inline return_type apply(Point const& point, - Polygon const& polygon, - Strategy const&) + Polygon const& polygon, + Strategy const&) { typedef typename detail::distance::default_ps_strategy < @@ -189,25 +186,19 @@ struct distance Strategy >::type ps_strategy_type; - std::pair - dc = detail::distance::point_to_polygon + return detail::distance::point_to_polygon < - Point, Polygon, + Point, + Polygon, geometry::closure::value, ps_strategy_type >::apply(point, polygon, ps_strategy_type()); - - return dc.second ? return_type(0) : dc.first; } }; -namespace splitted_dispatch -{ - - template < typename Point, @@ -215,11 +206,11 @@ template typename MultiGeometryTag, typename Strategy > -struct distance_single_to_multi +struct distance < Point, MultiGeometry, Strategy, point_tag, MultiGeometryTag, - strategy_tag_distance_point_point + strategy_tag_distance_point_point, false > { typedef typename strategy::distance::services::return_type @@ -238,11 +229,11 @@ struct distance_single_to_multi Strategy >::type ps_strategy_type; - return distance_single_to_multi + return distance < Point, MultiGeometry, ps_strategy_type, point_tag, MultiGeometryTag, - strategy_tag_distance_point_segment + strategy_tag_distance_point_segment, false >::apply(point, multigeometry, ps_strategy_type()); } }; @@ -255,11 +246,11 @@ template typename GeometryTag, typename Strategy > -struct distance_single_to_multi +struct distance < Geometry, MultiPoint, Strategy, GeometryTag, multi_point_tag, - strategy_tag_distance_point_point + strategy_tag_distance_point_point, false > { typedef typename strategy::distance::services::return_type @@ -280,11 +271,11 @@ struct distance_single_to_multi Strategy >::type ps_strategy_type; - return distance_single_to_multi + return distance < Geometry, MultiPoint, ps_strategy_type, GeometryTag, multi_point_tag, - strategy_tag_distance_point_segment + strategy_tag_distance_point_segment, false >::apply(geometry, multipoint, ps_strategy_type()); } }; @@ -297,11 +288,11 @@ template typename MultiGeometryTag, typename Strategy > -struct distance_multi_to_multi +struct distance < MultiPoint, MultiGeometry, Strategy, multi_point_tag, MultiGeometryTag, - strategy_tag_distance_point_point + strategy_tag_distance_point_point, false > { typedef typename strategy::distance::services::return_type @@ -322,19 +313,16 @@ struct distance_multi_to_multi Strategy >::type ps_strategy_type; - return distance_multi_to_multi + return distance < MultiPoint, MultiGeometry, ps_strategy_type, multi_point_tag, MultiGeometryTag, - strategy_tag_distance_point_segment + strategy_tag_distance_point_segment, false >::apply(multipoint, multigeometry, ps_strategy_type()); } }; -} // namespace splitted_dispatch - - } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH diff --git a/include/boost/geometry/algorithms/detail/distance/box_to_box.hpp b/include/boost/geometry/algorithms/detail/distance/box_to_box.hpp index 57c908d38..44778e9e0 100644 --- a/include/boost/geometry/algorithms/detail/distance/box_to_box.hpp +++ b/include/boost/geometry/algorithms/detail/distance/box_to_box.hpp @@ -10,6 +10,8 @@ #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_BOX_TO_BOX_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_BOX_TO_BOX_HPP +#include + #include #include @@ -42,7 +44,7 @@ struct distance >::type apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy) { - boost::ignore_unused_variable_warning(strategy); + boost::ignore_unused(strategy); return strategy.apply(box1, box2); } }; diff --git a/include/boost/geometry/algorithms/detail/distance/default_strategies.hpp b/include/boost/geometry/algorithms/detail/distance/default_strategies.hpp index 3b79f82a3..a01ace2b5 100644 --- a/include/boost/geometry/algorithms/detail/distance/default_strategies.hpp +++ b/include/boost/geometry/algorithms/detail/distance/default_strategies.hpp @@ -95,10 +95,7 @@ struct default_strategy < point_tag, box_tag, typename point_type::type, - typename point_type::type, - cartesian_tag, - cartesian_tag, - void + typename point_type::type > {}; @@ -109,10 +106,7 @@ struct default_strategy < box_tag, box_tag, typename point_type::type, - typename point_type::type, - cartesian_tag, - cartesian_tag, - void + typename point_type::type > {}; diff --git a/include/boost/geometry/algorithms/detail/distance/geometry_to_geometry_rtree.hpp b/include/boost/geometry/algorithms/detail/distance/geometry_to_geometry_rtree.hpp deleted file mode 100644 index fc5318405..000000000 --- a/include/boost/geometry/algorithms/detail/distance/geometry_to_geometry_rtree.hpp +++ /dev/null @@ -1,395 +0,0 @@ -// 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_DETAIL_DISTANCE_GEOMETRY_TO_GEOMETRY_RTREE_HPP -#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_GEOMETRY_TO_GEOMETRY_RTREE_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_DETAIL -namespace detail { namespace distance -{ - - - -template -< - typename RTreePoint, - typename Geometry, - typename Strategy -> -class point_range_to_geometry_rtree -{ -private: - typedef typename strategy::distance::services::comparable_type - < - Strategy - >::type comparable_strategy; - - typedef typename strategy::distance::services::return_type - < - comparable_strategy, - RTreePoint, - typename point_type::type - >::type comparable_return_type; - - typedef index::rtree > r_tree; - - // functor to evaluate minimum comparable distance - struct minimum_comparable_distance_evaluator - { - r_tree const& m_r_tree; - comparable_strategy const& m_cstrategy; - bool m_first; - comparable_return_type m_min_cd; - - minimum_comparable_distance_evaluator - (r_tree const& r_tree, comparable_strategy const& cstrategy) - : m_r_tree(r_tree) - , m_cstrategy(cstrategy) - , m_first(true) - , m_min_cd() - {} - - template - inline void operator()(QueryGeometry const& query_geometry) - { - typename r_tree::value_type t_v; - std::size_t n = - m_r_tree.query(index::nearest(query_geometry, 1), &t_v); - - BOOST_ASSERT( n > 0 ); - // n above is unused outside BOOST_ASSERT, hence the call - // to boost::ignore_unused below - // - // however, t_v (initialized by the call to m_r_tree.query(...)) - // is used below, which is why we cannot put the call to - // m_r_tree.query(...) inside BOOST_ASSERT - boost::ignore_unused(n); - - comparable_return_type cd = dispatch::distance - < - typename r_tree::value_type, - QueryGeometry, - comparable_strategy - >::apply(t_v, query_geometry, m_cstrategy); - - if ( m_first || cd < m_min_cd ) - { - m_first = false; - m_min_cd = cd; - } - } - }; - - - - // class to choose between for_each_point and for_each_segment - template ::type> - struct for_each_selector - { - typedef dispatch::for_each_segment type; - }; - - template - struct for_each_selector - { - typedef dispatch::for_each_point type; - }; - -public: - typedef typename strategy::distance::services::return_type - < - Strategy, - RTreePoint, - typename point_type::type - >::type return_type; - - template - static inline return_type apply(PointIterator points_first, - PointIterator points_beyond, - Geometry const& geometry, - Strategy const& strategy) - { - BOOST_ASSERT( points_first != points_beyond ); - - if ( geometry::has_one_element(points_first, points_beyond) ) - { - return dispatch::distance - < - typename std::iterator_traits::value_type, - Geometry, - Strategy - >::apply(*points_first, geometry, strategy); - } - - // create -- packing algorithm - r_tree rt(points_first, points_beyond); - - minimum_comparable_distance_evaluator - functor(rt, - strategy::distance::services::get_comparable - < - Strategy - >::apply(strategy)); - - for_each_selector::type::apply(geometry, functor); - - return strategy::distance::services::comparable_to_regular - < - comparable_strategy, Strategy, RTreePoint, Geometry - >::apply(functor.m_min_cd); - } -}; - - - -template -< - typename Geometry1, - typename Geometry2, - typename Strategy -> -class geometry_to_geometry_rtree -{ - // the following works with linear geometries seen as ranges of points - // - // we compute the r-tree for the points of one range and then, - // compute nearest points for the segments of the other, - // ... and ... - // vice versa. - -private: - typedef typename strategy::distance::services::comparable_type - < - Strategy - >::type comparable_strategy; - - typedef typename strategy::distance::services::return_type - < - comparable_strategy, - typename point_type::type, - typename point_type::type - >::type comparable_return_type; - -public: - typedef typename strategy::distance::services::return_type - < - Strategy, - typename point_type::type, - typename point_type::type - >::type return_type; - - static inline return_type apply(Geometry1 const& geometry1, - Geometry2 const& geometry2, - Strategy const& strategy, - bool check_intersection = true) - { - typedef geometry::point_iterator const_point_iterator1; - typedef geometry::point_iterator const_point_iterator2; - - const_point_iterator1 first1 = points_begin(geometry1); - const_point_iterator1 beyond1 = points_end(geometry1); - const_point_iterator2 first2 = points_begin(geometry2); - const_point_iterator2 beyond2 = points_end(geometry2); - - if ( geometry::has_one_element(first1, beyond1) ) - { - return dispatch::distance - < - typename point_type::type, - Geometry2, - Strategy - >::apply(*first1, geometry2, strategy); - } - - if ( geometry::has_one_element(first2, beyond2) ) - { - return dispatch::distance - < - typename point_type::type, - Geometry1, - Strategy - >::apply(*first2, geometry1, strategy); - } - - if ( check_intersection && geometry::intersects(geometry1, geometry2) ) - { - return return_type(0); - } - - comparable_strategy cstrategy = - strategy::distance::services::get_comparable - < - Strategy - >::apply(strategy); - - comparable_return_type cdist1 = point_range_to_geometry_rtree - < - typename point_type::type, - Geometry2, - comparable_strategy - >::apply(first1, beyond1, geometry2, cstrategy); - - comparable_return_type cdist2 = point_range_to_geometry_rtree - < - typename point_type::type, - Geometry1, - comparable_strategy - >::apply(first2, beyond2, geometry1, cstrategy); - - - return strategy::distance::services::comparable_to_regular - < - comparable_strategy, Strategy, Geometry1, Geometry2 - >::apply( (std::min)(cdist1, cdist2) ); - } -}; - - - - -}} // namespace detail::distance -#endif // DOXYGEN_NO_DETAIL - - - - -#ifndef DOXYGEN_NO_DISPATCH -namespace dispatch -{ - - -template -struct distance - < - Linestring1, Linestring2, Strategy, - linestring_tag, linestring_tag, - strategy_tag_distance_point_segment, false - > - : detail::distance::geometry_to_geometry_rtree - < - Linestring1, Linestring2, Strategy - > -{}; - - - -template -struct distance - < - Linestring, Polygon, Strategy, - linestring_tag, polygon_tag, - strategy_tag_distance_point_segment, false - > - : detail::distance::geometry_to_geometry_rtree - < - Linestring, Polygon, Strategy - > -{}; - - - -template -struct distance - < - Linestring, Ring, Strategy, - linestring_tag, ring_tag, - strategy_tag_distance_point_segment, false - > - : detail::distance::geometry_to_geometry_rtree - < - Linestring, Ring, Strategy - > -{}; - - - -template -struct distance - < - Polygon1, Polygon2, Strategy, - polygon_tag, polygon_tag, - strategy_tag_distance_point_segment, false - > - : detail::distance::geometry_to_geometry_rtree - < - Polygon1, Polygon2, Strategy - > -{}; - - - -template -struct distance - < - Polygon, Ring, Strategy, - polygon_tag, ring_tag, - strategy_tag_distance_point_segment, false - > - : detail::distance::geometry_to_geometry_rtree - < - Polygon, Ring, Strategy - > -{}; - - - -template -struct distance - < - Ring1, Ring2, Strategy, - ring_tag, ring_tag, - strategy_tag_distance_point_segment, false - > - : detail::distance::geometry_to_geometry_rtree - < - Ring1, Ring2, Strategy - > -{}; - - - -} // namespace dispatch -#endif // DOXYGEN_NO_DISPATCH - - - -}} // namespace boost::geometry - -#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_GEOMETRY_TO_GEOMETRY_RTREE_HPP diff --git a/include/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp b/include/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp new file mode 100644 index 000000000..04d1095cb --- /dev/null +++ b/include/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp @@ -0,0 +1,462 @@ +// 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_DETAIL_DISTANCE_GEOMETRY_TO_SEGMENT_OR_BOX_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_GEOMETRY_TO_SEGMENT_OR_BOX_HPP + +#include + +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include + + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace distance +{ + + +// closure of segment or box point range +template +< + typename SegmentOrBox, + typename Tag = typename tag::type +> +struct segment_or_box_point_range_closure + : not_implemented +{}; + +template +struct segment_or_box_point_range_closure +{ + static const closure_selector value = closed; +}; + +template +struct segment_or_box_point_range_closure +{ + static const closure_selector value = open; +}; + + + +template +< + typename Geometry, + typename SegmentOrBox, + typename Strategy, + typename Tag = typename tag::type +> +class geometry_to_segment_or_box +{ +private: + typedef typename point_type::type segment_or_box_point; + + typedef typename strategy::distance::services::comparable_type + < + Strategy + >::type comparable_strategy; + + typedef detail::closest_feature::point_to_point_range + < + typename point_type::type, + std::vector, + segment_or_box_point_range_closure::value, + comparable_strategy + > point_to_point_range; + + typedef detail::closest_feature::geometry_to_range geometry_to_range; + + typedef typename strategy::distance::services::return_type + < + comparable_strategy, + typename point_type::type, + segment_or_box_point + >::type comparable_return_type; + + + // assign the new minimum value for an iterator of the point range + // of a segment or a box + template + < + typename SegOrBox, + typename SegOrBoxTag = typename tag::type + > + struct assign_new_min_iterator + : not_implemented + {}; + + template + struct assign_new_min_iterator + { + template + static inline void apply(Iterator&, Iterator) + { + } + }; + + template + struct assign_new_min_iterator + { + template + static inline void apply(Iterator& it_min, Iterator it) + { + it_min = it; + } + }; + + + // assign the points of a segment or a box to a range + template + < + typename SegOrBox, + typename PointRange, + typename SegOrBoxTag = typename tag::type + > + struct assign_segment_or_box_points + {}; + + template + struct assign_segment_or_box_points + { + static inline void apply(Segment const& segment, PointRange& range) + { + detail::assign_point_from_index<0>(segment, range[0]); + detail::assign_point_from_index<1>(segment, range[1]); + } + }; + + template + struct assign_segment_or_box_points + { + static inline void apply(Box const& box, PointRange& range) + { + detail::assign_box_corners_oriented(box, range); + } + }; + + +public: + typedef typename strategy::distance::services::return_type + < + Strategy, + typename point_type::type, + segment_or_box_point + >::type return_type; + + static inline return_type apply(Geometry const& geometry, + SegmentOrBox const& segment_or_box, + Strategy const& strategy, + bool check_intersection = true) + { + typedef geometry::point_iterator point_iterator_type; + typedef geometry::segment_iterator + < + Geometry const + > segment_iterator_type; + + typedef typename std::vector + < + segment_or_box_point + >::const_iterator seg_or_box_iterator_type; + + typedef assign_new_min_iterator assign_new_value; + + + if (check_intersection + && geometry::intersects(geometry, segment_or_box)) + { + return 0; + } + + comparable_strategy cstrategy = + strategy::distance::services::get_comparable + < + Strategy + >::apply(strategy); + + // get all points of the segment or the box + std::vector + seg_or_box_points(geometry::num_points(segment_or_box)); + + assign_segment_or_box_points + < + SegmentOrBox, + std::vector + >::apply(segment_or_box, seg_or_box_points); + + // consider all distances of the points in the geometry to the + // segment or box + comparable_return_type cd_min1; + point_iterator_type pit_min; + seg_or_box_iterator_type it_min1 = seg_or_box_points.begin(); + seg_or_box_iterator_type it_min2 = ++seg_or_box_points.begin(); + bool first = true; + + for (point_iterator_type pit = points_begin(geometry); + pit != points_end(geometry); ++pit, first = false) + { + comparable_return_type cd; + std::pair + < + seg_or_box_iterator_type, seg_or_box_iterator_type + > it_pair + = point_to_point_range::apply(*pit, + seg_or_box_points.begin(), + seg_or_box_points.end(), + cstrategy, + cd); + + if (first || cd < cd_min1) + { + cd_min1 = cd; + pit_min = pit; + assign_new_value::apply(it_min1, it_pair.first); + assign_new_value::apply(it_min2, it_pair.second); + } + } + + // consider all distances of the points in the segment or box to the + // segments of the geometry + comparable_return_type cd_min2; + segment_iterator_type sit_min; + typename std::vector::const_iterator it_min; + + first = true; + for (typename std::vector::const_iterator it + = seg_or_box_points.begin(); + it != seg_or_box_points.end(); ++it, first = false) + { + comparable_return_type cd; + segment_iterator_type sit + = geometry_to_range::apply(*it, + segments_begin(geometry), + segments_end(geometry), + cstrategy, + cd); + + if (first || cd < cd_min2) + { + cd_min2 = cd; + it_min = it; + sit_min = sit; + } + } + + if (is_comparable::value) + { + return (std::min)(cd_min1, cd_min2); + } + + if (cd_min1 < cd_min2) + { + return strategy.apply(*pit_min, *it_min1, *it_min2); + } + else + { + return dispatch::distance + < + segment_or_box_point, + typename std::iterator_traits + < + segment_iterator_type + >::value_type, + Strategy + >::apply(*it_min, *sit_min, strategy); + } + } + + + static inline return_type + apply(SegmentOrBox const& segment_or_box, Geometry const& geometry, + Strategy const& strategy, bool check_intersection = true) + { + return apply(geometry, segment_or_box, strategy, check_intersection); + } +}; + + + +template +class geometry_to_segment_or_box + < + MultiPoint, SegmentOrBox, Strategy, multi_point_tag + > +{ +private: + typedef detail::closest_feature::geometry_to_range base_type; + + typedef typename boost::range_iterator + < + MultiPoint const + >::type iterator_type; + + typedef detail::closest_feature::geometry_to_range geometry_to_range; + +public: + typedef typename strategy::distance::services::return_type + < + Strategy, + typename point_type::type, + typename point_type::type + >::type return_type; + + static inline return_type apply(MultiPoint const& multipoint, + SegmentOrBox const& segment_or_box, + Strategy const& strategy) + { + namespace sds = strategy::distance::services; + + typename sds::return_type + < + typename sds::comparable_type::type, + typename point_type::type, + typename point_type::type + >::type cd_min; + + iterator_type it_min + = geometry_to_range::apply(segment_or_box, + boost::begin(multipoint), + boost::end(multipoint), + sds::get_comparable + < + Strategy + >::apply(strategy), + cd_min); + + return + is_comparable::value + ? + cd_min + : + dispatch::distance + < + typename point_type::type, + SegmentOrBox, + Strategy + >::apply(*it_min, segment_or_box, strategy); + } +}; + + + +}} // namespace detail::distance +#endif // DOXYGEN_NO_DETAIL + + + +#ifndef DOXYGEN_NO_DISPATCH +namespace dispatch +{ + + +template +struct distance + < + Linear, Segment, Strategy, linear_tag, segment_tag, + strategy_tag_distance_point_segment, false + > : detail::distance::geometry_to_segment_or_box +{}; + + +template +struct distance + < + Areal, Segment, Strategy, areal_tag, segment_tag, + strategy_tag_distance_point_segment, false + > : detail::distance::geometry_to_segment_or_box +{}; + + +template +struct distance + < + Segment, Areal, Strategy, segment_tag, areal_tag, + strategy_tag_distance_point_segment, false + > : detail::distance::geometry_to_segment_or_box +{}; + + +template +struct distance + < + Linear, Box, Strategy, linear_tag, box_tag, + strategy_tag_distance_point_segment, false + > : detail::distance::geometry_to_segment_or_box + < + Linear, Box, Strategy + > +{}; + + +template +struct distance + < + Areal, Box, Strategy, areal_tag, box_tag, + strategy_tag_distance_point_segment, false + > : detail::distance::geometry_to_segment_or_box +{}; + + +template +struct distance + < + MultiPoint, Segment, Strategy, + multi_point_tag, segment_tag, + strategy_tag_distance_point_segment, false + > : detail::distance::geometry_to_segment_or_box + < + MultiPoint, Segment, Strategy + > +{}; + + +template +struct distance + < + MultiPoint, Box, Strategy, + multi_point_tag, box_tag, + strategy_tag_distance_point_box, false + > : detail::distance::geometry_to_segment_or_box + < + MultiPoint, Box, Strategy + > +{}; + + +} // namespace dispatch +#endif // DOXYGEN_NO_DISPATCH + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_GEOMETRY_TO_SEGMENT_OR_BOX_HPP diff --git a/include/boost/geometry/algorithms/detail/distance/implementation.hpp b/include/boost/geometry/algorithms/detail/distance/implementation.hpp index 45f40bbb3..7c009f4d7 100644 --- a/include/boost/geometry/algorithms/detail/distance/implementation.hpp +++ b/include/boost/geometry/algorithms/detail/distance/implementation.hpp @@ -22,17 +22,14 @@ // the implementation details #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include #include +#include +#include #include - #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_IMPLEMENTATION_HPP diff --git a/include/boost/geometry/algorithms/detail/distance/is_comparable.hpp b/include/boost/geometry/algorithms/detail/distance/is_comparable.hpp new file mode 100644 index 000000000..d13cc6c74 --- /dev/null +++ b/include/boost/geometry/algorithms/detail/distance/is_comparable.hpp @@ -0,0 +1,45 @@ +// 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_ALGORITHS_DETAIL_DISTANCE_IS_COMPARABLE_HPP +#define BOOST_GEOMETRY_ALGORITHS_DETAIL_DISTANCE_IS_COMPARABLE_HPP + +#include + +#include + + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace distance +{ + + +// metafunction to determine is a strategy is comparable or not +template +struct is_comparable + : boost::is_same + < + Strategy, + typename strategy::distance::services::comparable_type + < + Strategy + >::type + > +{}; + + +}} // namespace detail::distance +#endif // DOXYGEN_NO_DETAIL + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHS_DETAIL_DISTANCE_IS_COMPARABLE_HPP diff --git a/include/boost/geometry/algorithms/detail/distance/iterator_selector.hpp b/include/boost/geometry/algorithms/detail/distance/iterator_selector.hpp new file mode 100644 index 000000000..363ec465a --- /dev/null +++ b/include/boost/geometry/algorithms/detail/distance/iterator_selector.hpp @@ -0,0 +1,70 @@ +// 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_ALGORITHS_DETAIL_DISTANCE_ITERATOR_SELECTOR_HPP +#define BOOST_GEOMETRY_ALGORITHS_DETAIL_DISTANCE_ITERATOR_SELECTOR_HPP + +#include +#include + +#include +#include + + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace distance +{ + + +// class to choose between point_iterator and segment_iterator +template ::type> +struct iterator_selector +{ + typedef geometry::segment_iterator iterator_type; + + static inline iterator_type begin(Geometry& geometry) + { + return segments_begin(geometry); + } + + static inline iterator_type end(Geometry& geometry) + { + return segments_end(geometry); + } +}; + +template +struct iterator_selector +{ + typedef geometry::point_iterator iterator_type; + + static inline iterator_type begin(MultiPoint& multipoint) + { + return points_begin(multipoint); + } + + static inline iterator_type end(MultiPoint& multipoint) + { + return points_end(multipoint); + } +}; + + +}} // namespace detail::distance +#endif // DOXYGEN_NO_DETAIL + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_ALGORITHS_DETAIL_DISTANCE_ITERATOR_SELECTOR_HPP diff --git a/include/boost/geometry/algorithms/detail/distance/linear_or_areal_to_areal.hpp b/include/boost/geometry/algorithms/detail/distance/linear_or_areal_to_areal.hpp new file mode 100644 index 000000000..b63104da7 --- /dev/null +++ b/include/boost/geometry/algorithms/detail/distance/linear_or_areal_to_areal.hpp @@ -0,0 +1,147 @@ +// 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_DETAIL_DISTANCE_LINEAR_OR_AREAL_TO_AREAL_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_LINEAR_OR_AREAL_TO_AREAL_HPP + +#include + +#include + +#include + +#include + + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace distance +{ + + +template +struct linear_to_areal +{ + typedef typename strategy::distance::services::return_type + < + Strategy, + typename point_type::type, + typename point_type::type + >::type return_type; + + static inline return_type apply(Linear const& linear, + Areal const& areal, + Strategy const& strategy) + { + if ( geometry::intersects(linear, areal) ) + { + return 0; + } + + return linear_to_linear + < + Linear, Areal, Strategy + >::apply(linear, areal, strategy, false); + } + + + static inline return_type apply(Areal const& areal, + Linear const& linear, + Strategy const& strategy) + { + return apply(linear, areal, strategy); + } +}; + + +template +struct areal_to_areal +{ + typedef typename strategy::distance::services::return_type + < + Strategy, + typename point_type::type, + typename point_type::type + >::type return_type; + + static inline return_type apply(Areal1 const& areal1, + Areal2 const& areal2, + Strategy const& strategy) + { + if ( geometry::intersects(areal1, areal2) ) + { + return 0; + } + + return linear_to_linear + < + Areal1, Areal2, Strategy + >::apply(areal1, areal2, strategy, false); + } +}; + + +}} // namespace detail::distance +#endif // DOXYGEN_NO_DETAIL + + +#ifndef DOXYGEN_NO_DISPATCH +namespace dispatch +{ + +template +struct distance + < + Linear, Areal, Strategy, + linear_tag, areal_tag, + strategy_tag_distance_point_segment, false + > + : detail::distance::linear_to_areal + < + Linear, Areal, Strategy + > +{}; + + +template +struct distance + < + Areal, Linear, Strategy, + areal_tag, linear_tag, + strategy_tag_distance_point_segment, false + > + : detail::distance::linear_to_areal + < + Linear, Areal, Strategy + > +{}; + + +template +struct distance + < + Areal1, Areal2, Strategy, + areal_tag, areal_tag, + strategy_tag_distance_point_segment, false + > + : detail::distance::areal_to_areal + < + Areal1, Areal2, Strategy + > +{}; + + +} // namespace dispatch +#endif // DOXYGEN_NO_DISPATCH + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_LINEAR_OR_AREAL_TO_AREAL_HPP diff --git a/include/boost/geometry/algorithms/detail/distance/linear_to_linear.hpp b/include/boost/geometry/algorithms/detail/distance/linear_to_linear.hpp new file mode 100644 index 000000000..e44b37284 --- /dev/null +++ b/include/boost/geometry/algorithms/detail/distance/linear_to_linear.hpp @@ -0,0 +1,123 @@ +// 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_DETAIL_DISTANCE_LINEAR_TO_LINEAR_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_LINEAR_TO_LINEAR_HPP + +#include + +#include + +#include +#include + +#include +#include + +#include + +#include + + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace distance +{ + + +template +struct linear_to_linear +{ + typedef typename strategy::distance::services::return_type + < + Strategy, + typename point_type::type, + typename point_type::type + >::type return_type; + + static inline return_type apply(Linear1 const& linear1, + Linear2 const& linear2, + Strategy const& strategy, + bool = false) + { + if (geometry::num_points(linear1) == 1) + { + return dispatch::distance + < + typename point_type::type, + Linear2, + Strategy + >::apply(*points_begin(linear1), linear2, strategy); + } + + if (geometry::num_points(linear2) == 1) + { + return dispatch::distance + < + typename point_type::type, + Linear1, + Strategy + >::apply(*points_begin(linear2), linear1, strategy); + } + + if (geometry::num_segments(linear2) < geometry::num_segments(linear1)) + { + return point_or_segment_range_to_geometry_rtree + < + geometry::segment_iterator, + Linear1, + Strategy + >::apply(geometry::segments_begin(linear2), + geometry::segments_end(linear2), + linear1, + strategy); + + } + + return point_or_segment_range_to_geometry_rtree + < + geometry::segment_iterator, + Linear2, + Strategy + >::apply(geometry::segments_begin(linear1), + geometry::segments_end(linear1), + linear2, + strategy); + } +}; + + +}} // namespace detail::distance +#endif // DOXYGEN_NO_DETAIL + + +#ifndef DOXYGEN_NO_DISPATCH +namespace dispatch +{ + +template +struct distance + < + Linear1, Linear2, Strategy, + linear_tag, linear_tag, + strategy_tag_distance_point_segment, false + > : detail::distance::linear_to_linear + < + Linear1, Linear2, Strategy + > +{}; + +} // namespace dispatch +#endif // DOXYGEN_NO_DISPATCH + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_LINEAR_TO_LINEAR_HPP diff --git a/include/boost/geometry/algorithms/detail/distance/multi_to_multi.hpp b/include/boost/geometry/algorithms/detail/distance/multi_to_multi.hpp deleted file mode 100644 index 0d541cc3a..000000000 --- a/include/boost/geometry/algorithms/detail/distance/multi_to_multi.hpp +++ /dev/null @@ -1,256 +0,0 @@ -// Boost.Geometry (aka GGL, Generic Geometry Library) - -// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2008-2014 Bruno Lalande, Paris, France. -// Copyright (c) 2009-2014 Mateusz Loskot, London, UK. - -// This file was modified by Oracle on 2014. -// Modifications copyright (c) 2014, Oracle and/or its affiliates. - -// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle - -// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library -// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. - -// Use, modification and distribution is subject to the Boost Software License, -// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTI_TO_MULTI_HPP -#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTI_TO_MULTI_HPP - -#include - -#include -#include -#include - -#include -#include -#include - -#include - -#include - -#include - -#include -#include - - -namespace boost { namespace geometry -{ - -#ifndef DOXYGEN_NO_DETAIL -namespace detail { namespace distance -{ - - - -template -class distance_multi_to_multi_generic -{ -private: - typedef typename strategy::distance::services::comparable_type - < - Strategy - >::type comparable_strategy; - - typedef typename strategy::distance::services::return_type - < - comparable_strategy, - typename point_type::type, - typename point_type::type - >::type comparable_return_type; - -public: - typedef typename strategy::distance::services::return_type - < - Strategy, - typename point_type::type, - typename point_type::type - >::type return_type; - - static inline return_type apply(Multi1 const& multi1, - Multi2 const& multi2, Strategy const& strategy) - { - comparable_return_type min_cdist = comparable_return_type(); - bool first = true; - - comparable_strategy cstrategy = - strategy::distance::services::get_comparable - < - Strategy - >::apply(strategy); - - for(typename range_iterator::type it = boost::begin(multi1); - it != boost::end(multi1); - ++it, first = false) - { - comparable_return_type cdist = - dispatch::splitted_dispatch::distance_single_to_multi - < - typename range_value::type, - Multi2, - comparable_strategy, - typename tag::type>::type, - typename tag::type, - typename strategy::distance::services::tag - < - comparable_strategy - >::type - >::apply(*it, multi2, cstrategy); - if (first || cdist < min_cdist) - { - min_cdist = cdist; - if ( geometry::math::equals(min_cdist, 0) ) - { - break; - } - } - } - - return strategy::distance::services::comparable_to_regular - < - comparable_strategy, - Strategy, - Multi1, - Multi2 - >::apply(min_cdist); - } -}; - - -}} // namespace detail::distance -#endif // DOXYGEN_NO_DETAIL - - - -#ifndef DOXYGEN_NO_DISPATCH -namespace dispatch -{ - - -namespace splitted_dispatch -{ - - -template -< - typename MultiGeometry1, - typename MultiGeometry2, - typename Strategy, - typename Tag1, - typename Tag2, - typename StrategyTag -> -struct distance_multi_to_multi - : not_implemented -{}; - - - -template -< - typename MultiPoint, - typename MultiPolygon, - typename Strategy -> -struct distance_multi_to_multi - < - MultiPoint, MultiPolygon, Strategy, - multi_point_tag, multi_polygon_tag, - strategy_tag_distance_point_segment - > : detail::distance::distance_multi_to_multi_generic - < - MultiPoint, MultiPolygon, Strategy - > -{}; - - - -template -< - typename MultiLinestring1, - typename MultiLinestring2, - typename Strategy -> -struct distance_multi_to_multi - < - MultiLinestring1, MultiLinestring2, Strategy, - multi_linestring_tag, multi_linestring_tag, - strategy_tag_distance_point_segment - > : detail::distance::geometry_to_geometry_rtree - < - MultiLinestring1, MultiLinestring2, Strategy - > -{}; - - -template -< - typename MultiLinestring, - typename MultiPolygon, - typename Strategy -> -struct distance_multi_to_multi - < - MultiLinestring, MultiPolygon, Strategy, - multi_linestring_tag, multi_polygon_tag, - strategy_tag_distance_point_segment - > : detail::distance::geometry_to_geometry_rtree - < - MultiLinestring, MultiPolygon, Strategy - > -{}; - - -template -struct distance_multi_to_multi - < - MultiPolygon1, MultiPolygon2, Strategy, - multi_polygon_tag, multi_polygon_tag, - strategy_tag_distance_point_segment - > : detail::distance::geometry_to_geometry_rtree - < - MultiPolygon1, MultiPolygon2, Strategy - > -{}; - - -} // namespace splitted_dispatch - - - - -template -< - typename MultiGeometry1, - typename MultiGeometry2, - typename Strategy, - typename StrategyTag -> -struct distance - < - MultiGeometry1, MultiGeometry2, Strategy, multi_tag, multi_tag, - StrategyTag, false - > : splitted_dispatch::distance_multi_to_multi - < - MultiGeometry1, MultiGeometry2, Strategy, - typename geometry::tag::type, - typename geometry::tag::type, - StrategyTag - > -{}; - - - -} // namespace dispatch -#endif // DOXYGEN_NO_DISPATCH - - -}} // namespace boost::geometry - - -#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTI_TO_MULTI_HPP diff --git a/include/boost/geometry/algorithms/detail/distance/multipoint_to_geometry.hpp b/include/boost/geometry/algorithms/detail/distance/multipoint_to_geometry.hpp new file mode 100644 index 000000000..5f2c6e34f --- /dev/null +++ b/include/boost/geometry/algorithms/detail/distance/multipoint_to_geometry.hpp @@ -0,0 +1,240 @@ +// 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_DETAIL_DISTANCE_MULTIPOINT_TO_GEOMETRY_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTIPOINT_TO_GEOMETRY_HPP + +#include + +#include +#include + +#include +#include + +#include + +#include + +#include +#include + + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace distance +{ + + +template +struct multipoint_to_multipoint +{ + typedef typename strategy::distance::services::return_type + < + Strategy, + typename point_type::type, + typename point_type::type + >::type return_type; + + static inline return_type apply(MultiPoint1 const& multipoint1, + MultiPoint2 const& multipoint2, + Strategy const& strategy) + { + if (boost::size(multipoint2) < boost::size(multipoint1)) + + { + return point_or_segment_range_to_geometry_rtree + < + typename boost::range_iterator::type, + MultiPoint1, + Strategy + >::apply(boost::begin(multipoint2), + boost::end(multipoint2), + multipoint1, + strategy); + } + + return point_or_segment_range_to_geometry_rtree + < + typename boost::range_iterator::type, + MultiPoint2, + Strategy + >::apply(boost::begin(multipoint1), + boost::end(multipoint1), + multipoint2, + strategy); + } +}; + + +template +struct multipoint_to_linear +{ + typedef typename strategy::distance::services::return_type + < + Strategy, + typename point_type::type, + typename point_type::type + >::type return_type; + + static inline return_type apply(MultiPoint const& multipoint, + Linear const& linear, + Strategy const& strategy) + { + return detail::distance::point_or_segment_range_to_geometry_rtree + < + typename boost::range_iterator::type, + Linear, + Strategy + >::apply(boost::begin(multipoint), + boost::end(multipoint), + linear, + strategy); + } + + static inline return_type apply(Linear const& linear, + MultiPoint const& multipoint, + Strategy const& strategy) + { + return apply(multipoint, linear, strategy); + } +}; + + +template +class multipoint_to_areal +{ +private: + struct within_areal + { + within_areal(Areal const& areal) + : m_areal(areal) + {} + + template + inline bool apply(Point const& point) const + { + return geometry::within(point, m_areal); + } + + Areal const& m_areal; + }; + +public: + typedef typename strategy::distance::services::return_type + < + Strategy, + typename point_type::type, + typename point_type::type + >::type return_type; + + static inline return_type apply(MultiPoint const& multipoint, + Areal const& areal, + Strategy const& strategy) + { + within_areal predicate(areal); + + if (check_iterator_range + < + within_areal, false + >::apply(boost::begin(multipoint), + boost::end(multipoint), + predicate)) + { + return 0; + } + + return detail::distance::point_or_segment_range_to_geometry_rtree + < + typename boost::range_iterator::type, + Areal, + Strategy + >::apply(boost::begin(multipoint), + boost::end(multipoint), + areal, + strategy); + } + + static inline return_type apply(Areal const& areal, + MultiPoint const& multipoint, + Strategy const& strategy) + { + return apply(multipoint, areal, strategy); + } +}; + + +}} // namespace detail::distance +#endif // DOXYGEN_NO_DETAIL + + + +#ifndef DOXYGEN_NO_DISPATCH +namespace dispatch +{ + + +template +struct distance + < + MultiPoint1, MultiPoint2, Strategy, + multi_point_tag, multi_point_tag, + strategy_tag_distance_point_point, false + > : detail::distance::multipoint_to_multipoint + < + MultiPoint1, MultiPoint2, Strategy + > +{}; + +template +struct distance + < + MultiPoint, Linear, Strategy, multi_point_tag, linear_tag, + strategy_tag_distance_point_segment, false + > : detail::distance::multipoint_to_linear +{}; + + +template +struct distance + < + Linear, MultiPoint, Strategy, linear_tag, multi_point_tag, + strategy_tag_distance_point_segment, false + > : detail::distance::multipoint_to_linear +{}; + + +template +struct distance + < + MultiPoint, Areal, Strategy, multi_point_tag, areal_tag, + strategy_tag_distance_point_segment, false + > : detail::distance::multipoint_to_areal +{}; + + +template +struct distance + < + Areal, MultiPoint, Strategy, areal_tag, multi_point_tag, + strategy_tag_distance_point_segment, false + > : detail::distance::multipoint_to_areal +{}; + + +} // namespace dispatch +#endif // DOXYGEN_NO_DISPATCH + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTIPOINT_TO_GEOMETRY_HPP diff --git a/include/boost/geometry/algorithms/detail/distance/multipoint_to_range.hpp b/include/boost/geometry/algorithms/detail/distance/multipoint_to_range.hpp deleted file mode 100644 index 1774fab72..000000000 --- a/include/boost/geometry/algorithms/detail/distance/multipoint_to_range.hpp +++ /dev/null @@ -1,183 +0,0 @@ -// 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_DETAIL_DISTANCE_MULTIPOINT_TO_RANGE_HPP -#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTIPOINT_TO_RANGE_HPP - -#include - -#include -#include - -#include - -#include -#include -#include - -#include - -#include - - -namespace boost { namespace geometry -{ - -#ifndef DOXYGEN_NO_DETAIL -namespace detail { namespace distance -{ - -template -struct multipoint_to_multipoint -{ - typedef typename strategy::distance::services::return_type - < - Strategy, - typename point_type::type, - typename point_type::type - >::type return_type; - - static inline return_type apply(MultiPoint1 const& multipoint1, - MultiPoint2 const& multipoint2, - Strategy const& strategy) - { - if ( boost::size(multipoint1) > boost::size(multipoint2) ) - - { - return multipoint_to_multipoint - < - MultiPoint2, MultiPoint1, Strategy - >::apply(multipoint2, multipoint1, strategy); - } - - return point_range_to_geometry_rtree - < - typename point_type::type, - MultiPoint2, - Strategy - >::apply(points_begin(multipoint1), points_end(multipoint1), - multipoint2, strategy); - } -}; - - -}} // namespace detail::distance -#endif // DOXYGEN_NO_DETAIL - - - -#ifndef DOXYGEN_NO_DISPATCH -namespace dispatch -{ - - -namespace splitted_dispatch -{ - -// specializations of distance_single_to_multi for various geometry combinations - -template -struct distance_single_to_multi - < - Linestring, MultiPoint, Strategy, - linestring_tag, multi_point_tag, - strategy_tag_distance_point_segment - > -{ - typedef typename strategy::distance::services::return_type - < - Strategy, - typename point_type::type, - typename point_type::type - >::type return_type; - - static inline return_type apply(Linestring const& linestring, - MultiPoint const& multipoint, - Strategy const& strategy) - { - return detail::distance::point_range_to_geometry_rtree - < - typename point_type::type, - Linestring, - Strategy - >::apply(geometry::points_begin(multipoint), - geometry::points_end(multipoint), - linestring, strategy); - - } -}; - - - - -// specializations of distance_multi_to_multi for various geometry combinations - - -template -struct distance_multi_to_multi - < - MultiPoint1, MultiPoint2, Strategy, - multi_point_tag, multi_point_tag, - strategy_tag_distance_point_point - > : detail::distance::multipoint_to_multipoint - < - MultiPoint1, MultiPoint2, Strategy - > -{}; - - - -template -< - typename MultiPoint, - typename MultiLinestring, - typename Strategy -> -struct distance_multi_to_multi - < - MultiPoint, MultiLinestring, Strategy, - multi_point_tag, multi_linestring_tag, - strategy_tag_distance_point_segment - > -{ - typedef typename strategy::distance::services::return_type - < - Strategy, - typename point_type::type, - typename point_type::type - >::type return_type; - - static inline return_type apply(MultiPoint const& multipoint, - MultiLinestring const& multilinestring, - Strategy const& strategy) - { - return detail::distance::point_range_to_geometry_rtree - < - typename point_type::type, - MultiLinestring, - Strategy - >::apply(geometry::points_begin(multipoint), - geometry::points_end(multipoint), - multilinestring, strategy); - - } -}; - -} // namespace splitted_dispatch - - -} // namespace dispatch -#endif // DOXYGEN_NO_DISPATCH - - - -}} // namespace boost::geometry - - -#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DISTANCE_ALTERNATE_HPP diff --git a/include/boost/geometry/algorithms/detail/distance/point_to_geometry.hpp b/include/boost/geometry/algorithms/detail/distance/point_to_geometry.hpp index a46f1fe7d..ab5de3d9b 100644 --- a/include/boost/geometry/algorithms/detail/distance/point_to_geometry.hpp +++ b/include/boost/geometry/algorithms/detail/distance/point_to_geometry.hpp @@ -20,33 +20,35 @@ #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_POINT_TO_GEOMETRY_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_POINT_TO_GEOMETRY_HPP -#include +#include +#include #include +#include #include #include #include #include -#include +#include #include #include #include #include -#include - -#include #include +#include #include -#include + +#include +#include +#include +#include #include -#include - namespace boost { namespace geometry { @@ -63,7 +65,7 @@ struct point_to_point typename strategy::distance::services::return_type::type apply(P1 const& p1, P2 const& p2, Strategy const& strategy) { - boost::ignore_unused_variable_warning(strategy); + boost::ignore_unused(strategy); return strategy.apply(p1, p2); } }; @@ -84,12 +86,10 @@ private: Strategy >::type comparable_strategy; - typedef typename strategy::distance::services::return_type + typedef detail::closest_feature::point_to_point_range < - comparable_strategy, - Point, - typename boost::range_value::type - >::type comparable_return_type; + Point, Range, Closure, comparable_strategy + > point_to_point_range; public: typedef typename strategy::distance::services::return_type @@ -102,68 +102,42 @@ public: static inline return_type apply(Point const& point, Range const& range, Strategy const& strategy) { - comparable_strategy c_strategy = - strategy::distance::services::get_comparable - < - Strategy - >::apply(strategy); - - comparable_return_type const zero = comparable_return_type(0); + return_type const zero = return_type(0); if (boost::size(range) == 0) { return zero; } - typedef typename closeable_view::type view_type; + namespace sds = strategy::distance::services; - view_type view(range); - - // line of one point: return point distance - typedef typename boost::range_iterator::type iterator_type; - iterator_type it = boost::begin(view); - iterator_type prev = it++; - if (it == boost::end(view)) - { - return strategy::distance::services::comparable_to_regular - < - comparable_strategy, Strategy, Point, - typename boost::range_value::type - >::apply( c_strategy.apply(point, - *boost::begin(view), - *boost::begin(view)) ); - } - - // start with first segment distance - comparable_return_type cd = c_strategy.apply(point, *prev, *it); - - // check if other segments are closer - for (++prev, ++it; it != boost::end(view); ++prev, ++it) - { - comparable_return_type cds = c_strategy.apply(point, *prev, *it); - if (geometry::math::equals(cds, zero)) - { - return strategy::distance::services::comparable_to_regular - < - comparable_strategy, - Strategy, - Point, - typename boost::range_value::type - >::apply(zero); - } - else if (cds < cd) - { - cd = cds; - } - } - - return strategy::distance::services::comparable_to_regular + typename sds::return_type < comparable_strategy, - Strategy, Point, - typename boost::range_value::type - >::apply(cd); + typename point_type::type + >::type cd_min; + + std::pair + < + typename boost::range_iterator::type, + typename boost::range_iterator::type + > it_pair + = point_to_point_range::apply(point, + boost::begin(range), + boost::end(range), + sds::get_comparable + < + Strategy + >::apply(strategy), + cd_min); + + return + is_comparable::value + ? + cd_min + : + strategy.apply(point, *it_pair.first, *it_pair.second); } }; @@ -177,35 +151,28 @@ template > struct point_to_ring { - typedef std::pair + typedef typename strategy::distance::services::return_type < - typename strategy::distance::services::return_type - < - Strategy, Point, typename point_type::type - >::type, - bool - > distance_containment; + Strategy, Point, typename point_type::type + >::type return_type; - static inline distance_containment apply(Point const& point, - Ring const& ring, - Strategy const& strategy) + static inline return_type apply(Point const& point, + Ring const& ring, + Strategy const& strategy) { - return distance_containment - ( - point_to_range - < - Point, - Ring, - Closure, - Strategy - >::apply(point, ring, strategy), - geometry::within(point, ring) - ); + if (geometry::within(point, ring)) + { + return return_type(0); + } + + return point_to_range + < + Point, Ring, closure::value, Strategy + >::apply(point, ring, strategy); } }; - template < typename Point, @@ -215,79 +182,163 @@ template > class point_to_polygon { -private: - typedef typename strategy::distance::services::comparable_type - < - Strategy - >::type comparable_strategy; - - typedef typename strategy::distance::services::return_type - < - comparable_strategy, Point, typename point_type::type - >::type comparable_return_type; - - typedef std::pair - < - comparable_return_type, bool - > comparable_distance_containment; - public: typedef typename strategy::distance::services::return_type < Strategy, Point, typename point_type::type >::type return_type; - typedef std::pair distance_containment; - static inline distance_containment apply(Point const& point, - Polygon const& polygon, - Strategy const& strategy) +private: + typedef point_to_range + < + Point, typename ring_type::type, Closure, Strategy + > per_ring; + + struct distance_to_interior_rings { - comparable_strategy c_strategy = - strategy::distance::services::get_comparable - < - Strategy - >::apply(strategy); - - // Check distance to all rings - typedef point_to_ring - < - Point, - typename ring_type::type, - Closure, - comparable_strategy - > per_ring; - - comparable_distance_containment dc = - per_ring::apply(point, exterior_ring(polygon), c_strategy); - - typename interior_return_type::type rings - = interior_rings(polygon); - for (typename boost::range_iterator - < - typename interior_type::type const - >::type it = boost::begin(rings); - it != boost::end(rings); ++it) + template + static inline return_type apply(Point const& point, + InteriorRingIterator first, + InteriorRingIterator last, + Strategy const& strategy) { - comparable_distance_containment dcr = - per_ring::apply(point, *it, c_strategy); - if (dcr.first < dc.first) + for (InteriorRingIterator it = first; it != last; ++it) { - dc.first = dcr.first; - } - // If it was inside, and also inside inner ring, - // turn off the inside-flag, it is outside the polygon - if (dc.second && dcr.second) - { - dc.second = false; + if (geometry::within(point, *it)) + { + // the point is inside a polygon hole, so its distance + // to the polygon its distance to the polygon's + // hole boundary + return per_ring::apply(point, *it, strategy); + } } + return 0; } - return_type rd = strategy::distance::services::comparable_to_regular - < - comparable_strategy, Strategy, Point, Polygon - >::apply(dc.first); + template + static inline return_type apply(Point const& point, + InteriorRings const& interior_rings, + Strategy const& strategy) + { + return apply(point, + boost::begin(interior_rings), + boost::end(interior_rings), + strategy); + } + }; - return std::make_pair(rd, dc.second); + +public: + static inline return_type apply(Point const& point, + Polygon const& polygon, + Strategy const& strategy) + { + if (!geometry::covered_by(point, exterior_ring(polygon))) + { + // the point is outside the exterior ring, so its distance + // to the polygon is its distance to the polygon's exterior ring + return per_ring::apply(point, exterior_ring(polygon), strategy); + } + + // Check interior rings + return distance_to_interior_rings::apply(point, + interior_rings(polygon), + strategy); + } +}; + + +template +< + typename Point, + typename MultiGeometry, + typename Strategy, + bool CheckCoveredBy = boost::is_same + < + typename tag::type, multi_polygon_tag + >::value +> +class point_to_multigeometry +{ +private: + typedef detail::closest_feature::geometry_to_range geometry_to_range; + +public: + typedef typename strategy::distance::services::return_type + < + Strategy, + Point, + typename point_type::type + >::type return_type; + + static inline return_type apply(Point const& point, + MultiGeometry const& multigeometry, + Strategy const& strategy) + { + typedef iterator_selector selector_type; + + namespace sds = strategy::distance::services; + + typename sds::return_type + < + typename sds::comparable_type::type, + Point, + typename point_type::type + >::type cd; + + typename selector_type::iterator_type it_min + = geometry_to_range::apply(point, + selector_type::begin(multigeometry), + selector_type::end(multigeometry), + sds::get_comparable + < + Strategy + >::apply(strategy), + cd); + + return + is_comparable::value + ? + cd + : + dispatch::distance + < + Point, + typename std::iterator_traits + < + typename selector_type::iterator_type + >::value_type, + Strategy + >::apply(point, *it_min, strategy); + } +}; + + +// this is called only for multipolygons, hence the change in the +// template parameter name MultiGeometry to MultiPolygon +template +struct point_to_multigeometry +{ + typedef typename strategy::distance::services::return_type + < + Strategy, + Point, + typename point_type::type + >::type return_type; + + static inline return_type apply(Point const& point, + MultiPolygon const& multipolygon, + Strategy const& strategy) + { + if (geometry::covered_by(point, multipolygon)) + { + return 0; + } + + return point_to_multigeometry + < + Point, MultiPolygon, Strategy, false + >::apply(point, multipolygon, strategy); } }; @@ -307,111 +358,73 @@ namespace dispatch template struct distance < - P1, P2, Strategy, - point_tag, point_tag, strategy_tag_distance_point_point, - false - > - : detail::distance::point_to_point + P1, P2, Strategy, point_tag, point_tag, + strategy_tag_distance_point_point, false + > : detail::distance::point_to_point {}; // Point-line version 2, where point-segment strategy is specified template struct distance -< - Point, Linestring, Strategy, - point_tag, linestring_tag, strategy_tag_distance_point_segment, - false -> : detail::distance::point_to_range + < + Point, Linestring, Strategy, point_tag, linestring_tag, + strategy_tag_distance_point_segment, false + > : detail::distance::point_to_range {}; // Point-ring , where point-segment strategy is specified template struct distance -< - Point, Ring, Strategy, - point_tag, ring_tag, strategy_tag_distance_point_segment, - false -> -{ - typedef typename strategy::distance::services::return_type + < + Point, Ring, Strategy, point_tag, ring_tag, + strategy_tag_distance_point_segment, false + > : detail::distance::point_to_ring < - Strategy, Point, typename point_type::type - >::type return_type; - - static inline return_type apply(Point const& point, - Ring const& ring, - Strategy const& strategy) - { - std::pair - dc = detail::distance::point_to_ring - < - Point, Ring, - geometry::closure::value, - Strategy - >::apply(point, ring, strategy); - - return dc.second ? return_type(0) : dc.first; - } -}; + Point, Ring, closure::value, Strategy + > +{}; // Point-polygon , where point-segment strategy is specified template struct distance -< - Point, Polygon, Strategy, point_tag, polygon_tag, - strategy_tag_distance_point_segment, false -> -{ - typedef typename strategy::distance::services::return_type + < + Point, Polygon, Strategy, point_tag, polygon_tag, + strategy_tag_distance_point_segment, false + > : detail::distance::point_to_polygon < - Strategy, Point, typename point_type::type - >::type return_type; - - static inline return_type apply(Point const& point, - Polygon const& polygon, - Strategy const& strategy) - { - std::pair - dc = detail::distance::point_to_polygon - < - Point, Polygon, - geometry::closure::value, - Strategy - >::apply(point, polygon, strategy); - - return dc.second ? return_type(0) : dc.first; - } -}; + Point, Polygon, closure::value, Strategy + > +{}; // Point-segment version 2, with point-segment strategy template struct distance -< - Point, Segment, Strategy, - point_tag, segment_tag, strategy_tag_distance_point_segment, - false -> + < + Point, Segment, Strategy, point_tag, segment_tag, + strategy_tag_distance_point_segment, false + > { - static inline typename return_type::type>::type - apply(Point const& point, - Segment const& segment, - Strategy const& strategy) + static inline typename strategy::distance::services::return_type + < + Strategy, Point, typename point_type::type + >::type apply(Point const& point, + Segment const& segment, + Strategy const& strategy) { typename point_type::type p[2]; geometry::detail::assign_point_from_index<0>(segment, p[0]); geometry::detail::assign_point_from_index<1>(segment, p[1]); - boost::ignore_unused_variable_warning(strategy); + boost::ignore_unused(strategy); return strategy.apply(point, p[0], p[1]); } }; - template struct distance < @@ -425,12 +438,75 @@ struct distance >::type apply(Point const& point, Box const& box, Strategy const& strategy) { - boost::ignore_unused_variable_warning(strategy); + boost::ignore_unused(strategy); return strategy.apply(point, box); } }; +template +struct distance + < + Point, MultiPoint, Strategy, point_tag, multi_point_tag, + strategy_tag_distance_point_point, false + > : detail::distance::point_to_multigeometry + < + Point, MultiPoint, Strategy + > +{}; + + +template +struct distance + < + Point, MultiLinestring, Strategy, point_tag, multi_linestring_tag, + strategy_tag_distance_point_segment, false + > : detail::distance::point_to_multigeometry + < + Point, MultiLinestring, Strategy + > +{}; + + +template +struct distance + < + Point, MultiPolygon, Strategy, point_tag, multi_polygon_tag, + strategy_tag_distance_point_segment, false + > : detail::distance::point_to_multigeometry + < + Point, MultiPolygon, Strategy + > +{}; + + +template +struct distance + < + Point, Linear, Strategy, point_tag, linear_tag, + strategy_tag_distance_point_segment, false + > : distance + < + Point, Linear, Strategy, + point_tag, typename tag::type, + strategy_tag_distance_point_segment, false + > +{}; + + +template +struct distance + < + Point, Areal, Strategy, point_tag, areal_tag, + strategy_tag_distance_point_segment, false + > : distance + < + Point, Areal, Strategy, + point_tag, typename tag::type, + strategy_tag_distance_point_segment, false + > +{}; + } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH diff --git a/include/boost/geometry/algorithms/detail/distance/polygon_to_segment_or_box.hpp b/include/boost/geometry/algorithms/detail/distance/polygon_to_segment_or_box.hpp deleted file mode 100644 index 631cb25d3..000000000 --- a/include/boost/geometry/algorithms/detail/distance/polygon_to_segment_or_box.hpp +++ /dev/null @@ -1,160 +0,0 @@ -// 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_DETAIL_DISTANCE_POLYGON_TO_SEGMENT_OR_BOX_HPP -#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_POLYGON_TO_SEGMENT_OR_BOX_HPP - -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include - -#include - -#include -#include - - -namespace boost { namespace geometry -{ - -#ifndef DOXYGEN_NO_DETAIL -namespace detail { namespace distance -{ - - -template -class polygon_to_segment_or_box -{ -private: - typedef typename strategy::distance::services::comparable_type - < - Strategy - >::type comparable_strategy; - - typedef typename strategy::distance::services::return_type - < - comparable_strategy, - typename point_type::type, - typename point_type::type - >::type comparable_return_type; - -public: - typedef typename strategy::distance::services::return_type - < - Strategy, - typename point_type::type, - typename point_type::type - >::type return_type; - - static inline return_type apply(Polygon const& polygon, - SegmentOrBox const& segment_or_box, - Strategy const& strategy) - { - typedef typename geometry::ring_type::type e_ring; - typedef typename geometry::interior_type::type i_rings; - typedef typename range_value::type i_ring; - - if ( geometry::intersects(polygon, segment_or_box) ) - { - return 0; - } - - e_ring const& ext_ring = geometry::exterior_ring(polygon); - i_rings const& int_rings = geometry::interior_rings(polygon); - - comparable_strategy cstrategy = - strategy::distance::services::get_comparable - < - Strategy - >::apply(strategy); - - - comparable_return_type cd_min = range_to_segment_or_box - < - e_ring, SegmentOrBox, comparable_strategy - >::apply(ext_ring, segment_or_box, cstrategy, false); - - typedef typename boost::range_iterator::type iterator_type; - for (iterator_type it = boost::begin(int_rings); - it != boost::end(int_rings); ++it) - { - comparable_return_type cd = range_to_segment_or_box - < - i_ring, SegmentOrBox, comparable_strategy - >::apply(*it, segment_or_box, cstrategy, false); - - if ( cd < cd_min ) - { - cd_min = cd; - } - } - - return strategy::distance::services::comparable_to_regular - < - comparable_strategy, - Strategy, - Polygon, - SegmentOrBox - >::apply(cd_min); - } -}; - - -}} // namespace detail::distance -#endif // DOXYGEN_NO_DETAIL - - - -#ifndef DOXYGEN_NO_DETAIL -namespace dispatch -{ - - -template -struct distance - < - Polygon, Segment, Strategy, polygon_tag, segment_tag, - strategy_tag_distance_point_segment, false - > - : detail::distance::polygon_to_segment_or_box -{}; - - - -template -struct distance - < - Polygon, Box, Strategy, polygon_tag, box_tag, - strategy_tag_distance_point_segment, false - > - : detail::distance::polygon_to_segment_or_box -{}; - - - -} // namespace dispatch -#endif // DOXYGEN_NO_DETAIL - -}} // namespace boost::geometry - - -#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_POLYGON_TO_SEGMENT_OR_BOX_HPP diff --git a/include/boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp b/include/boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp new file mode 100644 index 000000000..78189794a --- /dev/null +++ b/include/boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp @@ -0,0 +1,131 @@ +// 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_DETAIL_DISTANCE_RANGE_TO_GEOMETRY_RTREE_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_RANGE_TO_GEOMETRY_RTREE_HPP + +#include +#include + +#include + +#include + +#include + +#include + +#include + +#include +#include +#include + + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace distance +{ + + +template +< + typename PointOrSegmentIterator, + typename Geometry, + typename Strategy +> +class point_or_segment_range_to_geometry_rtree +{ +private: + typedef typename std::iterator_traits + < + PointOrSegmentIterator + >::value_type point_or_segment_type; + + typedef iterator_selector selector_type; + + typedef detail::closest_feature::range_to_range_rtree range_to_range; + +public: + typedef typename strategy::distance::services::return_type + < + Strategy, + typename point_type::type, + typename point_type::type + >::type return_type; + + static inline return_type apply(PointOrSegmentIterator first, + PointOrSegmentIterator last, + Geometry const& geometry, + Strategy const& strategy) + { + namespace sds = strategy::distance::services; + + BOOST_ASSERT( first != last ); + + if ( geometry::has_one_element(first, last) ) + { + return dispatch::distance + < + point_or_segment_type, Geometry, Strategy + >::apply(*first, geometry, strategy); + } + + typename sds::return_type + < + typename sds::comparable_type::type, + typename point_type::type, + typename point_type::type + >::type cd_min; + + std::pair + < + point_or_segment_type, + typename selector_type::iterator_type + > closest_features + = range_to_range::apply(first, + last, + selector_type::begin(geometry), + selector_type::end(geometry), + sds::get_comparable + < + Strategy + >::apply(strategy), + cd_min); + + return + is_comparable::value + ? + cd_min + : + dispatch::distance + < + point_or_segment_type, + typename std::iterator_traits + < + typename selector_type::iterator_type + >::value_type, + Strategy + >::apply(closest_features.first, + *closest_features.second, + strategy); + } +}; + + +}} // namespace detail::distance +#endif // DOXYGEN_NO_DETAIL + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_RANGE_TO_GEOMETRY_RTREE_HPP diff --git a/include/boost/geometry/algorithms/detail/distance/range_to_segment_or_box.hpp b/include/boost/geometry/algorithms/detail/distance/range_to_segment_or_box.hpp deleted file mode 100644 index 8d02e1cce..000000000 --- a/include/boost/geometry/algorithms/detail/distance/range_to_segment_or_box.hpp +++ /dev/null @@ -1,333 +0,0 @@ -// 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_DETAIL_DISTANCE_RANGE_TO_SEGMENT_OR_BOX_HPP -#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_RANGE_TO_SEGMENT_OR_BOX_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_DETAIL -namespace detail { namespace distance -{ - - - -template -< - typename Range, - typename SegmentOrBox, - typename Strategy -> -class range_to_segment_or_box -{ -private: - typedef typename point_type::type segment_or_box_point; - typedef typename point_type::type range_point; - - typedef typename strategy::distance::services::comparable_type - < - Strategy - >::type comparable_strategy; - - typedef typename strategy::distance::services::return_type - < - comparable_strategy, range_point, segment_or_box_point - >::type comparable_return_type; - - typedef typename strategy::distance::services::tag - < - comparable_strategy - >::type comparable_strategy_tag; - - typedef dispatch::distance - < - segment_or_box_point, Range, comparable_strategy, - point_tag, typename tag::type, - comparable_strategy_tag, false - > comparable_point_to_range; - - // compute distance of a point to a segment or a box - template - < - typename Point, - typename SegOrBoxPoints, - typename ComparableStrategy, - typename Tag - > - struct comparable_distance_point_to_segment_or_box - {}; - - template - < - typename Point, - typename SegmentPoints, - typename ComparableStrategy - > - struct comparable_distance_point_to_segment_or_box - < - Point, SegmentPoints, ComparableStrategy, segment_tag - > - { - static inline - comparable_return_type apply(Point const& point, - SegmentPoints const& segment_points, - ComparableStrategy const& strategy) - { - boost::ignore_unused_variable_warning(strategy); - return strategy.apply(point, segment_points[0], segment_points[1]); - } - }; - - template - < - typename Point, - typename BoxPoints, - typename ComparableStrategy - > - struct comparable_distance_point_to_segment_or_box - < - Point, BoxPoints, ComparableStrategy, box_tag - > - { - static inline - comparable_return_type apply(Point const& point, - BoxPoints const& box_points, - ComparableStrategy const& strategy) - { - return point_to_range - < - Point, BoxPoints, open, ComparableStrategy - >::apply(point, box_points, strategy); - } - }; - - - // assign the points of a segment or a box to a range - template - < - typename SegOrBox, - typename PointRange, - typename Tag = typename tag::type - > - struct assign_segment_or_box_points - {}; - - - template - struct assign_segment_or_box_points - { - static inline void apply(Segment const& segment, PointRange& range) - { - detail::assign_point_from_index<0>(segment, range[0]); - detail::assign_point_from_index<1>(segment, range[1]); - } - }; - - template - struct assign_segment_or_box_points - { - static inline void apply(Box const& box, PointRange& range) - { - detail::assign_box_corners_oriented(box, range); - } - }; - - -public: - typedef typename strategy::distance::services::return_type - < - Strategy, range_point, segment_or_box_point - >::type return_type; - - static inline return_type - apply(Range const& range, SegmentOrBox const& segment_or_box, - Strategy const& strategy, bool check_intersection = true) - { - if ( check_intersection && geometry::intersects(range, segment_or_box) ) - { - return 0; - } - - comparable_strategy cstrategy = - strategy::distance::services::get_comparable - < - Strategy - >::apply(strategy); - - - // get all points of the segment or the box - std::vector - segment_or_box_points(geometry::num_points(segment_or_box)); - - assign_segment_or_box_points - < - - SegmentOrBox, - std::vector - >::apply(segment_or_box, segment_or_box_points); - - // consider all distances from each endpoint of the segment or box - // to the range - typename std::vector::const_iterator it - = segment_or_box_points.begin(); - comparable_return_type cd_min = - comparable_point_to_range::apply(*it, range, cstrategy); - - for (++it; it != segment_or_box_points.end(); ++it) - { - comparable_return_type cd = - comparable_point_to_range::apply(*it, range, cstrategy); - if ( cd < cd_min ) - { - cd_min = cd; - } - } - - // consider all distances of the points in the range to the - // segment or box - typedef typename range_iterator::type iterator_type; - for (iterator_type it = boost::begin(range); it != boost::end(range); ++it) - { - comparable_return_type cd = - comparable_distance_point_to_segment_or_box - < - typename point_type::type, - std::vector, - comparable_strategy, - typename tag::type - >::apply(*it, segment_or_box_points, cstrategy); - - if ( cd < cd_min ) - { - cd_min = cd; - } - } - - return strategy::distance::services::comparable_to_regular - < - comparable_strategy, Strategy, - range_point, segment_or_box_point - >::apply(cd_min); - } - - static inline return_type - apply(SegmentOrBox const& segment_or_box, Range const& range, - Strategy const& strategy, bool check_intersection = true) - { - return apply(range, segment_or_box, strategy, check_intersection); - } -}; - - -}} // namespace detail::distance -#endif // DOXYGEN_NO_DETAIL - - - -#ifndef DOXYGEN_NO_DISPATCH -namespace dispatch -{ - - - -template -struct distance - < - Linestring, Segment, Strategy, linestring_tag, segment_tag, - strategy_tag_distance_point_segment, false - > - : detail::distance::range_to_segment_or_box - < - Linestring, Segment, Strategy - > -{}; - - - - -template -struct distance - < - Segment, Ring, Strategy, segment_tag, ring_tag, - strategy_tag_distance_point_segment, false - > - : detail::distance::range_to_segment_or_box - < - Ring, Segment, Strategy - > -{}; - - - - -template -struct distance - < - Linestring, Box, Strategy, linestring_tag, box_tag, - strategy_tag_distance_point_segment, false - > - : detail::distance::range_to_segment_or_box - < - Linestring, Box, Strategy - > -{}; - - - - -template -struct distance - < - Ring, Box, Strategy, ring_tag, box_tag, - strategy_tag_distance_point_segment, false - > - : detail::distance::range_to_segment_or_box - < - Ring, Box, Strategy - > -{}; - - - - -} // namespace dispatch -#endif // DOXYGEN_NO_DISPATCH - - - -}} // namespace boost::geometry - - -#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_RANGE_TO_SEGMENT_OR_BOX_HPP 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 b085da513..f64a3e9fc 100644 --- a/include/boost/geometry/algorithms/detail/distance/segment_to_box.hpp +++ b/include/boost/geometry/algorithms/detail/distance/segment_to_box.hpp @@ -10,6 +10,8 @@ #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_BOX_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_BOX_HPP +#include + #include #include @@ -20,6 +22,7 @@ #include #include +#include #include #include #include @@ -28,7 +31,6 @@ #include #include -#include #include #include @@ -40,7 +42,7 @@ #include #include #include -#include +#include #include @@ -73,16 +75,19 @@ private: Strategy >::type comparable_strategy; + typedef detail::closest_feature::point_to_point_range + < + segment_point, + std::vector, + open, + comparable_strategy + > point_to_point_range; + typedef typename strategy::distance::services::return_type < comparable_strategy, segment_point, box_point >::type comparable_return_type; - typedef point_to_range - < - segment_point, std::vector, open, comparable_strategy - > point_to_box_boundary; - public: typedef typename strategy::distance::services::return_type < @@ -94,7 +99,7 @@ public: Strategy const& strategy, bool check_intersection = true) { - if ( check_intersection && geometry::intersects(segment, box) ) + if (check_intersection && geometry::intersects(segment, box)) { return 0; } @@ -104,7 +109,6 @@ public: < Strategy >::apply(strategy); - boost::ignore_unused(cstrategy); // get segment points segment_point p[2]; @@ -120,13 +124,49 @@ public: { cd[i] = cstrategy.apply(box_points[i], p[0], p[1]); } - cd[4] = point_to_box_boundary::apply(p[0], box_points, cstrategy); - cd[5] = point_to_box_boundary::apply(p[1], box_points, cstrategy); - return strategy::distance::services::comparable_to_regular + std::pair < - comparable_strategy, Strategy, Segment, Box - >::apply( *std::min_element(cd, cd + 6) ); + typename std::vector::const_iterator, + typename std::vector::const_iterator + > bit_min[2]; + + bit_min[0] = point_to_point_range::apply(p[0], + box_points.begin(), + box_points.end(), + cstrategy, + cd[4]); + bit_min[1] = point_to_point_range::apply(p[1], + box_points.begin(), + box_points.end(), + cstrategy, + cd[5]); + + unsigned int imin = 0; + for (unsigned int i = 1; i < 6; ++i) + { + if (cd[i] < cd[imin]) + { + imin = i; + } + } + + if (is_comparable::value) + { + return cd[imin]; + } + + if (imin < 4) + { + return strategy.apply(box_points[imin], p[0], p[1]); + } + else + { + unsigned int bimin = imin - 4; + return strategy.apply(p[bimin], + *bit_min[bimin].first, + *bit_min[bimin].second); + } } }; @@ -153,12 +193,14 @@ private: comparable_strategy, segment_point, box_point >::type comparable_return_type; + typedef typename detail::distance::default_strategy + < + segment_point, Box + >::type point_box_strategy; + typedef typename strategy::distance::services::comparable_type < - typename detail::distance::default_strategy - < - segment_point, Box - >::type + point_box_strategy >::type point_box_comparable_strategy; public: @@ -172,7 +214,7 @@ public: Strategy const& strategy, bool check_intersection = true) { - if ( check_intersection && geometry::intersects(segment, box) ) + if (check_intersection && geometry::intersects(segment, box)) { return 0; } @@ -204,10 +246,28 @@ public: cd[4] = pb_cstrategy.apply(p[0], box); cd[5] = pb_cstrategy.apply(p[1], box); - return strategy::distance::services::comparable_to_regular - < - comparable_strategy, Strategy, Segment, Box - >::apply( *std::min_element(cd, cd + 6) ); + unsigned int imin = 0; + for (unsigned int i = 1; i < 6; ++i) + { + if (cd[i] < cd[imin]) + { + imin = i; + } + } + + if (is_comparable::value) + { + return cd[imin]; + } + + if (imin < 4) + { + strategy.apply(box_points[imin], p[0], p[1]); + } + else + { + return point_box_strategy().apply(p[imin - 4], box); + } } }; @@ -294,19 +354,22 @@ private: LessEqual less_equal; - if ( less_equal(geometry::get<1>(top_right), geometry::get<1>(p0)) ) + if (less_equal(geometry::get<1>(top_right), geometry::get<1>(p0))) { // closest box point is the top-right corner return cast::apply(pp_strategy.apply(p0, top_right)); } - else if ( less_equal(geometry::get<1>(bottom_right), - geometry::get<1>(p0)) ) + else if (less_equal(geometry::get<1>(bottom_right), + geometry::get<1>(p0))) { // distance is realized between p0 and right-most // segment of box ReturnType diff = cast::apply(geometry::get<0>(p0)) - cast::apply(geometry::get<0>(bottom_right)); - return diff * diff; + return strategy::distance::services::result_from_distance + < + PSStrategy, BoxPoint, SegmentPoint + >::apply(ps_strategy, math::abs(diff)); } else { @@ -338,11 +401,14 @@ private: // p0 is above the upper segment of the box // (and inside its band) - if ( less_equal(geometry::get<0>(top_left), geometry::get<0>(p0)) ) + if (less_equal(geometry::get<0>(top_left), geometry::get<0>(p0))) { ReturnType diff = cast::apply(geometry::get<1>(p0)) - cast::apply(geometry::get<1>(top_left)); - return diff * diff; + return strategy::distance::services::result_from_distance + < + PSStrategy, SegmentPoint, BoxPoint + >::apply(ps_strategy, math::abs(diff)); } // p0 is to the left of the box, but p1 is above the box @@ -367,7 +433,7 @@ private: ReturnType& result) { // p0 lies to the right of the box - if ( geometry::get<0>(p0) >= geometry::get<0>(top_right) ) + if (geometry::get<0>(p0) >= geometry::get<0>(top_right)) { result = right_of_box < @@ -378,7 +444,7 @@ private: } // p1 lies to the left of the box - if ( geometry::get<0>(p1) <= geometry::get<0>(bottom_left) ) + if (geometry::get<0>(p1) <= geometry::get<0>(bottom_left)) { result = right_of_box < @@ -406,7 +472,7 @@ private: ReturnType& result) { // the segment lies below the box - if ( geometry::get<1>(p1) < geometry::get<1>(bottom_left) ) + if (geometry::get<1>(p1) < geometry::get<1>(bottom_left)) { result = above_of_box < @@ -416,7 +482,7 @@ private: } // the segment lies above the box - if ( geometry::get<1>(p0) > geometry::get<1>(top_right) ) + if (geometry::get<1>(p0) > geometry::get<1>(top_right)) { result = above_of_box < @@ -457,7 +523,7 @@ private: ReturnType t_max1 = cast::apply(geometry::get<1>(top_right1)) - cast::apply(geometry::get<1>(p0)); - if ( diff1 < 0 ) + if (diff1 < 0) { diff1 = -diff1; t_min1 = -t_min1; @@ -465,14 +531,14 @@ private: } // t_min0 > t_max1 - if ( t_min0 * diff1 > t_max1 * diff0 ) + if (t_min0 * diff1 > t_max1 * diff0) { result = cast::apply(ps_strategy.apply(corner1, p0, p1)); return true; } // t_max0 < t_min1 - if ( t_max0 * diff1 < t_min1 * diff0 ) + if (t_max0 * diff1 < t_min1 * diff0) { result = cast::apply(ps_strategy.apply(corner2, p0, p1)); return true; @@ -503,31 +569,31 @@ private: ReturnType result(0); - if ( check_right_left_of_box - < - less_equal - >::apply(p0, p1, - top_left, top_right, bottom_left, bottom_right, - pp_strategy, ps_strategy, result) ) + if (check_right_left_of_box + < + less_equal + >::apply(p0, p1, + top_left, top_right, bottom_left, bottom_right, + pp_strategy, ps_strategy, result)) { return result; } - if ( check_above_below_of_box - < - less_equal - >::apply(p0, p1, - top_left, top_right, bottom_left, bottom_right, - ps_strategy, result) ) + if (check_above_below_of_box + < + less_equal + >::apply(p0, p1, + top_left, top_right, bottom_left, bottom_right, + ps_strategy, result)) { return result; } - if ( check_generic_position::apply(p0, p1, - bottom_left, top_right, - bottom_left, top_right, - top_left, bottom_right, - ps_strategy, result) ) + if (check_generic_position::apply(p0, p1, + bottom_left, top_right, + bottom_left, top_right, + top_left, bottom_right, + ps_strategy, result)) { return result; } @@ -555,31 +621,31 @@ private: ReturnType result(0); - if ( check_right_left_of_box - < - greater_equal - >::apply(p0, p1, - bottom_left, bottom_right, top_left, top_right, - pp_strategy, ps_strategy, result) ) + if (check_right_left_of_box + < + greater_equal + >::apply(p0, p1, + bottom_left, bottom_right, top_left, top_right, + pp_strategy, ps_strategy, result)) { return result; } - if ( check_above_below_of_box - < - greater_equal - >::apply(p1, p0, - top_right, top_left, bottom_right, bottom_left, - ps_strategy, result) ) + if (check_above_below_of_box + < + greater_equal + >::apply(p1, p0, + top_right, top_left, bottom_right, bottom_left, + ps_strategy, result)) { return result; } - if ( check_generic_position::apply(p0, p1, - bottom_left, top_right, - top_right, bottom_left, - bottom_left, top_right, - ps_strategy, result) ) + if (check_generic_position::apply(p0, p1, + bottom_left, top_right, + top_right, bottom_left, + bottom_left, top_right, + ps_strategy, result)) { return result; } @@ -600,8 +666,8 @@ public: { BOOST_ASSERT( geometry::less()(p0, p1) ); - if ( geometry::get<0>(p0) < geometry::get<0>(p1) - && geometry::get<1>(p0) > geometry::get<1>(p1) ) + if (geometry::get<0>(p0) < geometry::get<0>(p1) + && geometry::get<1>(p0) > geometry::get<1>(p1)) { return negative_slope_segment(p0, p1, top_left, top_right, @@ -675,7 +741,7 @@ public: detail::assign_point_from_index<0>(segment, p[0]); detail::assign_point_from_index<1>(segment, p[1]); - if ( geometry::equals(p[0], p[1]) ) + if (geometry::equals(p[0], p[1])) { typedef typename boost::mpl::if_ < @@ -709,53 +775,34 @@ public: detail::assign_box_corners(box, bottom_left, bottom_right, top_left, top_right); - pp_comparable_strategy c_pp_strategy = - strategy::distance::services::get_comparable - < - PPStrategy - >::apply(pp_strategy); - - ps_comparable_strategy c_ps_strategy = - strategy::distance::services::get_comparable - < - PSStrategy - >::apply(ps_strategy); - - comparable_return_type cd; - - if ( geometry::less()(p[0], p[1]) ) + if (geometry::less()(p[0], p[1])) { - cd = segment_to_box_2D + return segment_to_box_2D < return_type, segment_point, box_point, - pp_comparable_strategy, - ps_comparable_strategy + PPStrategy, + PSStrategy >::apply(p[0], p[1], top_left, top_right, bottom_left, bottom_right, - c_pp_strategy, - c_ps_strategy); + pp_strategy, + ps_strategy); } else { - cd = segment_to_box_2D + return segment_to_box_2D < return_type, segment_point, box_point, - pp_comparable_strategy, - ps_comparable_strategy + PPStrategy, + PSStrategy >::apply(p[1], p[0], top_left, top_right, bottom_left, bottom_right, - c_pp_strategy, - c_ps_strategy); + pp_strategy, + ps_strategy); } - - return strategy::distance::services::comparable_to_regular - < - ps_comparable_strategy, PSStrategy, Segment, Box - >::apply( cd ); } }; @@ -790,12 +837,32 @@ struct distance { assert_dimension_equal(); - typedef typename detail::distance::default_strategy + typedef typename boost::mpl::if_ < - typename point_type::type, - typename point_type::type + boost::is_same + < + typename strategy::distance::services::comparable_type + < + Strategy + >::type, + Strategy + >, + typename strategy::distance::services::comparable_type + < + typename detail::distance::default_strategy + < + typename point_type::type, + typename point_type::type + >::type + >::type, + typename detail::distance::default_strategy + < + typename point_type::type, + typename point_type::type + >::type >::type pp_strategy_type; + return detail::distance::segment_to_box < Segment, diff --git a/include/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp b/include/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp index 1ae22153c..2dcde6494 100644 --- a/include/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp +++ b/include/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp @@ -11,17 +11,21 @@ #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_SEGMENT_HPP #include +#include + +#include #include #include #include #include -#include #include #include +#include + #include @@ -64,7 +68,7 @@ public: apply(Segment1 const& segment1, Segment2 const& segment2, Strategy const& strategy) { - if ( geometry::intersects(segment1, segment2) ) + if (geometry::intersects(segment1, segment2)) { return 0; } @@ -89,10 +93,25 @@ public: d[2] = cstrategy.apply(p[0], q[0], q[1]); d[3] = cstrategy.apply(p[1], q[0], q[1]); - return strategy::distance::services::comparable_to_regular - < - comparable_strategy, Strategy, Segment1, Segment2 - >::apply( *std::min_element(d, d + 4) ); + std::size_t imin = std::distance(boost::addressof(d[0]), + std::min_element(d, d + 4)); + + if (is_comparable::value) + { + return d[imin]; + } + + switch (imin) + { + case 0: + return strategy.apply(q[0], p[0], p[1]); + case 1: + return strategy.apply(q[1], p[0], p[1]); + case 2: + return strategy.apply(p[0], q[0], q[1]); + default: + return strategy.apply(p[1], q[0], q[1]); + } } }; diff --git a/include/boost/geometry/algorithms/detail/distance/single_to_multi.hpp b/include/boost/geometry/algorithms/detail/distance/single_to_multi.hpp deleted file mode 100644 index 59cf17230..000000000 --- a/include/boost/geometry/algorithms/detail/distance/single_to_multi.hpp +++ /dev/null @@ -1,526 +0,0 @@ -// Boost.Geometry (aka GGL, Generic Geometry Library) - -// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2008-2014 Bruno Lalande, Paris, France. -// Copyright (c) 2009-2014 Mateusz Loskot, London, UK. - -// This file was modified by Oracle on 2014. -// Modifications copyright (c) 2014, Oracle and/or its affiliates. - -// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle - -// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library -// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. - -// Use, modification and distribution is subject to the Boost Software License, -// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SINGLE_TO_MULTI_HPP -#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SINGLE_TO_MULTI_HPP - -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include - -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include - - -namespace boost { namespace geometry -{ - -#ifndef DOXYGEN_NO_DETAIL -namespace detail { namespace distance -{ - - -template -class distance_single_to_multi_generic -{ -private: - typedef typename strategy::distance::services::comparable_type - < - Strategy - >::type comparable_strategy; - - typedef typename strategy::distance::services::return_type - < - comparable_strategy, - typename point_type::type, - typename point_type::type - >::type comparable_return_type; - -public: - typedef typename strategy::distance::services::return_type - < - Strategy, - typename point_type::type, - typename point_type::type - >::type return_type; - - static inline return_type apply(Geometry const& geometry, - MultiGeometry const& multi, - Strategy const& strategy) - { - comparable_return_type min_cdist = comparable_return_type(); - bool first = true; - - comparable_strategy cstrategy = - strategy::distance::services::get_comparable - < - Strategy - >::apply(strategy); - - for (typename range_iterator::type it = boost::begin(multi); - it != boost::end(multi); - ++it, first = false) - { - comparable_return_type cdist = dispatch::distance - < - Geometry, - typename range_value::type, - comparable_strategy - >::apply(geometry, *it, cstrategy); - - if (first || cdist < min_cdist) - { - min_cdist = cdist; - if ( geometry::math::equals(min_cdist, 0) ) - { - break; - } - } - } - - return strategy::distance::services::comparable_to_regular - < - comparable_strategy, Strategy, Geometry, MultiGeometry - >::apply(min_cdist); - } -}; - - - -template -struct distance_multi_to_single_generic -{ - typedef typename strategy::distance::services::return_type - < - Strategy, - typename point_type::type, - typename point_type::type - >::type return_type; - - static inline return_type apply(MultiGeometry const& multi, - Geometry const& geometry, - Strategy const& strategy) - { - return distance_single_to_multi_generic - < - Geometry, MultiGeometry, Strategy - >::apply(geometry, multi, strategy); - } -}; - - - - -}} // namespace detail::distance -#endif // DOXYGEN_NO_DETAIL - - - -#ifndef DOXYGEN_NO_DISPATCH -namespace dispatch -{ - - -namespace splitted_dispatch -{ - - -template -< - typename Geometry, - typename MultiGeometry, - typename Strategy, - typename GeometryTag, - typename MultiGeometryTag, - typename StrategyTag -> -struct distance_single_to_multi - : not_implemented -{}; - - - -template -struct distance_single_to_multi - < - Point, MultiPoint, Strategy, - point_tag, multi_point_tag, - strategy_tag_distance_point_point - > : detail::distance::distance_single_to_multi_generic - < - Point, MultiPoint, Strategy - > -{}; - - - -template -struct distance_single_to_multi - < - Point, MultiLinestring, Strategy, - point_tag, multi_linestring_tag, - strategy_tag_distance_point_segment - > : detail::distance::distance_single_to_multi_generic - < - Point, MultiLinestring, Strategy - > -{}; - - - -template -struct distance_single_to_multi - < - Point, MultiPolygon, Strategy, - point_tag, multi_polygon_tag, - strategy_tag_distance_point_segment - > : detail::distance::distance_single_to_multi_generic - < - Point, MultiPolygon, Strategy - > -{}; - - - -template -struct distance_single_to_multi - < - Linestring, MultiLinestring, Strategy, - linestring_tag, multi_linestring_tag, - strategy_tag_distance_point_segment - > : detail::distance::geometry_to_geometry_rtree - < - Linestring, MultiLinestring, Strategy - > -{}; - - - -template -struct distance_single_to_multi - < - Linestring, MultiPolygon, Strategy, - linestring_tag, multi_polygon_tag, - strategy_tag_distance_point_segment - > : detail::distance::geometry_to_geometry_rtree - < - Linestring, MultiPolygon, Strategy - > -{}; - - - -template -struct distance_single_to_multi - < - Polygon, MultiPoint, Strategy, - polygon_tag, multi_point_tag, - strategy_tag_distance_point_segment - > : detail::distance::distance_single_to_multi_generic - < - Polygon, MultiPoint, Strategy - > -{}; - - - -template -struct distance_single_to_multi - < - Polygon, MultiLinestring, Strategy, - polygon_tag, multi_linestring_tag, - strategy_tag_distance_point_segment - > : detail::distance::geometry_to_geometry_rtree - < - Polygon, MultiLinestring, Strategy - > -{}; - - - -template -struct distance_single_to_multi - < - Polygon, MultiPolygon, Strategy, - polygon_tag, multi_polygon_tag, - strategy_tag_distance_point_segment - > : detail::distance::geometry_to_geometry_rtree - < - Polygon, MultiPolygon, Strategy - > -{}; - - - -template -struct distance_single_to_multi - < - MultiLinestring, Ring, Strategy, - multi_linestring_tag, ring_tag, - strategy_tag_distance_point_segment - > : detail::distance::geometry_to_geometry_rtree - < - MultiLinestring, Ring, Strategy - > -{}; - - -template -struct distance_single_to_multi - < - MultiPolygon, Ring, Strategy, - multi_polygon_tag, ring_tag, - strategy_tag_distance_point_segment - > : detail::distance::geometry_to_geometry_rtree - < - MultiPolygon, Ring, Strategy - > -{}; - - - -template -< - typename MultiGeometry, - typename Geometry, - typename Strategy, - typename MultiGeometryTag, - typename GeometryTag, - typename StrategyTag -> -struct distance_multi_to_single - : not_implemented -{}; - - - -template -< - typename MultiPoint, - typename Segment, - typename Strategy -> -struct distance_multi_to_single - < - MultiPoint, Segment, Strategy, - multi_point_tag, segment_tag, - strategy_tag_distance_point_segment - > : detail::distance::distance_multi_to_single_generic - < - MultiPoint, Segment, Strategy - > -{}; - - - -template -< - typename MultiPoint, - typename Ring, - typename Strategy -> -struct distance_multi_to_single - < - MultiPoint, Ring, Strategy, - multi_point_tag, ring_tag, - strategy_tag_distance_point_segment - > : detail::distance::distance_multi_to_single_generic - < - MultiPoint, Ring, Strategy - > -{}; - - - -template -< - typename MultiPoint, - typename Box, - typename Strategy -> -struct distance_multi_to_single - < - MultiPoint, Box, Strategy, - multi_point_tag, box_tag, - strategy_tag_distance_point_box - > : detail::distance::distance_multi_to_single_generic - < - MultiPoint, Box, Strategy - > -{}; - - -template -struct distance_multi_to_single - < - MultiLinestring, Segment, Strategy, - multi_linestring_tag, segment_tag, - strategy_tag_distance_point_segment - > : detail::distance::distance_multi_to_single_generic - < - MultiLinestring, Segment, Strategy - > -{}; - - -template -struct distance_multi_to_single - < - MultiLinestring, Ring, Strategy, - multi_linestring_tag, ring_tag, - strategy_tag_distance_point_segment - > : detail::distance::geometry_to_geometry_rtree - < - MultiLinestring, Ring, Strategy - > -{}; - - -template -struct distance_multi_to_single - < - MultiLinestring, Box, Strategy, - multi_linestring_tag, box_tag, - strategy_tag_distance_point_segment - > : detail::distance::distance_multi_to_single_generic - < - MultiLinestring, Box, Strategy - > -{}; - - - -template -struct distance_multi_to_single - < - MultiPolygon, Segment, Strategy, - multi_polygon_tag, segment_tag, - strategy_tag_distance_point_segment - > : detail::distance::distance_multi_to_single_generic - < - MultiPolygon, Segment, Strategy - > -{}; - - -template -struct distance_multi_to_single - < - MultiPolygon, Ring, Strategy, - multi_polygon_tag, ring_tag, - strategy_tag_distance_point_segment - > : detail::distance::geometry_to_geometry_rtree - < - MultiPolygon, Ring, Strategy - > -{}; - - -template -struct distance_multi_to_single - < - MultiPolygon, Box, Strategy, - multi_polygon_tag, box_tag, - strategy_tag_distance_point_segment - > : detail::distance::distance_multi_to_single_generic - < - MultiPolygon, Box, Strategy - > -{}; - - -} // namespace splitted_dispatch - - -template -< - typename Geometry, - typename MultiGeometry, - typename Strategy, - typename GeometryTag, - typename StrategyTag -> -struct distance - < - Geometry, MultiGeometry, Strategy, GeometryTag, multi_tag, - StrategyTag, false - > : splitted_dispatch::distance_single_to_multi - < - Geometry, MultiGeometry, Strategy, - GeometryTag, typename tag::type, - StrategyTag - > -{}; - - - -template -< - typename MultiGeometry, - typename Geometry, - typename Strategy, - typename GeometryTag, - typename StrategyTag -> -struct distance - < - MultiGeometry, Geometry, Strategy, multi_tag, GeometryTag, - StrategyTag, false - > : splitted_dispatch::distance_multi_to_single - < - MultiGeometry, Geometry, Strategy, - typename tag::type, GeometryTag, - StrategyTag - > -{}; - - - -} // namespace dispatch -#endif // DOXYGEN_NO_DISPATCH - - -}} // namespace boost::geometry - - -#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SINGLE_TO_MULTI_HPP diff --git a/include/boost/geometry/algorithms/detail/relate/turns.hpp b/include/boost/geometry/algorithms/detail/relate/turns.hpp index cef9b81ef..a2e56a888 100644 --- a/include/boost/geometry/algorithms/detail/relate/turns.hpp +++ b/include/boost/geometry/algorithms/detail/relate/turns.hpp @@ -228,7 +228,7 @@ struct less template static inline bool use_fraction(Turn const& left, Turn const& right) { - static const LessOp less_op; + static LessOp less_op; return left.operations[OpId].fraction < right.operations[OpId].fraction || ( left.operations[OpId].fraction == right.operations[OpId].fraction diff --git a/include/boost/geometry/algorithms/detail/sub_range.hpp b/include/boost/geometry/algorithms/detail/sub_range.hpp index 5c5b2f9c0..a68f31362 100644 --- a/include/boost/geometry/algorithms/detail/sub_range.hpp +++ b/include/boost/geometry/algorithms/detail/sub_range.hpp @@ -103,7 +103,7 @@ typename sub_range_return_type::type sub_range(Geometry & geometry, Id const& id) { return detail_dispatch::sub_range::apply(geometry, id); -}; +} } // namespace detail #endif // DOXYGEN_NO_DETAIL diff --git a/include/boost/geometry/algorithms/detail/throw_on_empty_input.hpp b/include/boost/geometry/algorithms/detail/throw_on_empty_input.hpp index 3d83e6930..21f5fe40b 100644 --- a/include/boost/geometry/algorithms/detail/throw_on_empty_input.hpp +++ b/include/boost/geometry/algorithms/detail/throw_on_empty_input.hpp @@ -24,6 +24,10 @@ // So decided that at least for Boost 1.49 this is commented for // scalar results, except distance. +#if defined(BOOST_GEOMETRY_EMPTY_INPUT_NO_THROW) +#include +#endif + namespace boost { namespace geometry { @@ -39,6 +43,8 @@ inline void throw_on_empty_input(Geometry const& geometry) { throw empty_input_exception(); } +#else + boost::ignore_unused(geometry); #endif } diff --git a/include/boost/geometry/algorithms/dispatch/distance.hpp b/include/boost/geometry/algorithms/dispatch/distance.hpp index 58fd59340..cae3ebd0c 100644 --- a/include/boost/geometry/algorithms/dispatch/distance.hpp +++ b/include/boost/geometry/algorithms/dispatch/distance.hpp @@ -22,7 +22,9 @@ #include +#include #include +#include #include #include @@ -36,16 +38,33 @@ namespace dispatch { -using strategy::distance::services::return_type; - - template < typename Geometry1, typename Geometry2, - typename Strategy = typename detail::distance::default_strategy::type, - typename Tag1 = typename tag_cast::type, multi_tag>::type, - typename Tag2 = typename tag_cast::type, multi_tag>::type, - typename StrategyTag = typename strategy::distance::services::tag::type, + typename Strategy = typename detail::distance::default_strategy + < + Geometry1, Geometry2 + >::type, + typename Tag1 = typename tag_cast + < + typename tag::type, + segment_tag, + box_tag, + linear_tag, + areal_tag + >::type, + typename Tag2 = typename tag_cast + < + typename tag::type, + segment_tag, + box_tag, + linear_tag, + areal_tag + >::type, + typename StrategyTag = typename strategy::distance::services::tag + < + Strategy + >::type, bool Reverse = reverse_dispatch::type::value > struct distance: not_implemented @@ -53,8 +72,6 @@ struct distance: not_implemented - - } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH diff --git a/include/boost/geometry/algorithms/simplify.hpp b/include/boost/geometry/algorithms/simplify.hpp index 101b1324e..00b6ed6f9 100644 --- a/include/boost/geometry/algorithms/simplify.hpp +++ b/include/boost/geometry/algorithms/simplify.hpp @@ -16,6 +16,7 @@ #include +#include #include #include #include @@ -52,6 +53,8 @@ struct simplify_range_insert static inline void apply(Range const& range, OutputIterator out, Distance const& max_distance, Strategy const& strategy) { + boost::ignore_unused(strategy); + if (boost::size(range) <= 2 || max_distance < 0) { std::copy(boost::begin(range), boost::end(range), out); diff --git a/include/boost/geometry/core/cs.hpp b/include/boost/geometry/core/cs.hpp index cf6c56b53..301fb6b76 100644 --- a/include/boost/geometry/core/cs.hpp +++ b/include/boost/geometry/core/cs.hpp @@ -1,8 +1,13 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. -// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2014 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2014 Mateusz Loskot, London, UK. + +// This file was modified by Oracle on 2014. +// Modifications copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -16,7 +21,8 @@ #include -#include +#include +#include #include #include @@ -45,6 +51,35 @@ struct degree {}; struct radian {}; +#ifndef DOXYGEN_NO_DETAIL +namespace core_detail +{ + +template +struct coordinate_system_units +{ + BOOST_MPL_ASSERT_MSG + ((false), + COORDINATE_SYSTEM_UNITS_MUST_BE_DEGREES_OR_RADIANS, + (types)); +}; + +template <> +struct coordinate_system_units +{ + typedef geometry::degree units; +}; + +template <> +struct coordinate_system_units +{ + typedef geometry::radian units; +}; + +} // namespace core_detail +#endif // DOXYGEN_NO_DETAIL + + namespace cs { @@ -73,7 +108,10 @@ known as lat,long or lo,la or phi,lambda template struct geographic { - typedef DegreeOrRadian units; + typedef typename core_detail::coordinate_system_units + < + DegreeOrRadian + >::units units; }; @@ -99,7 +137,10 @@ struct geographic template struct spherical { - typedef DegreeOrRadian units; + typedef typename core_detail::coordinate_system_units + < + DegreeOrRadian + >::units units; }; @@ -116,7 +157,10 @@ struct spherical template struct spherical_equatorial { - typedef DegreeOrRadian units; + typedef typename core_detail::coordinate_system_units + < + DegreeOrRadian + >::units units; }; @@ -131,7 +175,10 @@ struct spherical_equatorial template struct polar { - typedef DegreeOrRadian units; + typedef typename core_detail::coordinate_system_units + < + DegreeOrRadian + >::units units; }; diff --git a/include/boost/geometry/extensions/nsphere/algorithms/num_points.hpp b/include/boost/geometry/extensions/nsphere/algorithms/num_points.hpp index 177f63ba4..e89714bb6 100644 --- a/include/boost/geometry/extensions/nsphere/algorithms/num_points.hpp +++ b/include/boost/geometry/extensions/nsphere/algorithms/num_points.hpp @@ -29,9 +29,9 @@ namespace dispatch { -template -struct num_points - : detail::num_points::other_count<1> +template +struct num_points + : detail::counting::other_count<1> {}; diff --git a/include/boost/geometry/extensions/nsphere/index/detail/rtree/rstar/redistribute_elements.hpp b/include/boost/geometry/extensions/nsphere/index/detail/rtree/rstar/redistribute_elements.hpp index 1deda1ada..01d6d3847 100644 --- a/include/boost/geometry/extensions/nsphere/index/detail/rtree/rstar/redistribute_elements.hpp +++ b/include/boost/geometry/extensions/nsphere/index/detail/rtree/rstar/redistribute_elements.hpp @@ -61,9 +61,9 @@ private: Translator const& m_tr; }; -template -struct choose_split_axis_and_index_for_axis - : choose_split_axis_and_index_for_axis +template +struct choose_split_axis_and_index_for_axis + : choose_split_axis_and_index_for_axis {}; diff --git a/include/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp b/include/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp index 825ef8061..1616369da 100644 --- a/include/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp +++ b/include/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp @@ -150,7 +150,7 @@ public : } } - void resize(std::size_t new_size) + void resize(std::size_t /*new_size*/) { if (m_do_hole) { diff --git a/include/boost/geometry/geometries/concepts/point_concept.hpp b/include/boost/geometry/geometries/concepts/point_concept.hpp index 1e1b31e61..db4977112 100644 --- a/include/boost/geometry/geometries/concepts/point_concept.hpp +++ b/include/boost/geometry/geometries/concepts/point_concept.hpp @@ -1,8 +1,13 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // -// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. -// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// Copyright (c) 2008-2014 Bruno Lalande, Paris, France. +// Copyright (c) 2008-2014 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2009-2014 Mateusz Loskot, London, UK. + +// This file was modified by Oracle on 2014. +// Modifications copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -17,6 +22,7 @@ #include #include +#include #include #include @@ -24,7 +30,6 @@ - namespace boost { namespace geometry { namespace concept { @@ -46,6 +51,9 @@ The point concept is defined as following: with two functions: - \b get to get a coordinate value - \b set to set a coordinate value (this one is not checked for ConstPoint) +- for non-Cartesian coordinate systems, the coordinate system's units + must either be boost::geometry::degree or boost::geometry::radian + \par Example: @@ -90,8 +98,12 @@ class Point typedef typename coordinate_type::type ctype; typedef typename coordinate_system::type csystem; - enum { ccount = dimension::value }; + // The following enum is used to fully instantiate the coordinate + // system class; this is needed in order to check the units passed + // to it for non-Cartesian coordinate systems. + enum { cs_check = sizeof(csystem) }; + enum { ccount = dimension::value }; template struct dimension_checker @@ -139,8 +151,12 @@ class ConstPoint typedef typename coordinate_type::type ctype; typedef typename coordinate_system::type csystem; - enum { ccount = dimension::value }; + // The following enum is used to fully instantiate the coordinate + // system class; this is needed in order to check the units passed + // to it for non-Cartesian coordinate systems. + enum { cs_check = sizeof(csystem) }; + enum { ccount = dimension::value }; template struct dimension_checker @@ -149,7 +165,7 @@ class ConstPoint { const P* p = 0; ctype coord(geometry::get(*p)); - boost::ignore_unused_variable_warning(coord); + boost::ignore_unused(coord); dimension_checker::apply(); } }; diff --git a/include/boost/geometry/geometries/point.hpp b/include/boost/geometry/geometries/point.hpp index a25340c46..8e9675739 100644 --- a/include/boost/geometry/geometries/point.hpp +++ b/include/boost/geometry/geometries/point.hpp @@ -1,8 +1,13 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. -// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2014 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2014 Mateusz Loskot, London, UK. + +// This file was modified by Oracle on 2014. +// Modifications copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -64,6 +69,12 @@ template > class point { +private: + // The following enum is used to fully instantiate the + // CoordinateSystem class and check the correctness of the units + // passed for non-Cartesian coordinate systems. + enum { cs_check = sizeof(CoordinateSystem) }; + public: /// @brief Default constructor, no initialization diff --git a/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp b/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp index b5ba1cf91..05a64c7b7 100644 --- a/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp +++ b/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp @@ -299,7 +299,7 @@ inline void pick_seeds(Elements const& elements, separation_type separation = 0; impl::apply(elements, parameters, tr, separation, seed1, seed2); -}; +} } // namespace linear diff --git a/include/boost/geometry/iterators/concatenate_iterator.hpp b/include/boost/geometry/iterators/concatenate_iterator.hpp index 20112b4c4..759c07d65 100644 --- a/include/boost/geometry/iterators/concatenate_iterator.hpp +++ b/include/boost/geometry/iterators/concatenate_iterator.hpp @@ -96,13 +96,13 @@ public: typename OtherValue, typename OtherReference > - concatenate_iterator operator=(concatenate_iterator - < - OtherIt1, - OtherIt2, - OtherValue, - OtherReference - > const& other) + concatenate_iterator & operator=(concatenate_iterator + < + OtherIt1, + OtherIt2, + OtherValue, + OtherReference + > const& other) { static const bool are_conv = boost::is_convertible::value diff --git a/include/boost/geometry/iterators/detail/segment_iterator/range_segment_iterator.hpp b/include/boost/geometry/iterators/detail/segment_iterator/range_segment_iterator.hpp index d79fda84d..c0270d9d0 100644 --- a/include/boost/geometry/iterators/detail/segment_iterator/range_segment_iterator.hpp +++ b/include/boost/geometry/iterators/detail/segment_iterator/range_segment_iterator.hpp @@ -149,12 +149,12 @@ public: typename OtherValue, typename OtherReference > - range_segment_iterator operator=(range_segment_iterator - < - OtherRange, - OtherValue, - OtherReference - > const& other) + range_segment_iterator & operator=(range_segment_iterator + < + OtherRange, + OtherValue, + OtherReference + > const& other) { typedef typename range_segment_iterator < diff --git a/include/boost/geometry/iterators/flatten_iterator.hpp b/include/boost/geometry/iterators/flatten_iterator.hpp index 078079dc2..b91499f32 100644 --- a/include/boost/geometry/iterators/flatten_iterator.hpp +++ b/include/boost/geometry/iterators/flatten_iterator.hpp @@ -72,6 +72,16 @@ public: : m_outer_it(outer_end), m_outer_end(outer_end) {} + flatten_iterator & operator=(flatten_iterator const& other) + { + m_outer_it = other.m_outer_it; + m_outer_end = other.m_outer_end; + // avoid assigning an iterator having singular value + if ( other.m_outer_it != other.m_outer_end ) + m_inner_it = other.m_inner_it; + return *this; + } + template < typename OtherOuterIterator, typename OtherInnerIterator, @@ -116,15 +126,15 @@ public: typename OtherAccessInnerEnd, typename OtherReference > - flatten_iterator operator=(flatten_iterator - < - OtherOuterIterator, - OtherInnerIterator, - OtherValue, - OtherAccessInnerBegin, - OtherAccessInnerEnd, - OtherReference - > const& other) + flatten_iterator & operator=(flatten_iterator + < + OtherOuterIterator, + OtherInnerIterator, + OtherValue, + OtherAccessInnerBegin, + OtherAccessInnerEnd, + OtherReference + > const& other) { static const bool are_conv = boost::is_convertible @@ -142,7 +152,9 @@ public: m_outer_it = other.m_outer_it; m_outer_end = other.m_outer_end; - m_inner_it = other.m_inner_it; + // avoid assigning an iterator having singular value + if ( other.m_outer_it != other.m_outer_end ) + m_inner_it = other.m_inner_it; return *this; } diff --git a/include/boost/geometry/iterators/point_iterator.hpp b/include/boost/geometry/iterators/point_iterator.hpp index 075339aa5..2517a648f 100644 --- a/include/boost/geometry/iterators/point_iterator.hpp +++ b/include/boost/geometry/iterators/point_iterator.hpp @@ -289,6 +289,32 @@ public: NOT_CONVERTIBLE, (point_iterator)); } + + inline point_iterator& operator++() // prefix + { + base::operator++(); + return *this; + } + + inline point_iterator& operator--() // prefix + { + base::operator--(); + return *this; + } + + inline point_iterator operator++(int) // postfix + { + point_iterator copy(*this); + base::operator++(); + return copy; + } + + inline point_iterator operator--(int) // postfix + { + point_iterator copy(*this); + base::operator--(); + return copy; + } }; diff --git a/include/boost/geometry/iterators/segment_iterator.hpp b/include/boost/geometry/iterators/segment_iterator.hpp index 206d7fc50..71aff39c4 100644 --- a/include/boost/geometry/iterators/segment_iterator.hpp +++ b/include/boost/geometry/iterators/segment_iterator.hpp @@ -272,6 +272,16 @@ private: inline segment_iterator(base const& base_it) : base(base_it) {} public: + // The following typedef is needed for this iterator to be + // bidirectional. + // Normally we would not have to define this. However, due to the + // fact that the value type of the iterator is not a reference, + // the iterator_facade framework (used to define the base class of + // this iterator) degrades automatically the iterator's category + // to input iterator. With the following typedef we recover the + // correct iterator category. + typedef std::bidirectional_iterator_tag iterator_category; + inline segment_iterator() {} template @@ -291,6 +301,32 @@ public: NOT_CONVERTIBLE, (segment_iterator)); } + + inline segment_iterator& operator++() // prefix + { + base::operator++(); + return *this; + } + + inline segment_iterator& operator--() // prefix + { + base::operator--(); + return *this; + } + + inline segment_iterator operator++(int) // postfix + { + segment_iterator copy(*this); + base::operator++(); + return copy; + } + + inline segment_iterator operator--(int) // postfix + { + segment_iterator copy(*this); + base::operator--(); + return copy; + } }; diff --git a/include/boost/geometry/strategies/agnostic/buffer_distance_asymmetric.hpp b/include/boost/geometry/strategies/agnostic/buffer_distance_asymmetric.hpp index c03a1a1d8..446d2f02c 100644 --- a/include/boost/geometry/strategies/agnostic/buffer_distance_asymmetric.hpp +++ b/include/boost/geometry/strategies/agnostic/buffer_distance_asymmetric.hpp @@ -9,6 +9,8 @@ #ifndef BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_BUFFER_DISTANCE_ASYMMETRIC_HPP #define BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_BUFFER_DISTANCE_ASYMMETRIC_HPP +#include + #include #include @@ -62,10 +64,10 @@ public : return negative() ? math::abs(result) : result; } - //! Returns 1 (used internally) + //! Used internally, returns -1 for deflate, 1 for inflate inline int factor() const { - return m_left < 0 ? -1 : 1; + return negative() ? -1 : 1; } //! Returns true if both distances are negative @@ -79,6 +81,8 @@ public : inline NumericType max_distance(JoinStrategy const& join_strategy, EndStrategy const& end_strategy) const { + boost::ignore_unused(join_strategy, end_strategy); + NumericType const left = geometry::math::abs(m_left); NumericType const right = geometry::math::abs(m_right); NumericType const dist = (std::max)(left, right); diff --git a/include/boost/geometry/strategies/agnostic/buffer_distance_symmetric.hpp b/include/boost/geometry/strategies/agnostic/buffer_distance_symmetric.hpp index a8815173b..bc0c46f64 100644 --- a/include/boost/geometry/strategies/agnostic/buffer_distance_symmetric.hpp +++ b/include/boost/geometry/strategies/agnostic/buffer_distance_symmetric.hpp @@ -56,13 +56,13 @@ public : inline NumericType apply(Point const& , Point const& , buffer_side_selector ) const { - return m_distance; + return negative() ? geometry::math::abs(m_distance) : m_distance; } - //! Returns 1 (used internally) + //! Used internally, returns -1 for deflate, 1 for inflate inline int factor() const { - return 1; + return negative() ? -1 : 1; } //! Returns true if distance is negative diff --git a/include/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp b/include/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp index ce3142d89..a960a6f1f 100644 --- a/include/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp +++ b/include/boost/geometry/strategies/agnostic/hull_graham_andrew.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 + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -282,17 +287,17 @@ public: template inline void result(partitions const& state, - OutputIterator out, bool clockwise) const + OutputIterator out, + bool clockwise, + bool closed) const { if (clockwise) { - output_range(state.m_upper_hull, out, false); - output_range(state.m_lower_hull, out, true); + output_ranges(state.m_upper_hull, state.m_lower_hull, out, closed); } else { - output_range(state.m_lower_hull, out, false); - output_range(state.m_upper_hull, out, true); + output_ranges(state.m_lower_hull, state.m_upper_hull, out, closed); } } @@ -343,28 +348,28 @@ private: } - template - static inline void output_range(container_type const& range, - OutputIterator out, bool skip_first) + template + static inline void output_ranges(container_type const& first, container_type const& second, + OutputIterator out, bool closed) { - typedef typename reversible_view::type view_type; - view_type view(range); - bool first = true; - for (typename boost::range_iterator::type it = boost::begin(view); - it != boost::end(view); ++it) + std::copy(boost::begin(first), boost::end(first), out); + + BOOST_ASSERT(closed ? !boost::empty(second) : boost::size(second) > 1); + std::copy(++boost::rbegin(second), // skip the first Point + closed ? boost::rend(second) : --boost::rend(second), // skip the last Point if open + out); + + typedef typename boost::range_size::type size_type; + size_type const count = boost::size(first) + boost::size(second) - 1; + // count describes a closed case but comparison with min size of closed + // gives the result compatible also with open + // here core_detail::closure::minimum_ring_size could be used + if ( count < 4 ) { - if (first && skip_first) - { - first = false; - } - else - { - *out = *it; - ++out; - } + // there should be only one missing + *out++ = *boost::begin(first); } } - }; }} // namespace strategy::convex_hull diff --git a/include/boost/geometry/strategies/cartesian/buffer_join_round.hpp b/include/boost/geometry/strategies/cartesian/buffer_join_round.hpp index 9e467c85a..f88b2904b 100644 --- a/include/boost/geometry/strategies/cartesian/buffer_join_round.hpp +++ b/include/boost/geometry/strategies/cartesian/buffer_join_round.hpp @@ -69,34 +69,30 @@ private : DistanceType const& buffer_distance, RangeOut& range_out) const { - PromotedType dx1 = get<0>(perp1) - get<0>(vertex); - PromotedType dy1 = get<1>(perp1) - get<1>(vertex); - PromotedType dx2 = get<0>(perp2) - get<0>(vertex); - PromotedType dy2 = get<1>(perp2) - get<1>(vertex); + PromotedType const dx1 = get<0>(perp1) - get<0>(vertex); + PromotedType const dy1 = get<1>(perp1) - get<1>(vertex); + PromotedType const dx2 = get<0>(perp2) - get<0>(vertex); + PromotedType const dy2 = get<1>(perp2) - get<1>(vertex); - BOOST_ASSERT(buffer_distance != 0); - - dx1 /= buffer_distance; - dy1 /= buffer_distance; - dx2 /= buffer_distance; - dy2 /= buffer_distance; - - PromotedType angle_diff = acos(dx1 * dx2 + dy1 * dy2); - - PromotedType two = 2.0; - PromotedType steps = m_points_per_circle; - int n = boost::numeric_cast(steps * angle_diff - / (two * geometry::math::pi())); - - if (n <= 1) - { - return; - } + PromotedType const two = 2.0; + PromotedType const two_pi = two * geometry::math::pi(); PromotedType const angle1 = atan2(dy1, dx1); - PromotedType diff = angle_diff / PromotedType(n); - PromotedType a = angle1 - diff; + PromotedType angle2 = atan2(dy2, dx2); + while (angle2 > angle1) + { + angle2 -= two_pi; + } + // Divide the angle into an integer amount of steps to make it + // visually correct also for a low number of points / circle + int const n = static_cast + ( + m_points_per_circle * (angle1 - angle2) / two_pi + ); + + PromotedType const diff = (angle1 - angle2) / static_cast(n); + PromotedType a = angle1 - diff; for (int i = 0; i < n - 1; i++, a -= diff) { Point p; diff --git a/include/boost/geometry/strategies/cartesian/buffer_side_straight.hpp b/include/boost/geometry/strategies/cartesian/buffer_side_straight.hpp index b5d28e257..24655ab3d 100644 --- a/include/boost/geometry/strategies/cartesian/buffer_side_straight.hpp +++ b/include/boost/geometry/strategies/cartesian/buffer_side_straight.hpp @@ -9,8 +9,6 @@ #include -#include - #include #include #include @@ -69,14 +67,19 @@ public : // Generate a block along (left or right of) the segment // Simulate a vector d (dx,dy) - coordinate_type dx = get<0>(input_p2) - get<0>(input_p1); - coordinate_type dy = get<1>(input_p2) - get<1>(input_p1); + coordinate_type const dx = get<0>(input_p2) - get<0>(input_p1); + coordinate_type const dy = get<1>(input_p2) - get<1>(input_p1); // For normalization [0,1] (=dot product d.d, sqrt) promoted_type const length = geometry::math::sqrt(dx * dx + dy * dy); - // Because coordinates are not equal, length should not be zero - BOOST_ASSERT((! geometry::math::equals(length, 0))); + if (geometry::math::equals(length, 0)) + { + // Coordinates are simplified and therefore most often not equal. + // But if simplify is skipped, or for lines with two + // equal points, length is 0 and we cannot generate output. + return; + } // Generate the normalized perpendicular p, to the left (ccw) promoted_type const px = -dy / length; diff --git a/include/boost/geometry/strategies/cartesian/distance_comparable_to_regular.hpp b/include/boost/geometry/strategies/cartesian/distance_comparable_to_regular.hpp deleted file mode 100644 index cf432ee82..000000000 --- a/include/boost/geometry/strategies/cartesian/distance_comparable_to_regular.hpp +++ /dev/null @@ -1,107 +0,0 @@ -// 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_STRATEGIES_CARTESIAN_DISTANCE_COMPARABLE_TO_REGULAR_HPP -#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_COMPARABLE_TO_REGULAR_HPP - - -#include -#include -#include -#include - -namespace boost { namespace geometry -{ - -namespace strategy { namespace distance -{ - - - -#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS -namespace services -{ - - -template -< - typename ComparableStrategy, - typename Strategy, - typename Geometry1, - typename Geometry2 -> -struct comparable_to_regular - < - ComparableStrategy, Strategy, - Geometry1, Geometry2, - cartesian_tag, cartesian_tag - > -{ - typedef typename return_type - < - Strategy, - typename point_type::type, - typename point_type::type - >::type calculation_type; - - typedef typename return_type - < - ComparableStrategy, - typename point_type::type, - typename point_type::type - >::type comparable_calculation_type; - - static inline calculation_type apply(comparable_calculation_type const& cd) - { - return math::sqrt( boost::numeric_cast(cd) ); - } -}; - - - -template -struct comparable_to_regular - < - ComparableStrategy, - ComparableStrategy, - Geometry1, - Geometry2, - cartesian_tag, - cartesian_tag - > -{ - typedef typename return_type - < - ComparableStrategy, - typename point_type::type, - typename point_type::type - >::type comparable_calculation_type; - - static inline comparable_calculation_type - apply(comparable_calculation_type const& cd) - { - return cd; - } -}; - - - - - - - -} // namespace services -#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS - - -}} // namespace strategy::distance - -}} // namespace boost::geometry - -#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_COMPARABLE_TO_REGULAR_HPP diff --git a/include/boost/geometry/strategies/concepts/convex_hull_concept.hpp b/include/boost/geometry/strategies/concepts/convex_hull_concept.hpp index 80c21423e..d6e42e95a 100644 --- a/include/boost/geometry/strategies/concepts/convex_hull_concept.hpp +++ b/include/boost/geometry/strategies/concepts/convex_hull_concept.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. @@ -56,7 +61,7 @@ class ConvexHullStrategy str->apply(*sp, *st); // 5) must implement a method result, with an output iterator - str->result(*st, std::back_inserter(*v), true); + str->result(*st, std::back_inserter(*v), true, true); } }; diff --git a/include/boost/geometry/strategies/distance_comparable_to_regular.hpp b/include/boost/geometry/strategies/distance_comparable_to_regular.hpp deleted file mode 100644 index 88f51eb15..000000000 --- a/include/boost/geometry/strategies/distance_comparable_to_regular.hpp +++ /dev/null @@ -1,53 +0,0 @@ -// 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_STRATEGIES_DISTANCE_COMPARABLE_TO_REGULAR_HPP -#define BOOST_GEOMETRY_STRATEGIES_DISTANCE_COMPARABLE_TO_REGULAR_HPP - -#include -#include -#include - - -namespace boost { namespace geometry -{ - -namespace strategy { namespace distance -{ - - - -#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS -namespace services -{ - - -template -< - typename ComparableStrategy, - typename Strategy, - typename Geometry1, - typename Geometry2, - typename CsTag1 = typename cs_tag::type, - typename CsTag2 = typename cs_tag::type -> -struct comparable_to_regular - : geometry::not_implemented -{}; - - -} // namespace services -#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS - - -}} // namespace strategy::distance - -}} // namespace boost::geometry - -#endif // BOOST_GEOMETRY_STRATEGIES_DISTANCE_COMPARABLE_TO_REGULAR_HPP diff --git a/include/boost/geometry/strategies/intersection_result.hpp b/include/boost/geometry/strategies/intersection_result.hpp index 695db79c9..b467b92a7 100644 --- a/include/boost/geometry/strategies/intersection_result.hpp +++ b/include/boost/geometry/strategies/intersection_result.hpp @@ -90,7 +90,7 @@ struct de9im static inline char as_char(int v) { - return v >= 0 && v < 10 ? ('0' + char(v)) : '-'; + return v >= 0 && v < 10 ? static_cast('0' + v) : '-'; } #if defined(HAVE_MATRIX_AS_STRING) diff --git a/include/boost/geometry/strategies/spherical/distance_cross_track.hpp b/include/boost/geometry/strategies/spherical/distance_cross_track.hpp index 6ffa4ff7c..a40f03dba 100644 --- a/include/boost/geometry/strategies/spherical/distance_cross_track.hpp +++ b/include/boost/geometry/strategies/spherical/distance_cross_track.hpp @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -117,10 +118,10 @@ public : return_type d2 = m_strategy.apply(sp2, p); - return_type crs_AD = course(sp1, p); - return_type crs_AB = course(sp1, sp2); + return_type crs_AD = geometry::detail::course(sp1, p); + return_type crs_AB = geometry::detail::course(sp1, sp2); return_type crs_BA = crs_AB - geometry::math::pi(); - return_type crs_BD = course(sp2, p); + return_type crs_BD = geometry::detail::course(sp2, p); return_type d_crs1 = crs_AD - crs_AB; return_type d_crs2 = crs_BD - crs_BA; @@ -165,24 +166,6 @@ public : private : Strategy m_strategy; - - /// Calculate course (bearing) between two points. Might be moved to a "course formula" ... - template - inline typename return_type::type - course(Point1 const& p1, Point2 const& p2) const - { - typedef typename return_type::type return_type; - - // http://williams.best.vwh.net/avform.htm#Crs - return_type dlon = get_as_radian<0>(p2) - get_as_radian<0>(p1); - return_type cos_p2lat = cos(get_as_radian<1>(p2)); - - // "An alternative formula, not requiring the pre-computation of d" - return atan2(sin(dlon) * cos_p2lat, - cos(get_as_radian<1>(p1)) * sin(get_as_radian<1>(p2)) - - sin(get_as_radian<1>(p1)) * cos_p2lat * cos(dlon)); - } - }; diff --git a/include/boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp b/include/boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp new file mode 100644 index 000000000..fe32f7723 --- /dev/null +++ b/include/boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp @@ -0,0 +1,287 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2008-2014 Bruno Lalande, Paris, France. +// Copyright (c) 2008-2014 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2009-2014 Mateusz Loskot, London, UK. + +// This file was modified by Oracle on 2014. +// Modifications copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_POINT_BOX_HPP +#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_POINT_BOX_HPP + + +#include + +#include + +#include +#include + + + +namespace boost { namespace geometry +{ + +namespace strategy { namespace distance +{ + +template +< + typename CalculationType = void, + typename Strategy = haversine +> +class cross_track_point_box +{ +public: + template + struct return_type + : promote_floating_point + < + typename select_calculation_type + < + Point, + typename point_type::type, + CalculationType + >::type + > + {}; + + inline cross_track_point_box() + {} + + explicit inline cross_track_point_box(typename Strategy::radius_type const& r) + : m_pp_strategy(r) + {} + + inline cross_track_point_box(Strategy const& s) + : m_pp_strategy(s) + {} + + template + inline typename return_type::type + apply(Point const& point, Box const& box) const + { + +#if !defined(BOOST_MSVC) + BOOST_CONCEPT_ASSERT + ( + (concept::PointDistanceStrategy + < + Strategy, Point, + typename point_type::type + >) + ); +#endif + + typedef typename return_type::type return_type; + typedef typename point_type::type box_point_t; + + // Create (counterclockwise) array of points, the fifth one closes it + // If every point is on the LEFT side (=1) or ON the border (=0) + // the distance should be equal to 0. + + // TODO: This strategy as well as other cross-track strategies + // and therefore e.g. spherical within(Point, Box) may not work + // properly for a Box degenerated to a Segment or Point + + boost::array bp; + geometry::detail::assign_box_corners_oriented(box, bp); + bp[4] = bp[0]; + + for (int i = 1; i < 5; i++) + { + box_point_t const& p1 = bp[i - 1]; + box_point_t const& p2 = bp[i]; + + return_type const crs_AD = geometry::detail::course(p1, point); + return_type const crs_AB = geometry::detail::course(p1, p2); + return_type const d_crs1 = crs_AD - crs_AB; + return_type const sin_d_crs1 = sin(d_crs1); + + // this constant sin() is here to be consistent with the side strategy + return_type const sigXTD = asin(sin(0.001) * sin_d_crs1); + + // If the point is on the right side of the edge + if ( sigXTD > 0 ) + { + return_type const crs_BA = crs_AB - geometry::math::pi(); + return_type const crs_BD = geometry::detail::course(p2, point); + return_type const d_crs2 = crs_BD - crs_BA; + + return_type const projection1 = cos( d_crs1 ); + return_type const projection2 = cos( d_crs2 ); + + if(projection1 > 0.0 && projection2 > 0.0) + { + return_type const d1 = m_pp_strategy.apply(p1, point); + return_type const + XTD = radius() + * geometry::math::abs( + asin( sin( d1 / radius() ) * sin_d_crs1 ) + ); + + return return_type(XTD); + } + else + { + // OPTIMIZATION + // Return d1 if projection1 <= 0 and d2 if projection2 <= 0 + // if both == 0 then return d1 or d2 + // both shouldn't be < 0 + + return_type const d1 = m_pp_strategy.apply(p1, point); + return_type const d2 = m_pp_strategy.apply(p2, point); + + return return_type((std::min)( d1 , d2 )); + } + } + } + + // Return 0 if the point isn't on the right side of any segment + return return_type(0); + } + + inline typename Strategy::radius_type radius() const + { return m_pp_strategy.radius(); } + +private : + + Strategy m_pp_strategy; +}; + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS +namespace services +{ + +template +struct tag > +{ + typedef strategy_tag_distance_point_box type; +}; + + +template +struct return_type, P, Box> + : cross_track_point_box::template return_type +{}; + + +template +struct comparable_type > +{ + // There is no shortcut, so the strategy itself is its comparable type + typedef cross_track_point_box type; +}; + + +template +< + typename CalculationType, + typename Strategy +> +struct get_comparable > +{ + typedef typename comparable_type + < + cross_track_point_box + >::type comparable_type; +public : + static inline comparable_type apply( + cross_track_point_box const& strategy) + { + return cross_track_point_box(strategy.radius()); + } +}; + + +template +< + typename CalculationType, + typename Strategy, + typename P, typename Box +> +struct result_from_distance + < + cross_track_point_box, + P, + Box + > +{ +private : + typedef typename cross_track_point_box + < + CalculationType, Strategy + >::template return_type return_type; +public : + template + static inline return_type apply( + cross_track_point_box const& , + T const& distance) + { + return distance; + } +}; + + +template +struct default_strategy + < + point_tag, box_tag, Point, Box, + spherical_equatorial_tag, spherical_equatorial_tag, + Strategy + > +{ + typedef cross_track_point_box + < + void, + typename boost::mpl::if_ + < + boost::is_void, + typename default_strategy + < + point_tag, point_tag, + Point, typename point_type::type, + spherical_equatorial_tag, spherical_equatorial_tag + >::type, + Strategy + >::type + > type; +}; + + +template +struct default_strategy + < + box_tag, point_tag, Box, Point, + spherical_equatorial_tag, spherical_equatorial_tag, + Strategy + > +{ + typedef typename default_strategy + < + point_tag, box_tag, Point, Box, + spherical_equatorial_tag, spherical_equatorial_tag, + Strategy + >::type type; +}; + + +} // namespace services +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::distance + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_POINT_BOX_HPP diff --git a/include/boost/geometry/strategies/spherical/side_by_cross_track.hpp b/include/boost/geometry/strategies/spherical/side_by_cross_track.hpp index 818bd4c34..c4c5f24ee 100644 --- a/include/boost/geometry/strategies/spherical/side_by_cross_track.hpp +++ b/include/boost/geometry/strategies/spherical/side_by_cross_track.hpp @@ -17,6 +17,8 @@ #include #include +#include + #include #include @@ -31,29 +33,6 @@ namespace boost { namespace geometry namespace strategy { namespace side { -#ifndef DOXYGEN_NO_DETAIL -namespace detail -{ - -/// Calculate course (bearing) between two points. Might be moved to a "course formula" ... -template -static inline double course(Point const& p1, Point const& p2) -{ - // http://williams.best.vwh.net/avform.htm#Crs - double dlon = get_as_radian<0>(p2) - get_as_radian<0>(p1); - double cos_p2lat = cos(get_as_radian<1>(p2)); - - // "An alternative formula, not requiring the pre-computation of d" - return atan2(sin(dlon) * cos_p2lat, - cos(get_as_radian<1>(p1)) * sin(get_as_radian<1>(p2)) - - sin(get_as_radian<1>(p1)) * cos_p2lat * cos(dlon)); -} - -} -#endif // DOXYGEN_NO_DETAIL - - - /*! \brief Check at which side of a Great Circle segment a point lies left of segment (> 0), right of segment (< 0), on segment (0) @@ -86,8 +65,8 @@ public : boost::ignore_unused(); double d1 = 0.001; // m_strategy.apply(sp1, p); - double crs_AD = detail::course(p1, p); - double crs_AB = detail::course(p1, p2); + double crs_AD = geometry::detail::course(p1, p); + double crs_AB = geometry::detail::course(p1, p2); double XTD = asin(sin(d1) * sin(crs_AD - crs_AB)); return math::equals(XTD, 0) ? 0 : XTD < 0 ? 1 : -1; diff --git a/include/boost/geometry/strategies/strategies.hpp b/include/boost/geometry/strategies/strategies.hpp index 5e70e8a02..afc5d7046 100644 --- a/include/boost/geometry/strategies/strategies.hpp +++ b/include/boost/geometry/strategies/strategies.hpp @@ -55,11 +55,11 @@ #include #include #include -#include #include #include #include +#include #include #include diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index d91542951..0f1d36035 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -29,4 +29,3 @@ build-project policies ; build-project io ; build-project util ; build-project views ; -build-project multi ; diff --git a/test/algorithms/Jamfile.v2 b/test/algorithms/Jamfile.v2 index 79b3d4ca9..9cd6dc4d0 100644 --- a/test/algorithms/Jamfile.v2 +++ b/test/algorithms/Jamfile.v2 @@ -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 # # Use, modification and distribution is subject to the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -24,66 +25,45 @@ test-suite boost-geometry-algorithms [ run convex_hull.cpp : : : msvc:/bigobj ] [ run correct.cpp : : : msvc:/bigobj ] [ run convert.cpp : : : msvc:/bigobj ] - [ run covered_by.cpp ] - [ run crosses.cpp : : : msvc:/bigobj ] - [ run difference.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE msvc:/bigobj ] - [ run difference_linear_linear.cpp ] - [ run difference_pl_pl.cpp ] - [ run disjoint.cpp : : : msvc:/bigobj ] - [ run disjoint_coverage.cpp : : : msvc:/bigobj ] - [ run distance.cpp : : : msvc:/bigobj ] - [ 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 ] - [ run distance_pointlike_pointlike.cpp ] [ run envelope.cpp : : : msvc:/bigobj ] - [ run equals.cpp : : : msvc:/bigobj ] [ run expand.cpp ] [ run for_each.cpp ] - [ run intersection.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE msvc:/bigobj ] - [ run intersection_linear_linear.cpp ] - [ run intersection_pl_pl.cpp ] - [ run intersects.cpp : : : msvc:/bigobj ] [ run is_simple.cpp : : : msvc:/bigobj ] [ run is_valid.cpp : : : msvc:/bigobj ] [ run length.cpp ] [ run make.cpp ] + [ run multi_area.cpp ] + [ run multi_centroid.cpp ] + [ run multi_convert.cpp ] + [ run multi_convex_hull.cpp ] + [ run multi_correct.cpp ] + [ run multi_envelope.cpp ] + [ run multi_for_each.cpp ] + [ run multi_length.cpp ] + [ run multi_num_geometries.cpp ] + [ run multi_num_interior_rings.cpp ] + [ run multi_num_points.cpp ] + [ run multi_perimeter.cpp ] + [ run multi_reverse.cpp ] + [ run multi_simplify.cpp ] + [ run multi_transform.cpp ] + [ run multi_unique.cpp ] [ run num_geometries.cpp ] [ run num_interior_rings.cpp ] [ run num_points.cpp ] [ run num_segments.cpp ] - [ run overlaps.cpp : : : msvc:/bigobj ] [ run perimeter.cpp ] [ run point_on_surface.cpp ] - [ run relate_areal_areal.cpp : : : msvc:/bigobj ] - [ run relate_linear_areal.cpp : : : msvc:/bigobj ] - [ run relate_linear_linear.cpp : : : msvc:/bigobj ] - [ run relate_pointlike_xxx.cpp : : : msvc:/bigobj ] [ run remove_spikes.cpp ] [ run reverse.cpp ] [ run simplify.cpp ] - [ run sym_difference_linear_linear.cpp ] - [ run touches.cpp : : : msvc:/bigobj ] [ run transform.cpp ] - [ run union.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE msvc:/bigobj ] - [ run union_linear_linear.cpp ] - [ run union_pl_pl.cpp ] [ run unique.cpp ] - [ run within.cpp : : : msvc:/bigobj ] - [ run within_areal_areal.cpp : : : msvc:/bigobj ] - [ run within_linear_areal.cpp : : : msvc:/bigobj ] - [ run within_linear_linear.cpp : : : msvc:/bigobj ] - [ run within_pointlike_xxx.cpp : : : msvc:/bigobj ] ; -build-project overlay - ; - -build-project buffer - ; - -build-project detail - ; - +build-project buffer ; +build-project detail ; +build-project distance ; +build-project overlay ; +build-project relational_operations ; +build-project set_operations ; diff --git a/test/algorithms/buffer/linestring_buffer.cpp b/test/algorithms/buffer/linestring_buffer.cpp index bdca6e3d0..078ca3f21 100644 --- a/test/algorithms/buffer/linestring_buffer.cpp +++ b/test/algorithms/buffer/linestring_buffer.cpp @@ -27,6 +27,12 @@ static std::string const overlapping = "LINESTRING(0 0,4 5,7 4,10 6, 10 2,2 2)"; static std::string const curve = "LINESTRING(2 7,3 5,5 4,7 5,8 7)"; static std::string const tripod = "LINESTRING(5 0,5 5,1 8,5 5,9 8)"; // with spike +static std::string const degenerate0 = "LINESTRING()"; +static std::string const degenerate1 = "LINESTRING(5 5)"; +static std::string const degenerate2 = "LINESTRING(5 5,5 5)"; +static std::string const degenerate3 = "LINESTRING(5 5,5 5,5 5)"; +static std::string const degenerate4 = "LINESTRING(5 5,5 5,4 4,5 5,5 5)"; + static std::string const for_collinear = "LINESTRING(2 0,0 0,0 4,6 4,6 0,4 0)"; static std::string const for_collinear2 = "LINESTRING(2 1,2 0,0 0,0 4,6 4,6 0,4 0,4 1)"; @@ -42,11 +48,11 @@ static std::string const aimes171 = "LINESTRING(-2.393161 52.265087,-2.393002 52 static std::string const aimes181 = "LINESTRING(-2.320686 52.43505,-2.320678 52.435016,-2.320697 52.434978,-2.3207 52.434977,-2.320741 52.434964,-2.320807 52.434964,-2.320847 52.434986,-2.320903 52.435022)"; -template +template void test_all() { typedef bg::model::linestring

linestring; - typedef bg::model::polygon

polygon; + typedef bg::model::polygon polygon; bg::strategy::buffer::join_miter join_miter; bg::strategy::buffer::join_round join_round(100); @@ -133,6 +139,13 @@ void test_all() test_one("field_sprayer1", field_sprayer1, join_round, end_round, 718.761877, 16.5, 6.5); test_one("field_sprayer1", field_sprayer1, join_miter, end_round, 718.939628, 16.5, 6.5); + test_one("degenerate0", degenerate0, join_round, end_round, 0.0, 3.0); + test_one("degenerate1", degenerate1, join_round, end_round, 28.25, 3.0); + test_one("degenerate2", degenerate2, join_round, end_round, 28.2503, 3.0); + test_one("degenerate3", degenerate3, join_round, end_round, 28.2503, 3.0); + test_one("degenerate4", degenerate4, join_round, end_round, 36.7410, 3.0); + test_one("degenerate4", degenerate4, join_round, end_flat, 8.4853, 3.0); + double tolerance = 1.0e-10; test_one("aimes120", aimes120, join_miter, end_flat, 1.62669948622351512e-08, 0.000018, 0.000018, false, tolerance); @@ -165,7 +178,8 @@ void test_all() int test_main(int, char* []) { - test_all >(); + test_all >(); + test_all >(); //test_all >(); return 0; } diff --git a/test/algorithms/buffer/multi_linestring_buffer.cpp b/test/algorithms/buffer/multi_linestring_buffer.cpp index 6174e3c8e..c36a3a2e4 100644 --- a/test/algorithms/buffer/multi_linestring_buffer.cpp +++ b/test/algorithms/buffer/multi_linestring_buffer.cpp @@ -15,13 +15,19 @@ static std::string const simplex = "MULTILINESTRING((0 0,4 5),(5 4,10 0))"; static std::string const two_bends = "MULTILINESTRING((0 0,4 5,7 4,10 6),(1 5,5 9,8 6))"; static std::string const turn_inside = "MULTILINESTRING((0 0,4 5,7 4,10 6),(1 5,5 9,8 6),(0 4,-2 6))"; +static std::string const degenerate0 = "MULTILINESTRING()"; +static std::string const degenerate1 = "MULTILINESTRING((5 5))"; +static std::string const degenerate2 = "MULTILINESTRING((5 5),(9 9))"; +static std::string const degenerate3 = "MULTILINESTRING((5 5),(9 9),(4 10))"; +static std::string const degenerate4 = "MULTILINESTRING((5 5,5 5),(9 9,9 9,10 10,9 9,9 9,9 9),(4 10,4 10,3 11,4 12,3 11,4 10,4 10))"; -template + +template void test_all() { typedef bg::model::linestring

linestring; typedef bg::model::multi_linestring multi_linestring_type; - typedef bg::model::polygon

polygon; + typedef bg::model::polygon polygon; bg::strategy::buffer::join_miter join_miter; bg::strategy::buffer::join_round join_round(100); @@ -49,13 +55,20 @@ void test_all() test_one("two_bends", two_bends, join_round_by_divide, end_flat, 64.6217, 1.5, 1.5); test_one("two_bends", two_bends, join_miter, end_flat, 65.1834, 1.5, 1.5); test_one("two_bends", two_bends, join_miter, end_round, 75.2917, 1.5, 1.5); + + test_one("degenerate0", degenerate0, join_round, end_round, 0.0, 3.0, 3.0); + test_one("degenerate1", degenerate1, join_round, end_round, 28.2503, 3.0, 3.0); + test_one("degenerate2", degenerate2, join_round, end_round, 56.0457, 3.0, 3.0); + test_one("degenerate3", degenerate3, join_round, end_round, 80.4531, 3.0, 3.0); + test_one("degenerate4", degenerate4, join_round, end_round, 104.3142, 3.0, 3.0); } int test_main(int, char* []) { - test_all >(); + test_all >(); + test_all >(); return 0; } diff --git a/test/algorithms/buffer/multi_point_buffer.cpp b/test/algorithms/buffer/multi_point_buffer.cpp index 148292ef4..da0efc3a7 100644 --- a/test/algorithms/buffer/multi_point_buffer.cpp +++ b/test/algorithms/buffer/multi_point_buffer.cpp @@ -21,12 +21,10 @@ static std::string const multipoint_a = "MULTIPOINT((39 44),(38 37),(41 29),(15 static std::string const multipoint_b = "MULTIPOINT((5 56),(98 67),(20 7),(58 60),(10 4),(75 68),(61 68),(75 62),(92 26),(74 6),(67 54),(20 43),(63 30),(45 7))"; -template +template void test_all() { - //std::cout << typeid(bg::coordinate_type

::type).name() << std::endl; - - typedef bg::model::polygon

polygon; + typedef bg::model::polygon polygon; typedef bg::model::multi_point

multi_point_type; bg::strategy::buffer::join_miter join_miter; @@ -185,9 +183,8 @@ void test_growth(int n, int distance_count) int test_main(int, char* []) { - //std::cout << std::setprecision(6); - //test_all >(); - test_all >(); + test_all >(); + test_all >(); #ifdef BOOST_GEOMETRY_BUFFER_TEST_GROWTH diff --git a/test/algorithms/buffer/multi_polygon_buffer.cpp b/test/algorithms/buffer/multi_polygon_buffer.cpp index 9beeff8cc..cb7313f94 100644 --- a/test/algorithms/buffer/multi_polygon_buffer.cpp +++ b/test/algorithms/buffer/multi_polygon_buffer.cpp @@ -24,6 +24,13 @@ static std::string const wrapped static std::string const triangles = "MULTIPOLYGON(((0 4,3 0,-2.5 -1,0 4)),((3 8,5.5 13,8 8,3 8)),((11 4,13.5 -1,8 0,11 4)))"; +static std::string const degenerate0 + = "MULTIPOLYGON()"; +static std::string const degenerate1 + = "MULTIPOLYGON(((5 5,5 5,5 5,5 5)),((6 6,6 6,6 6,6 6)))"; +static std::string const degenerate2 + = "MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0),(5 5,5 5,5 5,5 5)),((11 5,11 5,11 5,11 5)))"; + // From robustness tests (rt) // Case with duplicate points (due to chained boxes) (round) @@ -260,10 +267,10 @@ static std::string const rt_u12 static std::string const rt_u13 = "MULTIPOLYGON(((6 4,6 5,7 5,6 4)),((3 2,3 3,4 3,3 2)),((7 8,7 9,8 9,8 8,7 8)),((4 9,4 10,5 10,4 9)),((7 7,7 8,8 7,7 7)),((2 6,2 7,3 7,2 6)),((0 1,1 2,1 1,0 1)),((3 1,4 2,4 1,3 1)),((2 5,2 6,3 6,2 5)),((3 5,4 4,3 4,2 4,3 5)),((4 1,5 2,5 1,4 1)),((2 0,2 1,3 1,2 0)),((5 7,5 8,6 7,5 7)),((0 2,0 3,1 3,0 2)),((9 8,9 9,10 9,10 8,9 8)),((7 5,7 6,8 5,7 5)),((5 6,5 7,6 6,5 6)),((0 6,0 7,1 7,1 6,0 6)),((5 0,5 1,6 1,5 0)),((8 7,8 8,9 8,8 7)),((4.5 4.5,5 4,4 4,4 5,5 5,4.5 4.5)),((6 2,5 2,5 3,6 3,7 3,8 2,7 2,6 2)),((8 6,8 7,9 7,9 6,9 5,8 5,8 6)),((8 1,9 0,8 0,7 0,8 1)))"; -template +template void test_all() { - typedef bg::model::polygon

polygon_type; + typedef bg::model::polygon polygon_type; typedef bg::model::multi_polygon multi_polygon_type; bg::strategy::buffer::join_miter join_miter; @@ -285,6 +292,11 @@ void test_all() test_one("multi_simplex_50", simplex, join_round, end_flat, 174.46, 5.0); test_one("multi_simplex_50", simplex, join_miter, end_flat, 298.797, 5.0); + test_one("multi_simplex_01", simplex, join_round, end_flat, 9.7514, -0.1); + test_one("multi_simplex_05", simplex, join_round, end_flat, 3.2019, -0.5); + test_one("multi_simplex_10", simplex, join_round, end_flat, 0.2012, -1.0); + test_one("multi_simplex_12", simplex, join_round, end_flat, 0.0, -1.2); + test_one("zonethru_05", zonethru, join_round, end_flat, 67.4627, 0.5); test_one("zonethru_05", zonethru, join_miter, end_flat, 68.0000, 0.5); test_one("zonethru_10", zonethru, join_round, end_flat, 93.8508, 1.0); @@ -298,6 +310,10 @@ void test_all() test_one("wrapped_15", wrapped, join_round, end_flat, 167.066, 1.5); test_one("wrapped_15", wrapped, join_miter, end_flat, 169.000, 1.5); + test_one("degenerate0", degenerate0, join_round, end_flat, 0.0, 1.0); + test_one("degenerate1", degenerate1, join_round, end_flat, 5.708, 1.0); + test_one("degenerate2", degenerate2, join_round, end_flat, 133.0166, 0.75); + test_one("rt_a", rt_a, join_round, end_flat, 34.5381, 1.0); test_one("rt_a", rt_a, join_miter, end_flat, 36, 1.0); test_one("rt_b", rt_b, join_round, end_flat, 31.4186, 1.0); @@ -364,11 +380,13 @@ void test_all() test_one("rt_q1", rt_q1, join_miter, end_flat, 27, 1.0); test_one("rt_q2", rt_q2, join_miter, end_flat, 26.4853, 1.0); + test_one("rt_q2", rt_q2, join_miter, end_flat, 0.9697, -0.25); test_one("rt_r", rt_r, join_miter, end_flat, 21.0761, 1.0); test_one("rt_s1", rt_s1, join_miter, end_flat, 20.4853, 1.0); test_one("rt_s2", rt_s2, join_miter, end_flat, 24.6495, 1.0); test_one("rt_t", rt_t, join_miter, end_flat, 15.6569, 1.0); + test_one("rt_t", rt_t, join_miter, end_flat, 0.1679, -0.25); test_one("rt_u1", rt_u1, join_round, end_flat, 33.2032, 1.0); test_one("rt_u2", rt_u2, join_round, end_flat, 138.8001, 1.0); @@ -384,8 +402,13 @@ void test_all() test_one("rt_u8", rt_u8, join_miter, end_flat, 70.9142, 1.0); test_one("rt_u9", rt_u9, join_miter, end_flat, 59.3063, 1.0); test_one("rt_u10", rt_u10, join_miter, end_flat, 144.0858, 1.0); + test_one("rt_u10_50", rt_u10, join_miter, end_flat, 0.2145, -0.50); + test_one("rt_u10_25", rt_u10, join_miter, end_flat, 9.6682, -0.25); test_one("rt_u11", rt_u11, join_miter, end_flat, 131.3995, 1.0); + test_one("rt_u11_50", rt_u11, join_miter, end_flat, 0.04289, -0.50); + test_one("rt_u11_25", rt_u11, join_miter, end_flat, 10.1449, -0.25); + #if defined(BOOST_GEOMETRY_BUFFER_INCLUDE_FAILING_TESTS) test_one("rt_u12", rt_u12, join_miter, end_flat, 999, 1.0); test_one("rt_u13", rt_u13, join_miter, end_flat, 115.4853, 1.0); @@ -394,7 +417,8 @@ void test_all() int test_main(int, char* []) { - test_all >(); + test_all >(); + test_all >(); //test_all >(); return 0; diff --git a/test/algorithms/buffer/point_buffer.cpp b/test/algorithms/buffer/point_buffer.cpp index ff68b9c52..a5f1b979b 100644 --- a/test/algorithms/buffer/point_buffer.cpp +++ b/test/algorithms/buffer/point_buffer.cpp @@ -7,29 +7,15 @@ // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -//#define BOOST_GEOMETRY_DEBUG_WITH_MAPPER -//#define BOOST_GEOMETRY_DEBUG_ASSEMBLE -//#define BOOST_GEOMETRY_DEBUG_IDENTIFIER - -#include - -#include -#include - -#include - -#include -#include - #include static std::string const simplex = "POINT(5 5)"; -template +template void test_all() { - typedef bg::model::polygon

polygon; + typedef bg::model::polygon polygon; bg::strategy::buffer::join_miter join_miter; bg::strategy::buffer::end_flat end_flat; @@ -44,8 +30,7 @@ void test_all() int test_main(int, char* []) { - //std::cout << std::setprecision(6); - //test_all >(); - test_all >(); + test_all >(); + test_all >(); return 0; } diff --git a/test/algorithms/buffer/polygon_buffer.cpp b/test/algorithms/buffer/polygon_buffer.cpp index e19b4f500..8a01c13f8 100644 --- a/test/algorithms/buffer/polygon_buffer.cpp +++ b/test/algorithms/buffer/polygon_buffer.cpp @@ -14,6 +14,8 @@ static std::string const simplex = "POLYGON ((0 0,1 5,6 1,0 0))"; static std::string const concave_simplex = "POLYGON ((0 0,3 5,3 3,5 3,0 0))"; +static std::string const square_simplex + = "POLYGON ((0 0,0 1,1 1,1 0,0 0))"; static std::string const spike_simplex = "POLYGON ((0 0,1 5,3 3,5 5,3 3,5 1,0 0))"; static std::string const chained_box @@ -63,6 +65,21 @@ static std::string const bowl static std::string const triangle = "POLYGON((4 5,5 4,4 4,3 4,3 5,3 6,4 5))"; +// Triangle which caused acos in join_round to fail with larger side strategy +static std::string const sharp_triangle + = "POLYGON((2 0,3 8,4 0,2 0))"; + + +static std::string const degenerate0 + = "POLYGON(())"; +static std::string const degenerate1 + = "POLYGON((5 5))"; +static std::string const degenerate2 + = "POLYGON((5 5,5 5,5 5,5 5))"; +static std::string const degenerate3 + = "POLYGON((0 0,0 10,10 10,10 0,0 0),(5 5,5 5,5 5,5 5))"; + + // Real-life examples static std::string const county1 = "POLYGON((-111.700 41.200 ,-111.681388 41.181739 ,-111.682453 41.181506 ,-111.684052 41.180804 ,-111.685295 41.180538 ,-111.686318 41.180776 ,-111.687517 41.181416 ,-111.688982 41.181520 ,-111.690670 41.181523 ,-111.692135 41.181460 ,-111.693646 41.182034 ,-111.695156 41.182204 ,-111.696489 41.182274 ,-111.697775 41.182075 ,-111.698974 41.181539 ,-111.700485 41.182348 ,-111.701374 41.182955 ,-111.700 41.200))"; @@ -98,11 +115,64 @@ static std::string const ticket_10398_4 static std::string const ticket_10412 = "POLYGON((897747.8 6270564.3,897764.3 6270569.7,897776.5 6270529.5,897768.1 6270527.1,897767.6 6270529.4,897756.3 6270525.8,897745.8 6270522.3,897752 6270502.9,897749.7 6270502,897750.7 6270499.1,897751.8 6270498.6,897752.3 6270499.3,897754.6 6270497.9,897755.8 6270500.2,897766.8 6270494.1,897765.6 6270491.5,897768.3 6270490.5,897770.9 6270491.5,897770.2 6270494.6,897780.1 6270497.5,897781 6270494.6,897786.8 6270496.6,897790.8 6270482.5,897785.3 6270480.7,897785.9 6270478.2,897768.9 6270473.2,897768.1 6270475.8,897766.1 6270475.2,897758.7 6270479.2,897753.2 6270481.8,897751.9 6270479,897746.5 6270481.9,897748 6270484.6,897745.2 6270486.1,897743.9 6270483.3,897741.4 6270484.7,897742.6 6270487.3,897739.4 6270488.9,897738.3 6270486.3,897735.6 6270487.8,897733.1 6270496.8,897731.2 6270502.7,897732.4 6270503.2,897731.5 6270506.1,897730.3 6270505.7,897725.8 6270520.2,897726.8 6270520.7,897726 6270523,897728 6270523.7,897726.3 6270529.6,897742.8 6270534.5,897741.2 6270539.9,897751.4 6270543.4,897750.7 6270546.4,897753.2 6270547.2,897747.8 6270564.3))"; +// CCW Polygons not working in 1.56 +static std::string const mysql_report_2014_10_24 + = "POLYGON((0 0, 0 8, 8 8, 8 10, -10 10, -10 0, 0 0))"; +static std::string const mysql_report_2014_10_28_1 + = "POLYGON((0 0,10 10,0 8,0 0))"; +static std::string const mysql_report_2014_10_28_2 + = "POLYGON((1 1,10 10,0 8,1 1))"; +static std::string const mysql_report_2014_10_28_3 + = "POLYGON((2 2,8 2,8 8,2 8,2 2))"; -template + +class buffer_custom_side_strategy +{ +public : + template + < + typename Point, + typename OutputRange, + typename DistanceStrategy + > + static inline void apply( + Point const& input_p1, Point const& input_p2, + bg::strategy::buffer::buffer_side_selector side, + DistanceStrategy const& distance, + OutputRange& output_range) + { + // Generate a block along (left or right of) the segment + + double const dx = bg::get<0>(input_p2) - bg::get<0>(input_p1); + double const dy = bg::get<1>(input_p2) - bg::get<1>(input_p1); + + // For normalization [0,1] (=dot product d.d, sqrt) + double const length = bg::math::sqrt(dx * dx + dy * dy); + + if (bg::math::equals(length, 0)) + { + return; + } + + // Generate the perpendicular p, to the left (ccw), and use an adapted distance + double const d = 1.1 * distance.apply(input_p1, input_p2, side); + double const px = d * -dy / length; + double const py = d * dx / length; + + output_range.resize(2); + + bg::set<0>(output_range.front(), bg::get<0>(input_p1) + px); + bg::set<1>(output_range.front(), bg::get<1>(input_p1) + py); + bg::set<0>(output_range.back(), bg::get<0>(input_p2) + px); + bg::set<1>(output_range.back(), bg::get<1>(input_p2) + py); + } +}; + + +template void test_all() { - typedef bg::model::polygon

polygon_type; + typedef bg::model::polygon polygon_type; bg::strategy::buffer::join_miter join_miter(10.0); bg::strategy::buffer::join_round join_round(100); @@ -112,9 +182,23 @@ void test_all() test_one("simplex", simplex, join_round, end_flat, 47.9408, 1.5); test_one("simplex", simplex, join_miter, end_flat, 52.8733, 1.5); + test_one("simplex", simplex, join_round, end_flat, 7.04043, -0.5); + test_one("simplex", simplex, join_miter, end_flat, 7.04043, -0.5); + + test_one("square_simplex", square_simplex, join_round, end_flat, 14.0639, 1.5); + test_one("square_simplex", square_simplex, join_miter, end_flat, 16.0000, 1.5); + + test_one("square_simplex01", square_simplex, join_miter, end_flat, 0.6400, -0.1); + test_one("square_simplex04", square_simplex, join_miter, end_flat, 0.0400, -0.4); + test_one("square_simplex05", square_simplex, join_miter, end_flat, 0.0, -0.5); + test_one("square_simplex06", square_simplex, join_miter, end_flat, 0.0, -0.6); + test_one("concave_simplex", concave_simplex, join_round, end_flat, 14.5616, 0.5); test_one("concave_simplex", concave_simplex, join_miter, end_flat, 16.3861, 0.5); + test_one("concave_simplex", concave_simplex, join_round, end_flat, 0.777987, -0.5); + test_one("concave_simplex", concave_simplex, join_miter, end_flat, 0.724208, -0.5); + test_one("spike_simplex15", spike_simplex, join_round, end_round, 50.3633, 1.5); test_one("spike_simplex15", spike_simplex, join_miter, end_flat, 51.5509, 1.5); @@ -154,13 +238,13 @@ void test_all() test_one("indentation12", indentation, join_miter, end_flat, 46.3541, 1.2); test_one("indentation12", indentation, join_round, end_flat, 45.0537, 1.2); - // TODO: fix, the buffered pieces are currently counterclockwise, that should be reversed - //test_one("indentation4_neg", indentation, join_miter, end_flat, 6.99098413022335, -0.4); - //test_one("indentation4_neg", indentation, join_round, end_flat, 7.25523322189147, -0.4); - //test_one("indentation8_neg", indentation, join_miter, end_flat, 1.36941992048731, -0.8); - //test_one("indentation8_neg", indentation, join_round, end_flat, 1.37375487490664, -0.8); - //test_one("indentation12_neg", indentation, join_miter, end_flat, 0, -1.2); - //test_one("indentation12_neg", indentation, join_round, end_flat, 0, -1.2); + // Indentation - deflated + test_one("indentation4", indentation, join_miter, end_flat, 6.99098413022335, -0.4); + test_one("indentation4", indentation, join_round, end_flat, 7.25523322189147, -0.4); + test_one("indentation8", indentation, join_miter, end_flat, 1.36941992048731, -0.8); + test_one("indentation8", indentation, join_round, end_flat, 1.37375487490664, -0.8); + test_one("indentation12", indentation, join_miter, end_flat, 0, -1.2); + test_one("indentation12", indentation, join_round, end_flat, 0, -1.2); test_one("donut_simplex6", donut_simplex, join_miter, end_flat, 53.648, 0.6); test_one("donut_simplex6", donut_simplex, join_round, end_flat, 52.820, 0.6); @@ -175,11 +259,20 @@ void test_all() test_one("donut_simplex16", donut_simplex, join_miter, end_flat, 93.777, 1.6); test_one("donut_simplex16", donut_simplex, join_round, end_flat, 87.933, 1.6); + test_one("donut_simplex3", donut_simplex, join_miter, end_flat, 19.7636, -0.3); + test_one("donut_simplex3", donut_simplex, join_round, end_flat, 19.8861, -0.3); + test_one("donut_simplex6", donut_simplex, join_miter, end_flat, 12.8920, -0.6); + test_one("donut_simplex6", donut_simplex, join_round, end_flat, 12.9157, -0.6); + test_one("donut_diamond1", donut_diamond, join_miter, end_flat, 280.0, 1.0); test_one("donut_diamond4", donut_diamond, join_miter, end_flat, 529.0, 4.0); test_one("donut_diamond5", donut_diamond, join_miter, end_flat, 625.0, 5.0); test_one("donut_diamond6", donut_diamond, join_miter, end_flat, 729.0, 6.0); + test_one("donut_diamond1", donut_diamond, join_miter, end_flat, 122.0417, -1.0); + test_one("donut_diamond2", donut_diamond, join_miter, end_flat, 56.3750, -2.0); + test_one("donut_diamond3", donut_diamond, join_miter, end_flat, 17.7084, -3.0); + test_one("arrow4", arrow, join_miter, end_flat, 28.265, 0.4); test_one("arrow4", arrow, join_round, end_flat, 27.039, 0.4); test_one("arrow5", arrow, join_miter, end_flat, 31.500, 0.5); @@ -210,6 +303,11 @@ void test_all() test_one("fork_c1", fork_c, join_miter, end_flat, 152, 1); test_one("triangle", triangle, join_miter, end_flat, 14.6569, 1.0); + test_one("degenerate0", degenerate0, join_round, end_round, 0.0, 1.0); + test_one("degenerate1", degenerate1, join_round, end_round, 3.1389, 1.0); + test_one("degenerate2", degenerate2, join_round, end_round, 3.1389, 1.0); + test_one("degenerate3", degenerate3, join_round, end_round, 143.1395, 1.0); + test_one("gammagate2", gammagate, join_miter, end_flat, 130, 2); test_one("flower1", flower, join_miter, end_flat, 67.614, 0.1); @@ -234,6 +332,9 @@ void test_all() test_one("flower55", flower, join_round, end_flat, 96.580, 0.55); test_one("flower60", flower, join_round, end_flat, 99.408, 0.60); + // Flower - deflated + test_one("flower60", flower, join_round, end_flat, 19.3210, -0.60); + // Saw { // SQL Server: @@ -288,6 +389,8 @@ void test_all() } test_one("county1", county1, join_round, end_flat, 0.00114092, 0.01); test_one("county1", county1, join_miter, end_flat, 0.00132859, 0.01); + test_one("county1", county1, join_round, end_flat, 0.00114092, -0.01); + test_one("county1", county1, join_miter, end_flat, 0.00132859, -0.01); test_one("parcel1_10", parcel1, join_round, end_flat, 7571.39121246337891, 10.0); test_one("parcel1_10", parcel1, join_miter, end_flat, 8207.45314788818359, 10.0); @@ -310,23 +413,20 @@ void test_all() test_one("parcel3_30", parcel3, join_round, end_flat, 45261.4196014404297, 30.0); test_one("parcel3_30", parcel3, join_miter, end_flat, 45567.3875694274902, 30.0); - test_one("parcel3_bend_10", parcel3_bend, join_round, end_flat, 155.6188, 5.0); + test_one("parcel3_bend_5", parcel3_bend, join_round, end_flat, 155.6188, 5.0); test_one("parcel3_bend_10", parcel3_bend, join_round, end_flat, 458.4187, 10.0); - test_one("parcel3_bend_10", parcel3_bend, join_round, end_flat, 917.9747, 15.0); - test_one("parcel3_bend_10", parcel3_bend, join_round, end_flat, 1534.4795, 20.0); + // These cases differ a bit based on point order (TODO: find out / describe why) + test_one("parcel3_bend_15", parcel3_bend, join_round, end_flat, Clockwise ? 917.9747 : 917.996, 15.0); + test_one("parcel3_bend_20", parcel3_bend, join_round, end_flat, Clockwise ? 1534.4795 : 1534.508, 20.0); - // Negative buffers making polygons smaller - test_one("simplex", simplex, join_round, end_flat, 7.04043, -0.5); - test_one("simplex", simplex, join_miter, end_flat, 7.04043, -0.5); - test_one("concave_simplex", concave_simplex, join_round, end_flat, 0.777987, -0.5); - test_one("concave_simplex", concave_simplex, join_miter, end_flat, 0.724208, -0.5); - - test_one("donut_simplex3", donut_simplex, join_miter, end_flat, 19.7636, -0.3); - test_one("donut_simplex3", donut_simplex, join_round, end_flat, 19.8861, -0.3); - test_one("donut_simplex6", donut_simplex, join_miter, end_flat, 12.8920, -0.6); - test_one("donut_simplex6", donut_simplex, join_round, end_flat, 12.9157, -0.6); + // Parcel - deflated + test_one("parcel1_10", parcel1, join_round, end_flat, 1571.9024, -10.0); + test_one("parcel1_10", parcel1, join_miter, end_flat, 1473.7325, -10.0); + test_one("parcel1_20", parcel1, join_round, end_flat, 209.3579, -20.0); + test_one("parcel1_20", parcel1, join_miter, end_flat, 188.4224, -20.0); + // Tickets test_one("ticket_10398_1_5", ticket_10398_1, join_miter, end_flat, 494.7192, 0.5, -999, false); test_one("ticket_10398_1_25", ticket_10398_1, join_miter, end_flat, 697.7798, 2.5, -999, false); test_one("ticket_10398_1_84", ticket_10398_1, join_miter, end_flat, 1470.8096, 8.4, -999, false); @@ -344,8 +444,67 @@ void test_all() test_one("ticket_10398_4_91", ticket_10398_4, join_miter, end_flat, 819.1406, 9.1, -999, false); test_one("ticket_10412", ticket_10412, join_miter, end_flat, 3109.6616, 1.5, -999, false); + + // Tickets - deflated + test_one("ticket_10398_1_5", ticket_10398_1, join_miter, end_flat, 404.3936, -0.5); + test_one("ticket_10398_1_25", ticket_10398_1, join_miter, end_flat, 246.7329, -2.5); + + { + bg::strategy::buffer::join_round join_round32(32); + bg::strategy::buffer::end_round end_round32(32); + test_one("mysql_report_2014_10_24", mysql_report_2014_10_24, + join_round32, end_round32, 174.902, 1.0); + test_one("mysql_report_2014_10_28_1", mysql_report_2014_10_28_1, + join_round32, end_round32, 75.46, 1.0); + test_one("mysql_report_2014_10_28_2", mysql_report_2014_10_28_2, + join_round32, end_round32, 69.117, 1.0); + test_one("mysql_report_2014_10_28_3", mysql_report_2014_10_28_3, + join_round32, end_round32, 63.121, 1.0); + } + + + { + bg::strategy::buffer::join_round join_round12(12); + buffer_custom_side_strategy side_strategy; + bg::strategy::buffer::point_circle point_strategy; + bg::strategy::buffer::distance_symmetric + < + typename bg::coordinate_type

::type + > distance_strategy(1.0); + + test_with_custom_strategies("sharp_triangle", + sharp_triangle, + join_round12, end_flat, distance_strategy, side_strategy, point_strategy, + 31.0721); + } + } +template +< + typename InputPoint, + typename OutputPoint, + bool InputClockwise, + bool OutputClockwise, + bool InputClosed, + bool OutputClosed +> +void test_mixed() +{ + typedef bg::model::polygon input_polygon_type; + typedef bg::model::polygon output_polygon_type; + + bg::strategy::buffer::join_round join_round(12); + bg::strategy::buffer::end_flat end_flat; + + std::ostringstream name; + name << "mixed_" << std::boolalpha + << InputClockwise << "_" << OutputClockwise + << "_" << InputClosed << "_" << OutputClosed; + + test_one(name.str(), + simplex, join_round, end_flat, 47.4831, 1.5); +} #ifdef HAVE_TTMATH #include @@ -353,8 +512,28 @@ void test_all() int test_main(int, char* []) { - test_all >(); - //test_all >(); - + typedef bg::model::point dpoint; + + test_all(); + test_all(); + +#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) + + test_mixed(); + test_mixed(); + test_mixed(); + test_mixed(); + + test_mixed(); + test_mixed(); + test_mixed(); + test_mixed(); + +#ifdef HAVE_TTMATH + test_all >(); +#endif + +#endif + return 0; } diff --git a/test/algorithms/buffer/test_buffer.hpp b/test/algorithms/buffer/test_buffer.hpp index c6467fdeb..1fd8810fd 100644 --- a/test/algorithms/buffer/test_buffer.hpp +++ b/test/algorithms/buffer/test_buffer.hpp @@ -128,7 +128,7 @@ struct svg_visitor color = 'r'; is_good = false; break; - case bgdb::inside_original : + case bgdb::location_discard : fill = "fill:rgb(0,0,255);"; color = 'b'; is_good = false; @@ -285,6 +285,9 @@ struct svg_visitor template inline void apply(PieceCollection const& collection, int phase) { + // Comment next return if you want to see pieces, turns, etc. + return; + if(phase == 0) { map_pieces(collection.m_pieces, collection.offsetted_rings, true, true); @@ -362,12 +365,18 @@ template typename GeometryOut, typename JoinStrategy, typename EndStrategy, + typename DistanceStrategy, + typename SideStrategy, + typename PointStrategy, typename Geometry > void test_buffer(std::string const& caseid, Geometry const& geometry, - JoinStrategy const& join_strategy, EndStrategy const& end_strategy, + JoinStrategy const& join_strategy, + EndStrategy const& end_strategy, + DistanceStrategy const& distance_strategy, + SideStrategy const& side_strategy, + PointStrategy const& point_strategy, bool check_self_intersections, double expected_area, - double distance_left, double distance_right, double tolerance, std::size_t* self_ip_count) { @@ -387,11 +396,6 @@ void test_buffer(std::string const& caseid, Geometry const& geometry, : "" ; - if (distance_right < -998) - { - distance_right = distance_left; - } - bg::model::box envelope; bg::envelope(geometry, envelope); @@ -411,7 +415,8 @@ void test_buffer(std::string const& caseid, Geometry const& geometry, << string_from_type::name() << "_" << join_name << (end_name.empty() ? "" : "_") << end_name - << (distance_left < 0 && distance_right < 0 ? "_deflate" : "") + << (distance_strategy.negative() ? "_deflate" : "") + << (bg::point_order::value == bg::counterclockwise ? "_ccw" : "") // << "_" << point_buffer_count ; @@ -426,10 +431,15 @@ void test_buffer(std::string const& caseid, Geometry const& geometry, mapper_type mapper(svg, 1000, 1000); { - double d = std::abs(distance_left) + std::abs(distance_right); - bg::model::box box = envelope; - bg::buffer(box, box, d * (join_name == "miter" ? 2.0 : 1.1)); + if (distance_strategy.negative()) + { + bg::buffer(box, box, 1.0); + } + else + { + bg::buffer(box, box, 1.1 * distance_strategy.max_distance(join_strategy, end_strategy)); + } mapper.add(box); } @@ -438,19 +448,6 @@ void test_buffer(std::string const& caseid, Geometry const& geometry, bg::detail::buffer::visit_pieces_default_policy visitor; #endif - bg::strategy::buffer::distance_asymmetric - < - coordinate_type - > - distance_strategy(distance_left, distance_right); - - bg::strategy::buffer::side_straight side_strategy; - - // For (multi)points a buffer with 88 points is used for testing. - // More points will give a more precise result - expected area should be - // adapted then - bg::strategy::buffer::point_circle circle_strategy(88); - typedef typename bg::point_type::type point_type; typedef typename bg::rescale_policy_type::type rescale_policy_type; @@ -469,7 +466,7 @@ void test_buffer(std::string const& caseid, Geometry const& geometry, side_strategy, join_strategy, end_strategy, - circle_strategy, + point_strategy, rescale_policy, visitor); @@ -524,16 +521,24 @@ void test_buffer(std::string const& caseid, Geometry const& geometry, // Map input geometry in green if (areal) { - mapper.map(geometry, "opacity:0.5;fill:rgb(0,128,0);stroke:rgb(0,128,0);stroke-width:2"); + mapper.map(geometry, "opacity:0.5;fill:rgb(0,128,0);stroke:rgb(0,64,0);stroke-width:2"); } else { mapper.map(geometry, "opacity:0.5;stroke:rgb(0,128,0);stroke-width:10"); } + // Map buffer in yellow (inflate) and with orange-dots (deflate) BOOST_FOREACH(GeometryOut const& polygon, buffered) { - mapper.map(polygon, "opacity:0.4;fill:rgb(255,255,128);stroke:rgb(0,0,0);stroke-width:3"); + if (distance_strategy.negative()) + { + mapper.map(polygon, "opacity:0.4;fill:rgb(255,255,192);stroke:rgb(255,128,0);stroke-width:3"); + } + else + { + mapper.map(polygon, "opacity:0.4;fill:rgb(255,255,128);stroke:rgb(0,0,0);stroke-width:3"); + } post_map(polygon, mapper, rescale_policy); } #endif @@ -595,10 +600,39 @@ void test_one(std::string const& caseid, std::string const& wkt, << std::endl; #endif + + bg::strategy::buffer::side_straight side_strategy; + bg::strategy::buffer::point_circle circle_strategy(88); + + bg::strategy::buffer::distance_asymmetric + < + typename bg::coordinate_type::type + > distance_strategy(distance_left, + distance_right > -998 ? distance_right : distance_left); + test_buffer - (caseid, g, join_strategy, end_strategy, + (caseid, g, + join_strategy, end_strategy, + distance_strategy, side_strategy, circle_strategy, check_self_intersections, expected_area, - distance_left, distance_right, tolerance, NULL); + tolerance, NULL); + + // Also test symmetric distance strategy if right-distance is not specified + if (bg::math::equals(distance_right, -999)) + { + bg::strategy::buffer::distance_symmetric + < + typename bg::coordinate_type::type + > sym_distance_strategy(distance_left); + + test_buffer + (caseid + "_sym", g, + join_strategy, end_strategy, + sym_distance_strategy, side_strategy, circle_strategy, + check_self_intersections, expected_area, + tolerance, NULL); + + } } // Version (currently for the Aimes test) counting self-ip's instead of checking @@ -621,10 +655,52 @@ void test_one(std::string const& caseid, std::string const& wkt, bg::read_wkt(wkt, g); bg::correct(g); - test_buffer(caseid, g, join_strategy, end_strategy, + bg::strategy::buffer::distance_asymmetric + < + typename bg::coordinate_type::type + > distance_strategy(distance_left, + distance_right > -998 ? distance_right : distance_left); + + bg::strategy::buffer::point_circle circle_strategy(88); + bg::strategy::buffer::side_straight side_strategy; + test_buffer(caseid, g, + join_strategy, end_strategy, + distance_strategy, side_strategy, circle_strategy, false, expected_area, - distance_left, distance_right, tolerance, &self_ip_count); + tolerance, &self_ip_count); +} + +template +< + typename Geometry, + typename GeometryOut, + typename JoinStrategy, + typename EndStrategy, + typename DistanceStrategy, + typename SideStrategy, + typename PointStrategy +> +void test_with_custom_strategies(std::string const& caseid, + std::string const& wkt, + JoinStrategy const& join_strategy, + EndStrategy const& end_strategy, + DistanceStrategy const& distance_strategy, + SideStrategy const& side_strategy, + PointStrategy const& point_strategy, + double expected_area) +{ + namespace bg = boost::geometry; + Geometry g; + bg::read_wkt(wkt, g); + bg::correct(g); + + test_buffer + (caseid, g, + join_strategy, end_strategy, + distance_strategy, side_strategy, point_strategy, + true, expected_area, 0.01, NULL); } + #endif diff --git a/test/algorithms/centroid.cpp b/test/algorithms/centroid.cpp index f3ef78688..8e3af7f75 100644 --- a/test/algorithms/centroid.cpp +++ b/test/algorithms/centroid.cpp @@ -5,6 +5,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. @@ -129,6 +134,34 @@ void test_large_integers() BOOST_CHECK_EQUAL(bg::get<1>(int_centroid), bg::get<1>(double_centroid_as_int)); } +//#include + +void test_large_doubles() +{ + typedef bg::model::point point; + point pt_far, pt_near; + bg::model::polygon poly_far, poly_near; + + // related to ticket #10643 + bg::read_wkt("POLYGON((1074699.93 703064.65, 1074703.90 703064.58, 1074704.53 703061.40, 1074702.10 703054.62, 1074699.93 703064.65))", poly_far); + bg::read_wkt("POLYGON((699.93 64.65, 703.90 64.58, 704.53 61.40, 702.10 54.62, 699.93 64.65))", poly_near); + + bg::centroid(poly_far, pt_far); + bg::centroid(poly_near, pt_near); + + BOOST_CHECK(bg::within(pt_far, poly_far)); + BOOST_CHECK(bg::within(pt_near, poly_near)); + + point pt_near_moved; + bg::set<0>(pt_near_moved, bg::get<0>(pt_near) + 1074000.0); + bg::set<1>(pt_near_moved, bg::get<1>(pt_near) + 703000.0); + + //geom_to_svg(poly_far, pt_far, "far.svg"); + //geom_to_svg(poly_near, pt_near, "near.svg"); + + double d = bg::distance(pt_far, pt_near_moved); + BOOST_CHECK(d < 0.1); +} int test_main(int, char* []) { @@ -149,6 +182,9 @@ int test_main(int, char* []) // The test currently fails in release mode. TODO: fix this test_large_integers(); #endif + + test_large_doubles(); + test_exceptions >(); return 0; diff --git a/test/algorithms/detail/sections/range_by_section.cpp b/test/algorithms/detail/sections/range_by_section.cpp index fa804f1ff..d7cadde30 100644 --- a/test/algorithms/detail/sections/range_by_section.cpp +++ b/test/algorithms/detail/sections/range_by_section.cpp @@ -24,7 +24,7 @@ template -void test_sectionalize(std::string const caseid, Geometry const& geometry, std::size_t section_count) +void test_sectionalize(std::string const /*caseid*/, Geometry const& geometry, std::size_t section_count) { typedef typename bg::point_type::type point; typedef bg::model::box box; diff --git a/test/algorithms/distance/Jamfile.v2 b/test/algorithms/distance/Jamfile.v2 new file mode 100644 index 000000000..8d755c94a --- /dev/null +++ b/test/algorithms/distance/Jamfile.v2 @@ -0,0 +1,27 @@ +# Boost.Geometry (aka GGL, Generic Geometry Library) +# +# Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. +# Copyright (c) 2008-2014 Bruno Lalande, Paris, France. +# Copyright (c) 2009-2014 Mateusz Loskot, London, UK. +# +# This file was modified by Oracle on 2014. +# 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 +# http://www.boost.org/LICENSE_1_0.txt) + +test-suite boost-geometry-algorithms-distance + : + [ run distance.cpp : : : msvc:/bigobj ] + [ 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 ] + [ run distance_pointlike_pointlike.cpp ] + [ run distance_se_pl_pl.cpp ] + ; diff --git a/test/algorithms/distance.cpp b/test/algorithms/distance/distance.cpp similarity index 99% rename from test/algorithms/distance.cpp rename to test/algorithms/distance/distance.cpp index 8f2dfd03c..84e066808 100644 --- a/test/algorithms/distance.cpp +++ b/test/algorithms/distance/distance.cpp @@ -16,7 +16,7 @@ #include #include -#include +#include "test_distance.hpp" #include #include diff --git a/test/algorithms/distance_all.cpp b/test/algorithms/distance/distance_all.cpp similarity index 100% rename from test/algorithms/distance_all.cpp rename to test/algorithms/distance/distance_all.cpp diff --git a/test/algorithms/distance_areal_areal.cpp b/test/algorithms/distance/distance_areal_areal.cpp similarity index 100% rename from test/algorithms/distance_areal_areal.cpp rename to test/algorithms/distance/distance_areal_areal.cpp diff --git a/test/algorithms/distance_linear_areal.cpp b/test/algorithms/distance/distance_linear_areal.cpp similarity index 100% rename from test/algorithms/distance_linear_areal.cpp rename to test/algorithms/distance/distance_linear_areal.cpp diff --git a/test/algorithms/distance_linear_linear.cpp b/test/algorithms/distance/distance_linear_linear.cpp similarity index 100% rename from test/algorithms/distance_linear_linear.cpp rename to test/algorithms/distance/distance_linear_linear.cpp diff --git a/test/algorithms/distance_pointlike_areal.cpp b/test/algorithms/distance/distance_pointlike_areal.cpp similarity index 100% rename from test/algorithms/distance_pointlike_areal.cpp rename to test/algorithms/distance/distance_pointlike_areal.cpp diff --git a/test/algorithms/distance_pointlike_linear.cpp b/test/algorithms/distance/distance_pointlike_linear.cpp similarity index 100% rename from test/algorithms/distance_pointlike_linear.cpp rename to test/algorithms/distance/distance_pointlike_linear.cpp diff --git a/test/algorithms/distance_pointlike_pointlike.cpp b/test/algorithms/distance/distance_pointlike_pointlike.cpp similarity index 100% rename from test/algorithms/distance_pointlike_pointlike.cpp rename to test/algorithms/distance/distance_pointlike_pointlike.cpp diff --git a/test/algorithms/distance/distance_se_pl_pl.cpp b/test/algorithms/distance/distance_se_pl_pl.cpp new file mode 100644 index 000000000..630d33794 --- /dev/null +++ b/test/algorithms/distance/distance_se_pl_pl.cpp @@ -0,0 +1,229 @@ +// 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 + +#include + +#ifndef BOOST_TEST_MODULE +#define BOOST_TEST_MODULE test_distance_spherical_equatorial_pl_pl +#endif + +#include + +#include +#include + +#include "test_distance_se_common.hpp" + + +typedef bg::cs::spherical_equatorial cs_type; +typedef bg::model::point point_type; +typedef bg::model::multi_point multi_point_type; + +namespace services = bg::strategy::distance::services; +typedef bg::default_distance_result::type return_type; + +typedef bg::strategy::distance::haversine point_point_strategy; + +//=========================================================================== + +inline bg::default_distance_result::type +distance_from_wkt(std::string const& wkt1, std::string const& wkt2) +{ + point_type p1, p2; + bg::read_wkt(wkt1, p1); + bg::read_wkt(wkt2, p2); + return bg::distance(p1, p2); +} + +inline bg::default_comparable_distance_result::type +comparable_distance_from_wkt(std::string const& wkt1, std::string const& wkt2) +{ + point_type p1, p2; + bg::read_wkt(wkt1, p1); + bg::read_wkt(wkt2, p2); + return bg::comparable_distance(p1, p2); +} + +//=========================================================================== + +template +void test_distance_point_point(Strategy const& strategy) +{ +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "point/point distance tests" << std::endl; +#endif + typedef test_distance_of_geometries tester; + + tester::apply("POINT(10 10)", + "POINT(0 0)", + 0.24619691677893202, + 0.0150768448035229, + strategy); + tester::apply("POINT(10 10)", + "POINT(10 10)", + 0, 0, strategy); + + // antipodal points + tester::apply("POINT(0 10)", + "POINT(180 -10)", + 180.0 * bg::math::d2r, 1.0, strategy); +} + +//=========================================================================== + +template +void test_distance_point_multipoint(Strategy const& strategy) +{ +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "point/multipoint distance tests" << std::endl; +#endif + typedef test_distance_of_geometries tester; + + tester::apply("POINT(10 10)", + "MULTIPOINT(10 10,20 10,20 20,10 20)", + 0, 0, strategy); + tester::apply("POINT(10 10)", + "MULTIPOINT(20 20,20 30,30 20,30 30)", + distance_from_wkt("POINT(10 10)", "POINT(20 20)"), + comparable_distance_from_wkt("POINT(10 10)", "POINT(20 20)"), + strategy); + tester::apply("POINT(3 0)", + "MULTIPOINT(20 20,20 40,40 20,40 40)", + distance_from_wkt("POINT(3 0)", "POINT(20 20)"), + comparable_distance_from_wkt("POINT(3 0)", "POINT(20 20)"), + strategy); + + // almost antipodal points + tester::apply("POINT(179 2)", + "MULTIPOINT(3 3,4 3,4 4,3 4)", + distance_from_wkt("POINT(179 2)", "POINT(4 4)"), + comparable_distance_from_wkt("POINT(179 2)", "POINT(4 4)"), + strategy); + + // minimum distance across the dateline + tester::apply("POINT(355 5)", + "MULTIPOINT(10 10,20 10,20 20,10 20)", + distance_from_wkt("POINT(355 5)", "POINT(10 10)"), + comparable_distance_from_wkt("POINT(355 5)", "POINT(10 10)"), + strategy); +} + +//=========================================================================== + +template +void test_distance_multipoint_multipoint(Strategy const& strategy) +{ +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "multipoint/multipoint distance tests" << std::endl; +#endif + typedef test_distance_of_geometries + < + multi_point_type, multi_point_type + > tester; + + tester::apply("MULTIPOINT(10 10,11 10,10 11,11 11)", + "MULTIPOINT(11 11,12 11,12 12,11 12)", + 0, 0, strategy); + tester::apply("MULTIPOINT(10 10,11 10,10 11,11 11)", + "MULTIPOINT(12 12,12 13,13 12,13 13)", + distance_from_wkt("POINT(11 11)", "POINT(12 12)"), + comparable_distance_from_wkt("POINT(11 11)", "POINT(12 12)"), + strategy); + + // example with many points in each multi-point so that the r-tree + // does some splitting. + + tester::apply("MULTIPOINT(1 1,1 2,1 3,1 4,1 5,1 6,1 7,1 8,1 9,1 10,\ + 2 1,2 2,2 3,2 4,2 5,2 6,2 7,2 8,2 9,2 10,\ + 3 1,3 2,3 3,3 4,3 5,3 6,3 7,3 8,3 9,3 10,\ + 10 1,10 10)", + "MULTIPOINT(11 11,11 12,11 13,11 14,11 15,\ + 11 16,11 17,11 18,11 19,11 20,\ + 12 11,12 12,12 13,12 24,12 15,\ + 12 16,12 17,12 18,12 29,12 20,\ + 13 11,13 12,13 13,13 24,13 15,\ + 13 16,13 17,13 18,13 29,13 20,\ + 20 11,20 20)", + distance_from_wkt("POINT(10 10)", "POINT(11 11)"), + comparable_distance_from_wkt("POINT(10 10)", "POINT(11 11)"), + strategy); + +} + +//=========================================================================== + +template +void test_more_empty_input_pointlike_pointlike(Strategy const& strategy) +{ +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "testing on empty inputs... " << std::flush; +#endif + bg::model::multi_point multipoint_empty; + + Point point = from_wkt("POINT(0 0)"); + + // 1st geometry is empty + test_empty_input(multipoint_empty, point, strategy); + + // 2nd geometry is empty + test_empty_input(point, multipoint_empty, strategy); + + // both geometries are empty + test_empty_input(multipoint_empty, multipoint_empty, strategy); + +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << "done!" << std::endl; +#endif +} + +//=========================================================================== + +BOOST_AUTO_TEST_CASE( test_all_point_point ) +{ + test_distance_point_point(point_point_strategy()); + test_distance_point_point(point_point_strategy(earth_radius_km)); + test_distance_point_point(point_point_strategy(earth_radius_miles)); +} + +BOOST_AUTO_TEST_CASE( test_all_point_multipoint ) +{ + test_distance_point_multipoint(point_point_strategy()); + test_distance_point_multipoint(point_point_strategy(earth_radius_km)); + test_distance_point_multipoint(point_point_strategy(earth_radius_miles)); +} + +BOOST_AUTO_TEST_CASE( test_all_multipoint_multipoint ) +{ + test_distance_multipoint_multipoint(point_point_strategy()); + test_distance_multipoint_multipoint(point_point_strategy(earth_radius_km)); + test_distance_multipoint_multipoint(point_point_strategy(earth_radius_miles)); +} + +BOOST_AUTO_TEST_CASE( test_all_empty_input_pointlike_pointlike ) +{ + test_more_empty_input_pointlike_pointlike + < + point_type + >(point_point_strategy()); + + test_more_empty_input_pointlike_pointlike + < + point_type + >(point_point_strategy(earth_radius_km)); + + test_more_empty_input_pointlike_pointlike + < + point_type + >(point_point_strategy(earth_radius_miles)); +} diff --git a/test/algorithms/test_distance.hpp b/test/algorithms/distance/test_distance.hpp similarity index 100% rename from test/algorithms/test_distance.hpp rename to test/algorithms/distance/test_distance.hpp diff --git a/test/algorithms/test_distance_common.hpp b/test/algorithms/distance/test_distance_common.hpp similarity index 99% rename from test/algorithms/test_distance_common.hpp rename to test/algorithms/distance/test_distance_common.hpp index 31159e08b..62e87e368 100644 --- a/test/algorithms/test_distance_common.hpp +++ b/test/algorithms/distance/test_distance_common.hpp @@ -39,8 +39,7 @@ #include #include -#include "from_wkt.hpp" - +#include #include diff --git a/test/algorithms/distance/test_distance_se_common.hpp b/test/algorithms/distance/test_distance_se_common.hpp new file mode 100644 index 000000000..8294ea934 --- /dev/null +++ b/test/algorithms/distance/test_distance_se_common.hpp @@ -0,0 +1,573 @@ +// 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_GEOMETRY_TEST_DISTANCE_SE_COMMON_HPP +#define BOOST_GEOMETRY_TEST_DISTANCE_SE_COMMON_HPP + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + + +#ifndef BOOST_GEOMETRY_TEST_DISTANCE_HPP + +namespace bg = ::boost::geometry; + +static const double earth_radius_km = 6371.0; +static const double earth_radius_miles = 3959.0; + +// function copied from BG's test_distance.hpp + +template +void test_empty_input(Geometry1 const& geometry1, Geometry2 const& geometry2) +{ + try + { + bg::distance(geometry1, geometry2); + } + catch(bg::empty_input_exception const& ) + { + return; + } + BOOST_CHECK_MESSAGE(false, "A empty_input_exception should have been thrown" ); +} +#endif // BOOST_GEOMETRY_TEST_DISTANCE_HPP + + + +//======================================================================== + + + +template +< + typename PointLike1, + typename PointLike2, + typename Strategy, + typename Tag1 = typename bg::tag::type, + typename Tag2 = typename bg::tag::type +> +struct distance_brute_force +{}; + +template +< + typename PointLike1, + typename PointLike2, + typename Strategy +> +struct distance_brute_force +< + PointLike1, PointLike2, Strategy, + bg::point_tag, bg::point_tag +> +{ + typedef typename bg::distance_result + < + PointLike1, PointLike2, Strategy + >::type distance_type; + + static inline distance_type apply(PointLike1 const& p1, + PointLike2 const& p2, + Strategy const& strategy) + { + return bg::distance(p1, p2, strategy); + } +}; + +template +< + typename PointLike1, + typename PointLike2, + typename Strategy +> +struct distance_brute_force +< + PointLike1, PointLike2, Strategy, + bg::point_tag, bg::multi_point_tag +> +{ + typedef typename bg::distance_result + < + PointLike1, PointLike2, Strategy + >::type distance_type; + + static inline distance_type apply(PointLike1 const& p, + PointLike2 const& mp, + Strategy const& strategy) + { + typedef typename boost::range_iterator::type iterator; + + bool first = true; + distance_type d_min; + for (iterator it = boost::begin(mp); it != boost::end(mp); + ++it, first = false) + { + distance_type d = bg::distance(p, *it, strategy); + + if ( first || d < d_min ) + { + d_min = d; + } + } + return d_min; + } +}; + +template +< + typename PointLike1, + typename PointLike2, + typename Strategy +> +struct distance_brute_force +< + PointLike1, PointLike2, Strategy, + bg::multi_point_tag, bg::multi_point_tag +> +{ + typedef typename bg::distance_result + < + PointLike1, PointLike2, Strategy + >::type distance_type; + + static inline distance_type apply(PointLike1 const& mp1, + PointLike2 const& mp2, + Strategy const& strategy) + { + typedef typename boost::range_iterator + < + PointLike1 const + >::type iterator1; + + typedef typename boost::range_iterator + < + PointLike2 const + >::type iterator2; + + bool first = true; + distance_type d_min; + for (iterator1 it1 = boost::begin(mp1); it1 != boost::end(mp1); ++it1) + { + for (iterator2 it2 = boost::begin(mp2); it2 != boost::end(mp2); + ++it2, first = false) + { + distance_type d = bg::distance(*it1, *it2, strategy); + + if ( first || d < d_min ) + { + d_min = d; + } + } + } + return d_min; + } +}; + + + +//======================================================================== + + + +#ifdef BOOST_GEOMETRY_TEST_DEBUG +// pretty print geometry -- START +template +struct pretty_print_geometry_dispatch +{ + template + static inline Stream& apply(Geometry const& geometry, Stream& os) + { + os << bg::wkt(geometry); + return os; + } +}; + +template +struct pretty_print_geometry_dispatch +{ + template + static inline Stream& apply(Geometry const& geometry, Stream& os) + { + os << "SEGMENT" << bg::dsv(geometry); + return os; + } +}; + +template +struct pretty_print_geometry_dispatch +{ + template + static inline Stream& apply(Geometry const& geometry, Stream& os) + { + os << "BOX" << bg::dsv(geometry); + return os; + } +}; + + +template +struct pretty_print_geometry +{ + template + static inline Stream& apply(Geometry const& geometry, Stream& os) + { + return pretty_print_geometry_dispatch + < + Geometry, typename bg::tag::type + >::apply(geometry, os); + } +}; +// pretty print geometry -- END +#endif // BOOST_GEOMETRY_TEST_DEBUG + + +//======================================================================== + + +template +struct check_equal +{ + static inline void apply(T const& value1, T const& value2) + { + BOOST_CHECK( value1 == value2 ); + } +}; + +template <> +struct check_equal +{ + static inline void apply(double value1, double value2) + { + BOOST_CHECK_CLOSE( value1, value2, 0.0001 ); + } +}; + + +//======================================================================== + +template +< + typename Geometry1, typename Geometry2, + int id1 = bg::geometry_id::value, + int id2 = bg::geometry_id::value +> +struct test_distance_of_geometries + : public test_distance_of_geometries +{}; + + +template +struct test_distance_of_geometries +{ + template + < + typename DistanceType, + typename ComparableDistanceType, + typename Strategy + > + static inline + void apply(std::string const& wkt1, + std::string const& wkt2, + DistanceType const& expected_distance, + ComparableDistanceType const& expected_comparable_distance, + Strategy const& strategy, + bool test_reversed = true) + { + Geometry1 geometry1 = from_wkt(wkt1); + Geometry2 geometry2 = from_wkt(wkt2); + + apply(geometry1, geometry2, + expected_distance, expected_comparable_distance, + strategy, test_reversed); + } + + + template + < + typename DistanceType, + typename ComparableDistanceType, + typename Strategy + > + static inline + void apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + DistanceType const& expected_distance, + ComparableDistanceType const& expected_comparable_distance, + Strategy const& strategy, + bool test_reversed = true) + { +#ifdef BOOST_GEOMETRY_TEST_DEBUG + typedef pretty_print_geometry PPG1; + typedef pretty_print_geometry PPG2; + PPG1::apply(geometry1, std::cout); + std::cout << " - "; + PPG2::apply(geometry2, std::cout); + std::cout << std::endl; +#endif + typedef typename bg::default_distance_result + < + Geometry1, Geometry2 + >::type default_distance_result; + + typedef typename bg::strategy::distance::services::return_type + < + Strategy, Geometry1, Geometry2 + >::type distance_result_from_strategy; + + static const bool same_regular = boost::is_same + < + default_distance_result, + distance_result_from_strategy + >::type::value; + + BOOST_CHECK( same_regular ); + + + typedef typename bg::default_comparable_distance_result + < + Geometry1, Geometry2 + >::type default_comparable_distance_result; + + typedef typename bg::strategy::distance::services::return_type + < + typename bg::strategy::distance::services::comparable_type + < + Strategy + >::type, + Geometry1, + Geometry2 + >::type comparable_distance_result_from_strategy; + + static const bool same_comparable = boost::is_same + < + default_comparable_distance_result, + comparable_distance_result_from_strategy + >::type::value; + + BOOST_CHECK( same_comparable ); + + + // check distance with default strategy + default_distance_result dist_def = bg::distance(geometry1, geometry2); + + check_equal + < + default_distance_result + >::apply(dist_def, expected_distance); + + + // check distance with passed strategy + distance_result_from_strategy dist = + bg::distance(geometry1, geometry2, strategy); + + check_equal + < + default_distance_result + >::apply(dist, expected_distance * strategy.radius()); + + // check against the comparable distance computed in a + // brute-force manner + default_distance_result dist_brute_force = distance_brute_force + < + Geometry1, Geometry2, Strategy + >::apply(geometry1, geometry2, strategy); + + check_equal + < + default_distance_result + >::apply(dist_brute_force, expected_distance * strategy.radius()); + + + // check comparable distance with default strategy + default_comparable_distance_result cdist_def = + bg::comparable_distance(geometry1, geometry2); + + check_equal + < + default_comparable_distance_result + >::apply(cdist_def, expected_comparable_distance); + + + // check comparable distance with passed strategy + comparable_distance_result_from_strategy cdist = + bg::comparable_distance(geometry1, geometry2, strategy); + + check_equal + < + default_comparable_distance_result + >::apply(cdist, expected_comparable_distance); + + // check against the comparable distance computed in a + // brute-force manner + default_comparable_distance_result cdist_brute_force + = distance_brute_force + < + Geometry1, + Geometry2, + typename bg::strategy::distance::services::comparable_type + < + Strategy + >::type + >::apply(geometry1, + geometry2, + bg::strategy::distance::services::get_comparable + < + Strategy + >::apply(strategy)); + + check_equal + < + default_comparable_distance_result + >::apply(cdist_brute_force, expected_comparable_distance); + +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << string_from_type::type>::name() + << string_from_type::type>::name() + << " -> " + << string_from_type::name() + << string_from_type::name() + << std::endl; + std::cout << "expected distance (default strategy) = " + << expected_distance << " ; " + << "expected distance (passed strategy) = " + << (expected_distance * strategy.radius()) << " ; " + << "expected comp. distance = " + << expected_comparable_distance + << std::endl; + std::cout << "distance (default strategy) = " << dist_def << " ; " + << "distance (passed strategy) = " << dist << " ; " + << "comp. distance (default strategy) = " + << cdist_def << " ; " + << "comp. distance (passed strategy) = " + << cdist << std::endl; + + if ( !test_reversed ) + { + std::cout << std::endl; + } +#endif + + if ( test_reversed ) + { + // check distance with default strategy + dist_def = bg::distance(geometry2, geometry1); + + check_equal + < + default_distance_result + >::apply(dist_def, expected_distance); + + + // check distance with given strategy + dist = bg::distance(geometry2, geometry1, strategy); + + check_equal + < + default_distance_result + >::apply(dist, expected_distance * strategy.radius()); + + + // check comparable distance with default strategy + cdist_def = bg::comparable_distance(geometry2, geometry1); + + check_equal + < + default_comparable_distance_result + >::apply(cdist_def, expected_comparable_distance); + + // check comparable distance with given strategy + cdist = bg::comparable_distance(geometry2, geometry1, strategy); + + check_equal + < + default_comparable_distance_result + >::apply(cdist, expected_comparable_distance); + +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << "expected distance (default strategy) = " + << expected_distance << " ; " + << "expected distance (passed strategy) = " + << (expected_distance * strategy.radius()) << " ; " + << "expected comp. distance = " + << expected_comparable_distance + << std::endl; + std::cout << "distance[reversed args] (def. startegy) = " + << dist_def << " ; " + << "distance[reversed args] (passed startegy) = " + << dist << " ; " + << "comp. distance[reversed args] (def. strategy) = " + << cdist_def << " ; " + << "comp. distance[reversed args] (passed strategy) = " + << cdist << std::endl; + std::cout << std::endl; +#endif + } + } +}; + + +//======================================================================== + + +template +void test_empty_input(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) +{ + try + { + bg::distance(geometry1, geometry2, strategy); + } + catch(bg::empty_input_exception const& ) + { + return; + } + BOOST_CHECK_MESSAGE(false, "A empty_input_exception should have been thrown" ); + + try + { + bg::distance(geometry2, geometry1, strategy); + } + catch(bg::empty_input_exception const& ) + { + return; + } + BOOST_CHECK_MESSAGE(false, "A empty_input_exception should have been thrown" ); +} + +#endif // BOOST_GEOMETRY_TEST_DISTANCE_SE_COMMON_HPP diff --git a/test/algorithms/is_simple.cpp b/test/algorithms/is_simple.cpp index 63fac7bfa..34ec07e54 100644 --- a/test/algorithms/is_simple.cpp +++ b/test/algorithms/is_simple.cpp @@ -36,7 +36,7 @@ #include #include -#include "from_wkt.hpp" +#include #ifdef BOOST_GEOMETRY_TEST_DEBUG #include "pretty_print_geometry.hpp" diff --git a/test/algorithms/is_valid.cpp b/test/algorithms/is_valid.cpp index 2fc8402cb..60f98057d 100644 --- a/test/algorithms/is_valid.cpp +++ b/test/algorithms/is_valid.cpp @@ -16,7 +16,7 @@ #include -#include "from_wkt.hpp" +#include #include "test_is_valid.hpp" diff --git a/test/multi/algorithms/multi_area.cpp b/test/algorithms/multi_area.cpp similarity index 100% rename from test/multi/algorithms/multi_area.cpp rename to test/algorithms/multi_area.cpp diff --git a/test/multi/algorithms/multi_centroid.cpp b/test/algorithms/multi_centroid.cpp similarity index 100% rename from test/multi/algorithms/multi_centroid.cpp rename to test/algorithms/multi_centroid.cpp diff --git a/test/multi/algorithms/multi_clear.cpp b/test/algorithms/multi_clear.cpp similarity index 100% rename from test/multi/algorithms/multi_clear.cpp rename to test/algorithms/multi_clear.cpp diff --git a/test/multi/algorithms/multi_convert.cpp b/test/algorithms/multi_convert.cpp similarity index 100% rename from test/multi/algorithms/multi_convert.cpp rename to test/algorithms/multi_convert.cpp diff --git a/test/multi/algorithms/multi_convex_hull.cpp b/test/algorithms/multi_convex_hull.cpp similarity index 91% rename from test/multi/algorithms/multi_convex_hull.cpp rename to test/algorithms/multi_convex_hull.cpp index f27396529..4fe00633f 100644 --- a/test/multi/algorithms/multi_convex_hull.cpp +++ b/test/algorithms/multi_convex_hull.cpp @@ -5,6 +5,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. @@ -52,11 +57,11 @@ void test_all() test_geometry("MULTIPOINT((0 0),(5 0),(1 1),(4 1))", -1, 5, 4.0); test_geometry("MULTIPOINT((0 1),(5 1),(1 0),(4 0))", -1, 5, 4.0); - // All points in vertical line (this delivers an empty polygon with 2 points and a closing point) - test_geometry("MULTIPOINT((1 0),(5 0),(3 0),(4 0),(2 0))", -1, 3, 0.0); + // All points in vertical line (this delivers an empty polygon with 3 points and closing point for closed) + test_geometry("MULTIPOINT((1 0),(5 0),(3 0),(4 0),(2 0))", -1, 4, 0.0); // One point only - test_geometry("MULTIPOINT((1 0))", -1, 3, 0.0); + test_geometry("MULTIPOINT((1 0))", -1, 4, 0.0); // Problem of 6019, reproduced by the convex hull robustness test: test_geometry("MULTIPOINT((2 9),(1 3),(9 4),(1 1),(1 0),(7 9),(2 5),(3 7),(3 6),(2 4))", diff --git a/test/multi/algorithms/multi_correct.cpp b/test/algorithms/multi_correct.cpp similarity index 100% rename from test/multi/algorithms/multi_correct.cpp rename to test/algorithms/multi_correct.cpp diff --git a/test/multi/algorithms/multi_envelope.cpp b/test/algorithms/multi_envelope.cpp similarity index 100% rename from test/multi/algorithms/multi_envelope.cpp rename to test/algorithms/multi_envelope.cpp diff --git a/test/multi/algorithms/multi_for_each.cpp b/test/algorithms/multi_for_each.cpp similarity index 100% rename from test/multi/algorithms/multi_for_each.cpp rename to test/algorithms/multi_for_each.cpp diff --git a/test/multi/algorithms/multi_length.cpp b/test/algorithms/multi_length.cpp similarity index 100% rename from test/multi/algorithms/multi_length.cpp rename to test/algorithms/multi_length.cpp diff --git a/test/multi/algorithms/multi_num_geometries.cpp b/test/algorithms/multi_num_geometries.cpp similarity index 100% rename from test/multi/algorithms/multi_num_geometries.cpp rename to test/algorithms/multi_num_geometries.cpp diff --git a/test/multi/algorithms/multi_num_interior_rings.cpp b/test/algorithms/multi_num_interior_rings.cpp similarity index 100% rename from test/multi/algorithms/multi_num_interior_rings.cpp rename to test/algorithms/multi_num_interior_rings.cpp diff --git a/test/multi/algorithms/multi_num_points.cpp b/test/algorithms/multi_num_points.cpp similarity index 100% rename from test/multi/algorithms/multi_num_points.cpp rename to test/algorithms/multi_num_points.cpp diff --git a/test/multi/algorithms/multi_perimeter.cpp b/test/algorithms/multi_perimeter.cpp similarity index 100% rename from test/multi/algorithms/multi_perimeter.cpp rename to test/algorithms/multi_perimeter.cpp diff --git a/test/multi/algorithms/multi_reverse.cpp b/test/algorithms/multi_reverse.cpp similarity index 100% rename from test/multi/algorithms/multi_reverse.cpp rename to test/algorithms/multi_reverse.cpp diff --git a/test/multi/algorithms/multi_simplify.cpp b/test/algorithms/multi_simplify.cpp similarity index 100% rename from test/multi/algorithms/multi_simplify.cpp rename to test/algorithms/multi_simplify.cpp diff --git a/test/multi/algorithms/multi_transform.cpp b/test/algorithms/multi_transform.cpp similarity index 100% rename from test/multi/algorithms/multi_transform.cpp rename to test/algorithms/multi_transform.cpp diff --git a/test/multi/algorithms/multi_unique.cpp b/test/algorithms/multi_unique.cpp similarity index 100% rename from test/multi/algorithms/multi_unique.cpp rename to test/algorithms/multi_unique.cpp diff --git a/test/algorithms/overlay/Jamfile.v2 b/test/algorithms/overlay/Jamfile.v2 index 9319330e9..2d736874b 100644 --- a/test/algorithms/overlay/Jamfile.v2 +++ b/test/algorithms/overlay/Jamfile.v2 @@ -21,6 +21,7 @@ test-suite boost-geometry-algorithms-overlay [ run get_turns.cpp ] [ run get_turns_linear_linear.cpp ] [ run get_turns_linear_areal.cpp ] + [ run multi_traverse.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE BOOST_GEOMETRY_RESCALE_TO_ROBUST ] [ run relative_order.cpp ] [ run select_rings.cpp ] [ run self_intersection_points.cpp ] diff --git a/test/algorithms/overlay/get_turns_linear_areal.cpp b/test/algorithms/overlay/get_turns_linear_areal.cpp index 202eb28ed..b270edeb6 100644 --- a/test/algorithms/overlay/get_turns_linear_areal.cpp +++ b/test/algorithms/overlay/get_turns_linear_areal.cpp @@ -21,7 +21,7 @@ #include //TEST -//#include "to_svg.hpp" +//#include template void test_all() diff --git a/test/multi/algorithms/overlay/multi_overlay_cases.hpp b/test/algorithms/overlay/multi_overlay_cases.hpp similarity index 100% rename from test/multi/algorithms/overlay/multi_overlay_cases.hpp rename to test/algorithms/overlay/multi_overlay_cases.hpp diff --git a/test/multi/algorithms/overlay/multi_overlay_common.hpp b/test/algorithms/overlay/multi_overlay_common.hpp similarity index 100% rename from test/multi/algorithms/overlay/multi_overlay_common.hpp rename to test/algorithms/overlay/multi_overlay_common.hpp diff --git a/test/multi/algorithms/overlay/multi_traverse.cpp b/test/algorithms/overlay/multi_traverse.cpp similarity index 100% rename from test/multi/algorithms/overlay/multi_traverse.cpp rename to test/algorithms/overlay/multi_traverse.cpp diff --git a/test/algorithms/point_on_surface.cpp b/test/algorithms/point_on_surface.cpp index 3959b4114..00b6f1236 100644 --- a/test/algorithms/point_on_surface.cpp +++ b/test/algorithms/point_on_surface.cpp @@ -138,7 +138,6 @@ void test_geometry(std::string const& case_id, std::string const& wkt, double ex template void test_point_order_and_type() { - typedef bg::model::polygon polygon; typedef bg::model::polygon ccw_open_polygon; typedef bg::model::polygon cw_open_polygon; typedef bg::model::polygon ccw_closed_polygon; diff --git a/test/algorithms/relational_operations/Jamfile.v2 b/test/algorithms/relational_operations/Jamfile.v2 new file mode 100644 index 000000000..5b432e2e9 --- /dev/null +++ b/test/algorithms/relational_operations/Jamfile.v2 @@ -0,0 +1,33 @@ +# Boost.Geometry (aka GGL, Generic Geometry Library) +# +# Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. +# Copyright (c) 2008-2014 Bruno Lalande, Paris, France. +# Copyright (c) 2009-2014 Mateusz Loskot, London, UK. +# +# This file was modified by Oracle on 2014. +# 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 +# http://www.boost.org/LICENSE_1_0.txt) + +test-suite boost-geometry-algorithms-relational + : + [ run covered_by.cpp : : : msvc:/bigobj ] + [ run crosses.cpp : : : msvc:/bigobj ] + [ run equals.cpp : : : msvc:/bigobj ] + [ run intersects.cpp : : : msvc:/bigobj ] + [ run multi_covered_by.cpp : : : msvc:/bigobj ] + [ run multi_equals.cpp : : : msvc:/bigobj ] + [ run multi_intersects.cpp : : : msvc:/bigobj ] + [ run multi_touches.cpp : : : msvc:/bigobj ] + [ run overlaps.cpp : : : msvc:/bigobj ] + [ run touches.cpp : : : msvc:/bigobj ] + ; + +build-project disjoint ; +build-project relate ; +build-project within ; diff --git a/test/algorithms/covered_by.cpp b/test/algorithms/relational_operations/covered_by.cpp similarity index 99% rename from test/algorithms/covered_by.cpp rename to test/algorithms/relational_operations/covered_by.cpp index b4a00ea89..15031487a 100644 --- a/test/algorithms/covered_by.cpp +++ b/test/algorithms/relational_operations/covered_by.cpp @@ -7,7 +7,7 @@ // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include "test_covered_by.hpp" #include diff --git a/test/algorithms/crosses.cpp b/test/algorithms/relational_operations/crosses.cpp similarity index 98% rename from test/algorithms/crosses.cpp rename to test/algorithms/relational_operations/crosses.cpp index 103791018..62cb9146e 100644 --- a/test/algorithms/crosses.cpp +++ b/test/algorithms/relational_operations/crosses.cpp @@ -11,7 +11,7 @@ // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle -#include +#include "test_crosses.hpp" template void test_pl() diff --git a/test/algorithms/relational_operations/disjoint/Jamfile.v2 b/test/algorithms/relational_operations/disjoint/Jamfile.v2 new file mode 100644 index 000000000..a2423a745 --- /dev/null +++ b/test/algorithms/relational_operations/disjoint/Jamfile.v2 @@ -0,0 +1,22 @@ +# Boost.Geometry (aka GGL, Generic Geometry Library) +# +# Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. +# Copyright (c) 2008-2014 Bruno Lalande, Paris, France. +# Copyright (c) 2009-2014 Mateusz Loskot, London, UK. +# +# This file was modified by Oracle on 2014. +# 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 +# http://www.boost.org/LICENSE_1_0.txt) + +test-suite boost-geometry-algorithms-disjoint + : + [ run disjoint.cpp : : : msvc:/bigobj ] + [ run disjoint_coverage.cpp : : : msvc:/bigobj ] + [ run multi_disjoint.cpp : : : msvc:/bigobj ] + ; diff --git a/test/algorithms/disjoint.cpp b/test/algorithms/relational_operations/disjoint/disjoint.cpp similarity index 99% rename from test/algorithms/disjoint.cpp rename to test/algorithms/relational_operations/disjoint/disjoint.cpp index d765ef952..67a0f90a0 100644 --- a/test/algorithms/disjoint.cpp +++ b/test/algorithms/relational_operations/disjoint/disjoint.cpp @@ -13,7 +13,7 @@ // http://www.boost.org/LICENSE_1_0.txt) -#include +#include "test_disjoint.hpp" #include #include diff --git a/test/algorithms/disjoint_coverage.cpp b/test/algorithms/relational_operations/disjoint/disjoint_coverage.cpp similarity index 97% rename from test/algorithms/disjoint_coverage.cpp rename to test/algorithms/relational_operations/disjoint/disjoint_coverage.cpp index 5ce46ee32..7a19c0455 100644 --- a/test/algorithms/disjoint_coverage.cpp +++ b/test/algorithms/relational_operations/disjoint/disjoint_coverage.cpp @@ -41,7 +41,7 @@ #include -#include "from_wkt.hpp" +#include #ifdef HAVE_TTMATH @@ -1181,6 +1181,28 @@ inline void test_polygon_polygon() tester::apply(from_wkt("POLYGON((3 3,3 4,4 4,4 3))"), from_wkt("POLYGON((0 0,2 0,2 2,0 2))"), true); + + tester::apply(from_wkt("POLYGON((0 0,9 0,9 9,0 9))"), + from_wkt("POLYGON((3 3,6 3,6 6,3 6))"), + false); + // polygon with a hole which entirely contains the other polygon + tester::apply(from_wkt("POLYGON((0 0,9 0,9 9,0 9),(2 2,2 7,7 7,7 2))"), + from_wkt("POLYGON((3 3,6 3,6 6,3 6))"), + true); + // polygon with a hole, but the inner ring intersects the other polygon + tester::apply(from_wkt("POLYGON((0 0,9 0,9 9,0 9),(3 2,3 7,7 7,7 2))"), + from_wkt("POLYGON((2 3,6 3,6 6,2 6))"), + false); + // polygon with a hole, but the other polygon is entirely contained + // between the inner and outer rings. + tester::apply(from_wkt("POLYGON((0 0,9 0,9 9,0 9),(6 2,6 7,7 7,7 2))"), + from_wkt("POLYGON((3 3,5 3,5 6,3 6))"), + false); + // polygon with a hole and the outer ring of the other polygon lies + // between the inner and outer, but without touching either. + tester::apply(from_wkt("POLYGON((0 0,9 0,9 9,0 9),(3 3,3 6,6 6,6 3))"), + from_wkt("POLYGON((2 2,7 2,7 7,2 7))"), + false); } template diff --git a/test/multi/algorithms/multi_disjoint.cpp b/test/algorithms/relational_operations/disjoint/multi_disjoint.cpp similarity index 99% rename from test/multi/algorithms/multi_disjoint.cpp rename to test/algorithms/relational_operations/disjoint/multi_disjoint.cpp index 05cd985e3..bba5823cd 100644 --- a/test/multi/algorithms/multi_disjoint.cpp +++ b/test/algorithms/relational_operations/disjoint/multi_disjoint.cpp @@ -8,7 +8,7 @@ // http://www.boost.org/LICENSE_1_0.txt) -#include +#include "test_disjoint.hpp" #include diff --git a/test/algorithms/test_disjoint.hpp b/test/algorithms/relational_operations/disjoint/test_disjoint.hpp similarity index 100% rename from test/algorithms/test_disjoint.hpp rename to test/algorithms/relational_operations/disjoint/test_disjoint.hpp diff --git a/test/algorithms/equals.cpp b/test/algorithms/relational_operations/equals.cpp similarity index 99% rename from test/algorithms/equals.cpp rename to test/algorithms/relational_operations/equals.cpp index 1ee21ec22..8aa8fd30e 100644 --- a/test/algorithms/equals.cpp +++ b/test/algorithms/relational_operations/equals.cpp @@ -11,7 +11,7 @@ // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include "test_equals.hpp" #include #include diff --git a/test/algorithms/intersects.cpp b/test/algorithms/relational_operations/intersects.cpp similarity index 99% rename from test/algorithms/intersects.cpp rename to test/algorithms/relational_operations/intersects.cpp index 82bd0fe8e..01b2f73e5 100644 --- a/test/algorithms/intersects.cpp +++ b/test/algorithms/relational_operations/intersects.cpp @@ -10,7 +10,7 @@ // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include "test_intersects.hpp" #include diff --git a/test/multi/algorithms/multi_covered_by.cpp b/test/algorithms/relational_operations/multi_covered_by.cpp similarity index 97% rename from test/multi/algorithms/multi_covered_by.cpp rename to test/algorithms/relational_operations/multi_covered_by.cpp index df40109e5..7489435b4 100644 --- a/test/multi/algorithms/multi_covered_by.cpp +++ b/test/algorithms/relational_operations/multi_covered_by.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include "test_covered_by.hpp" template diff --git a/test/multi/algorithms/multi_equals.cpp b/test/algorithms/relational_operations/multi_equals.cpp similarity index 97% rename from test/multi/algorithms/multi_equals.cpp rename to test/algorithms/relational_operations/multi_equals.cpp index 64bc0d470..d1239d38f 100644 --- a/test/multi/algorithms/multi_equals.cpp +++ b/test/algorithms/relational_operations/multi_equals.cpp @@ -6,7 +6,7 @@ // http://www.boost.org/LICENSE_1_0.txt) -#include +#include "test_equals.hpp" #include #include diff --git a/test/multi/algorithms/multi_intersects.cpp b/test/algorithms/relational_operations/multi_intersects.cpp similarity index 96% rename from test/multi/algorithms/multi_intersects.cpp rename to test/algorithms/relational_operations/multi_intersects.cpp index d07b8b6cf..1880064f8 100644 --- a/test/multi/algorithms/multi_intersects.cpp +++ b/test/algorithms/relational_operations/multi_intersects.cpp @@ -13,7 +13,7 @@ #include -#include +#include "test_intersects.hpp" #include diff --git a/test/multi/algorithms/multi_touches.cpp b/test/algorithms/relational_operations/multi_touches.cpp similarity index 98% rename from test/multi/algorithms/multi_touches.cpp rename to test/algorithms/relational_operations/multi_touches.cpp index 8774beaf2..86456b04a 100644 --- a/test/multi/algorithms/multi_touches.cpp +++ b/test/algorithms/relational_operations/multi_touches.cpp @@ -6,7 +6,7 @@ // http://www.boost.org/LICENSE_1_0.txt) -#include +#include "test_touches.hpp" #include #include diff --git a/test/algorithms/overlaps.cpp b/test/algorithms/relational_operations/overlaps.cpp similarity index 98% rename from test/algorithms/overlaps.cpp rename to test/algorithms/relational_operations/overlaps.cpp index 14c615e25..594cb1084 100644 --- a/test/algorithms/overlaps.cpp +++ b/test/algorithms/relational_operations/overlaps.cpp @@ -11,7 +11,7 @@ // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle -#include +#include "test_overlaps.hpp" template void test_box_box_2d() diff --git a/test/algorithms/relational_operations/relate/Jamfile.v2 b/test/algorithms/relational_operations/relate/Jamfile.v2 new file mode 100644 index 000000000..871b8eb17 --- /dev/null +++ b/test/algorithms/relational_operations/relate/Jamfile.v2 @@ -0,0 +1,23 @@ +# Boost.Geometry (aka GGL, Generic Geometry Library) +# +# Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. +# Copyright (c) 2008-2014 Bruno Lalande, Paris, France. +# Copyright (c) 2009-2014 Mateusz Loskot, London, UK. +# +# This file was modified by Oracle on 2014. +# 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 +# http://www.boost.org/LICENSE_1_0.txt) + +test-suite boost-geometry-algorithms-relate + : + [ run relate_areal_areal.cpp : : : msvc:/bigobj ] + [ run relate_linear_areal.cpp : : : msvc:/bigobj ] + [ run relate_linear_linear.cpp : : : msvc:/bigobj ] + [ run relate_pointlike_xxx.cpp : : : msvc:/bigobj ] + ; diff --git a/test/algorithms/relate_areal_areal.cpp b/test/algorithms/relational_operations/relate/relate_areal_areal.cpp similarity index 99% rename from test/algorithms/relate_areal_areal.cpp rename to test/algorithms/relational_operations/relate/relate_areal_areal.cpp index fd9e84c40..0e8d95339 100644 --- a/test/algorithms/relate_areal_areal.cpp +++ b/test/algorithms/relational_operations/relate/relate_areal_areal.cpp @@ -11,7 +11,7 @@ // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle -#include +#include "test_relate.hpp" //TEST //#include diff --git a/test/algorithms/relate_linear_areal.cpp b/test/algorithms/relational_operations/relate/relate_linear_areal.cpp similarity index 99% rename from test/algorithms/relate_linear_areal.cpp rename to test/algorithms/relational_operations/relate/relate_linear_areal.cpp index 0096a01aa..09fd7c4dd 100644 --- a/test/algorithms/relate_linear_areal.cpp +++ b/test/algorithms/relational_operations/relate/relate_linear_areal.cpp @@ -11,7 +11,7 @@ // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle -#include +#include "test_relate.hpp" //TEST //#include diff --git a/test/algorithms/relate_linear_linear.cpp b/test/algorithms/relational_operations/relate/relate_linear_linear.cpp similarity index 99% rename from test/algorithms/relate_linear_linear.cpp rename to test/algorithms/relational_operations/relate/relate_linear_linear.cpp index f847db6fd..d1b43bb48 100644 --- a/test/algorithms/relate_linear_linear.cpp +++ b/test/algorithms/relational_operations/relate/relate_linear_linear.cpp @@ -11,7 +11,7 @@ // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle -#include +#include "test_relate.hpp" //TEST //#include diff --git a/test/algorithms/relate_pointlike_xxx.cpp b/test/algorithms/relational_operations/relate/relate_pointlike_xxx.cpp similarity index 99% rename from test/algorithms/relate_pointlike_xxx.cpp rename to test/algorithms/relational_operations/relate/relate_pointlike_xxx.cpp index 02d1fd84e..f9314454f 100644 --- a/test/algorithms/relate_pointlike_xxx.cpp +++ b/test/algorithms/relational_operations/relate/relate_pointlike_xxx.cpp @@ -11,7 +11,7 @@ // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle -#include +#include "test_relate.hpp" //TEST //#include diff --git a/test/algorithms/test_relate.hpp b/test/algorithms/relational_operations/relate/test_relate.hpp similarity index 100% rename from test/algorithms/test_relate.hpp rename to test/algorithms/relational_operations/relate/test_relate.hpp diff --git a/test/algorithms/test_covered_by.hpp b/test/algorithms/relational_operations/test_covered_by.hpp similarity index 100% rename from test/algorithms/test_covered_by.hpp rename to test/algorithms/relational_operations/test_covered_by.hpp diff --git a/test/algorithms/test_crosses.hpp b/test/algorithms/relational_operations/test_crosses.hpp similarity index 100% rename from test/algorithms/test_crosses.hpp rename to test/algorithms/relational_operations/test_crosses.hpp diff --git a/test/algorithms/test_equals.hpp b/test/algorithms/relational_operations/test_equals.hpp similarity index 100% rename from test/algorithms/test_equals.hpp rename to test/algorithms/relational_operations/test_equals.hpp diff --git a/test/algorithms/test_intersects.hpp b/test/algorithms/relational_operations/test_intersects.hpp similarity index 100% rename from test/algorithms/test_intersects.hpp rename to test/algorithms/relational_operations/test_intersects.hpp diff --git a/test/algorithms/test_overlaps.hpp b/test/algorithms/relational_operations/test_overlaps.hpp similarity index 100% rename from test/algorithms/test_overlaps.hpp rename to test/algorithms/relational_operations/test_overlaps.hpp diff --git a/test/algorithms/test_touches.hpp b/test/algorithms/relational_operations/test_touches.hpp similarity index 100% rename from test/algorithms/test_touches.hpp rename to test/algorithms/relational_operations/test_touches.hpp diff --git a/test/algorithms/touches.cpp b/test/algorithms/relational_operations/touches.cpp similarity index 99% rename from test/algorithms/touches.cpp rename to test/algorithms/relational_operations/touches.cpp index 451233ef3..d7a92c8e0 100644 --- a/test/algorithms/touches.cpp +++ b/test/algorithms/relational_operations/touches.cpp @@ -11,7 +11,7 @@ // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle -#include +#include "test_touches.hpp" template void test_all() diff --git a/test/algorithms/relational_operations/within/Jamfile.v2 b/test/algorithms/relational_operations/within/Jamfile.v2 new file mode 100644 index 000000000..d2a679571 --- /dev/null +++ b/test/algorithms/relational_operations/within/Jamfile.v2 @@ -0,0 +1,25 @@ +# Boost.Geometry (aka GGL, Generic Geometry Library) +# +# Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. +# Copyright (c) 2008-2014 Bruno Lalande, Paris, France. +# Copyright (c) 2009-2014 Mateusz Loskot, London, UK. +# +# This file was modified by Oracle on 2014. +# 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 +# http://www.boost.org/LICENSE_1_0.txt) + +test-suite boost-geometry-algorithms-within + : + [ run multi_within.cpp : : : msvc:/bigobj ] + [ run within.cpp : : : msvc:/bigobj ] + [ run within_areal_areal.cpp : : : msvc:/bigobj ] + [ run within_linear_areal.cpp : : : msvc:/bigobj ] + [ run within_linear_linear.cpp : : : msvc:/bigobj ] + [ run within_pointlike_xxx.cpp : : : msvc:/bigobj ] + ; diff --git a/test/multi/algorithms/multi_within.cpp b/test/algorithms/relational_operations/within/multi_within.cpp similarity index 98% rename from test/multi/algorithms/multi_within.cpp rename to test/algorithms/relational_operations/within/multi_within.cpp index 59db2dbc6..cf5573aa6 100644 --- a/test/multi/algorithms/multi_within.cpp +++ b/test/algorithms/relational_operations/within/multi_within.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include "test_within.hpp" template diff --git a/test/algorithms/test_within.hpp b/test/algorithms/relational_operations/within/test_within.hpp similarity index 100% rename from test/algorithms/test_within.hpp rename to test/algorithms/relational_operations/within/test_within.hpp diff --git a/test/algorithms/within.cpp b/test/algorithms/relational_operations/within/within.cpp similarity index 99% rename from test/algorithms/within.cpp rename to test/algorithms/relational_operations/within/within.cpp index 6abdce19b..2300a4ec5 100644 --- a/test/algorithms/within.cpp +++ b/test/algorithms/relational_operations/within/within.cpp @@ -12,7 +12,7 @@ // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle -#include +#include "test_within.hpp" #include diff --git a/test/algorithms/within_areal_areal.cpp b/test/algorithms/relational_operations/within/within_areal_areal.cpp similarity index 98% rename from test/algorithms/within_areal_areal.cpp rename to test/algorithms/relational_operations/within/within_areal_areal.cpp index 57f417d95..5e8673c8c 100644 --- a/test/algorithms/within_areal_areal.cpp +++ b/test/algorithms/relational_operations/within/within_areal_areal.cpp @@ -12,7 +12,7 @@ // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle -#include +#include "test_within.hpp" #include diff --git a/test/algorithms/within_linear_areal.cpp b/test/algorithms/relational_operations/within/within_linear_areal.cpp similarity index 98% rename from test/algorithms/within_linear_areal.cpp rename to test/algorithms/relational_operations/within/within_linear_areal.cpp index 68f9ce396..412dbd051 100644 --- a/test/algorithms/within_linear_areal.cpp +++ b/test/algorithms/relational_operations/within/within_linear_areal.cpp @@ -12,7 +12,7 @@ // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle -#include +#include "test_within.hpp" #include diff --git a/test/algorithms/within_linear_linear.cpp b/test/algorithms/relational_operations/within/within_linear_linear.cpp similarity index 99% rename from test/algorithms/within_linear_linear.cpp rename to test/algorithms/relational_operations/within/within_linear_linear.cpp index bf77d4cb8..6467e0110 100644 --- a/test/algorithms/within_linear_linear.cpp +++ b/test/algorithms/relational_operations/within/within_linear_linear.cpp @@ -12,7 +12,7 @@ // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle -#include +#include "test_within.hpp" #include diff --git a/test/algorithms/within_pointlike_xxx.cpp b/test/algorithms/relational_operations/within/within_pointlike_xxx.cpp similarity index 99% rename from test/algorithms/within_pointlike_xxx.cpp rename to test/algorithms/relational_operations/within/within_pointlike_xxx.cpp index 392ee5f78..5ea4f09f2 100644 --- a/test/algorithms/within_pointlike_xxx.cpp +++ b/test/algorithms/relational_operations/within/within_pointlike_xxx.cpp @@ -12,7 +12,7 @@ // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle -#include +#include "test_within.hpp" #include diff --git a/test/algorithms/set_operations/Jamfile.v2 b/test/algorithms/set_operations/Jamfile.v2 new file mode 100644 index 000000000..27ebad64b --- /dev/null +++ b/test/algorithms/set_operations/Jamfile.v2 @@ -0,0 +1,20 @@ +# Boost.Geometry (aka GGL, Generic Geometry Library) +# +# Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. +# Copyright (c) 2008-2014 Bruno Lalande, Paris, France. +# Copyright (c) 2009-2014 Mateusz Loskot, London, UK. +# +# This file was modified by Oracle on 2014. +# 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 +# http://www.boost.org/LICENSE_1_0.txt) + +build-project difference ; +build-project intersection ; +build-project sym_difference ; +build-project union ; diff --git a/test/algorithms/set_operations/difference/Jamfile.v2 b/test/algorithms/set_operations/difference/Jamfile.v2 new file mode 100644 index 000000000..2903d9cc5 --- /dev/null +++ b/test/algorithms/set_operations/difference/Jamfile.v2 @@ -0,0 +1,24 @@ +# Boost.Geometry (aka GGL, Generic Geometry Library) +# +# Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. +# Copyright (c) 2008-2014 Bruno Lalande, Paris, France. +# Copyright (c) 2009-2014 Mateusz Loskot, London, UK. +# +# This file was modified by Oracle on 2014. +# 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 +# http://www.boost.org/LICENSE_1_0.txt) + +test-suite boost-geometry-algorithms-difference + : + [ run difference.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE msvc:/bigobj ] + [ run difference_linear_linear.cpp ] + [ run difference_pl_pl.cpp ] + [ run multi_difference.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE msvc:/bigobj ] + [ run multi_difference_spike.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE msvc:/bigobj ] + ; diff --git a/test/algorithms/difference.cpp b/test/algorithms/set_operations/difference/difference.cpp similarity index 99% rename from test/algorithms/difference.cpp rename to test/algorithms/set_operations/difference/difference.cpp index 6f83aef4a..a54316beb 100644 --- a/test/algorithms/difference.cpp +++ b/test/algorithms/set_operations/difference/difference.cpp @@ -25,10 +25,10 @@ #include -#include +#include "test_difference.hpp" #include #include -#include +#include #include diff --git a/test/algorithms/difference_linear_linear.cpp b/test/algorithms/set_operations/difference/difference_linear_linear.cpp similarity index 100% rename from test/algorithms/difference_linear_linear.cpp rename to test/algorithms/set_operations/difference/difference_linear_linear.cpp diff --git a/test/algorithms/difference_pl_pl.cpp b/test/algorithms/set_operations/difference/difference_pl_pl.cpp similarity index 99% rename from test/algorithms/difference_pl_pl.cpp rename to test/algorithms/set_operations/difference/difference_pl_pl.cpp index 3030dea4e..14a80f485 100644 --- a/test/algorithms/difference_pl_pl.cpp +++ b/test/algorithms/set_operations/difference/difference_pl_pl.cpp @@ -20,7 +20,7 @@ #include -#include "test_set_ops_pl_pl.hpp" +#include "../test_set_ops_pl_pl.hpp" #include diff --git a/test/multi/algorithms/multi_difference.cpp b/test/algorithms/set_operations/difference/multi_difference.cpp similarity index 98% rename from test/multi/algorithms/multi_difference.cpp rename to test/algorithms/set_operations/difference/multi_difference.cpp index 310931b56..f9e0c3d4d 100644 --- a/test/multi/algorithms/multi_difference.cpp +++ b/test/algorithms/set_operations/difference/multi_difference.cpp @@ -23,9 +23,9 @@ //#define BOOST_GEOMETRY_DEBUG_TRAVERSE -#include +#include "test_difference.hpp" #include -#include +#include #include #include diff --git a/test/multi/algorithms/multi_difference_spike.cpp b/test/algorithms/set_operations/difference/multi_difference_spike.cpp similarity index 99% rename from test/multi/algorithms/multi_difference_spike.cpp rename to test/algorithms/set_operations/difference/multi_difference_spike.cpp index 6753a2380..56a909262 100644 --- a/test/multi/algorithms/multi_difference_spike.cpp +++ b/test/algorithms/set_operations/difference/multi_difference_spike.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include "test_difference.hpp" template diff --git a/test/algorithms/test_difference.hpp b/test/algorithms/set_operations/difference/test_difference.hpp similarity index 99% rename from test/algorithms/test_difference.hpp rename to test/algorithms/set_operations/difference/test_difference.hpp index f97c6860f..e3cda5d95 100644 --- a/test/algorithms/test_difference.hpp +++ b/test/algorithms/set_operations/difference/test_difference.hpp @@ -50,6 +50,8 @@ template void difference_output(std::string const& caseid, G1 const& g1, G2 const& g2, Output const& output) { + boost::ignore_unused(caseid, g1, g2, output); + #if defined(TEST_WITH_SVG) { typedef typename bg::coordinate_type::type coordinate_type; diff --git a/test/algorithms/test_difference_linear_linear.hpp b/test/algorithms/set_operations/difference/test_difference_linear_linear.hpp similarity index 98% rename from test/algorithms/test_difference_linear_linear.hpp rename to test/algorithms/set_operations/difference/test_difference_linear_linear.hpp index cf86124a3..daa037151 100644 --- a/test/algorithms/test_difference_linear_linear.hpp +++ b/test/algorithms/set_operations/difference/test_difference_linear_linear.hpp @@ -10,10 +10,10 @@ #ifndef BOOST_GEOMETRY_TEST_DIFFERENCE_LINEAR_LINEAR_HPP #define BOOST_GEOMETRY_TEST_DIFFERENCE_LINEAR_LINEAR_HPP -#include "from_wkt.hpp" #include -#include "test_set_ops_linear_linear.hpp" -#include "to_svg.hpp" +#include "../test_set_ops_linear_linear.hpp" +#include +#include //================================================================== diff --git a/test/algorithms/set_operations/intersection/Jamfile.v2 b/test/algorithms/set_operations/intersection/Jamfile.v2 new file mode 100644 index 000000000..c039b1664 --- /dev/null +++ b/test/algorithms/set_operations/intersection/Jamfile.v2 @@ -0,0 +1,23 @@ +# Boost.Geometry (aka GGL, Generic Geometry Library) +# +# Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. +# Copyright (c) 2008-2014 Bruno Lalande, Paris, France. +# Copyright (c) 2009-2014 Mateusz Loskot, London, UK. +# +# This file was modified by Oracle on 2014. +# 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 +# http://www.boost.org/LICENSE_1_0.txt) + +test-suite boost-geometry-algorithms-intersection + : + [ run intersection.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE msvc:/bigobj ] + [ run intersection_linear_linear.cpp ] + [ run intersection_pl_pl.cpp ] + [ run multi_intersection.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE msvc:/bigobj ] + ; diff --git a/test/algorithms/intersection.cpp b/test/algorithms/set_operations/intersection/intersection.cpp similarity index 99% rename from test/algorithms/intersection.cpp rename to test/algorithms/set_operations/intersection/intersection.cpp index cefdb8ec9..85b266a9f 100644 --- a/test/algorithms/intersection.cpp +++ b/test/algorithms/set_operations/intersection/intersection.cpp @@ -26,7 +26,7 @@ #include -#include +#include "test_intersection.hpp" #include #include diff --git a/test/algorithms/intersection_linear_linear.cpp b/test/algorithms/set_operations/intersection/intersection_linear_linear.cpp similarity index 100% rename from test/algorithms/intersection_linear_linear.cpp rename to test/algorithms/set_operations/intersection/intersection_linear_linear.cpp diff --git a/test/algorithms/intersection_pl_pl.cpp b/test/algorithms/set_operations/intersection/intersection_pl_pl.cpp similarity index 99% rename from test/algorithms/intersection_pl_pl.cpp rename to test/algorithms/set_operations/intersection/intersection_pl_pl.cpp index da5617b92..27b592e7a 100644 --- a/test/algorithms/intersection_pl_pl.cpp +++ b/test/algorithms/set_operations/intersection/intersection_pl_pl.cpp @@ -20,7 +20,7 @@ #include -#include "test_set_ops_pl_pl.hpp" +#include "../test_set_ops_pl_pl.hpp" #include diff --git a/test/algorithms/intersection_segment.cpp b/test/algorithms/set_operations/intersection/intersection_segment.cpp similarity index 100% rename from test/algorithms/intersection_segment.cpp rename to test/algorithms/set_operations/intersection/intersection_segment.cpp diff --git a/test/multi/algorithms/multi_intersection.cpp b/test/algorithms/set_operations/intersection/multi_intersection.cpp similarity index 98% rename from test/multi/algorithms/multi_intersection.cpp rename to test/algorithms/set_operations/intersection/multi_intersection.cpp index 8dea0da23..46106022d 100644 --- a/test/multi/algorithms/multi_intersection.cpp +++ b/test/algorithms/set_operations/intersection/multi_intersection.cpp @@ -16,9 +16,9 @@ // #define BOOST_GEOMETRY_DEBUG_ASSEMBLE -#include +#include "test_intersection.hpp" #include -#include +#include #include #include diff --git a/test/algorithms/test_intersection.hpp b/test/algorithms/set_operations/intersection/test_intersection.hpp similarity index 100% rename from test/algorithms/test_intersection.hpp rename to test/algorithms/set_operations/intersection/test_intersection.hpp diff --git a/test/algorithms/test_intersection_linear_linear.hpp b/test/algorithms/set_operations/intersection/test_intersection_linear_linear.hpp similarity index 98% rename from test/algorithms/test_intersection_linear_linear.hpp rename to test/algorithms/set_operations/intersection/test_intersection_linear_linear.hpp index b02aaa35e..bc378f932 100644 --- a/test/algorithms/test_intersection_linear_linear.hpp +++ b/test/algorithms/set_operations/intersection/test_intersection_linear_linear.hpp @@ -10,11 +10,11 @@ #ifndef BOOST_GEOMETRY_TEST_INTERSECTION_LINEAR_LINEAR_HPP #define BOOST_GEOMETRY_TEST_INTERSECTION_LINEAR_LINEAR_HPP -#include "from_wkt.hpp" #include #include -#include "test_set_ops_linear_linear.hpp" -#include "to_svg.hpp" +#include "../test_set_ops_linear_linear.hpp" +#include +#include //================================================================== diff --git a/test/algorithms/set_ops_ll.cpp b/test/algorithms/set_operations/set_ops_ll.cpp similarity index 100% rename from test/algorithms/set_ops_ll.cpp rename to test/algorithms/set_operations/set_ops_ll.cpp diff --git a/test/algorithms/set_ops_pp.cpp b/test/algorithms/set_operations/set_ops_pp.cpp similarity index 100% rename from test/algorithms/set_ops_pp.cpp rename to test/algorithms/set_operations/set_ops_pp.cpp diff --git a/test/algorithms/set_operations/sym_difference/Jamfile.v2 b/test/algorithms/set_operations/sym_difference/Jamfile.v2 new file mode 100644 index 000000000..f64bb92ba --- /dev/null +++ b/test/algorithms/set_operations/sym_difference/Jamfile.v2 @@ -0,0 +1,20 @@ +# Boost.Geometry (aka GGL, Generic Geometry Library) +# +# Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. +# Copyright (c) 2008-2014 Bruno Lalande, Paris, France. +# Copyright (c) 2009-2014 Mateusz Loskot, London, UK. +# +# This file was modified by Oracle on 2014. +# 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 +# http://www.boost.org/LICENSE_1_0.txt) + +test-suite boost-geometry-algorithms-sym_difference + : + [ run sym_difference_linear_linear.cpp ] + ; diff --git a/test/algorithms/sym_difference_linear_linear.cpp b/test/algorithms/set_operations/sym_difference/sym_difference_linear_linear.cpp similarity index 100% rename from test/algorithms/sym_difference_linear_linear.cpp rename to test/algorithms/set_operations/sym_difference/sym_difference_linear_linear.cpp diff --git a/test/algorithms/test_sym_difference_linear_linear.hpp b/test/algorithms/set_operations/sym_difference/test_sym_difference_linear_linear.hpp similarity index 98% rename from test/algorithms/test_sym_difference_linear_linear.hpp rename to test/algorithms/set_operations/sym_difference/test_sym_difference_linear_linear.hpp index 001c82bd8..69c82403e 100644 --- a/test/algorithms/test_sym_difference_linear_linear.hpp +++ b/test/algorithms/set_operations/sym_difference/test_sym_difference_linear_linear.hpp @@ -10,10 +10,10 @@ #ifndef BOOST_GEOMETRY_TEST_SYM_DIFFERENCE_LINEAR_LINEAR_HPP #define BOOST_GEOMETRY_TEST_SYM_DIFFERENCE_LINEAR_LINEAR_HPP -#include "from_wkt.hpp" #include -#include "test_set_ops_linear_linear.hpp" -#include "to_svg.hpp" +#include "../test_set_ops_linear_linear.hpp" +#include +#include //================================================================== diff --git a/test/algorithms/test_get_turns_ll_invariance.hpp b/test/algorithms/set_operations/test_get_turns_ll_invariance.hpp similarity index 100% rename from test/algorithms/test_get_turns_ll_invariance.hpp rename to test/algorithms/set_operations/test_get_turns_ll_invariance.hpp diff --git a/test/algorithms/test_set_ops_linear_linear.hpp b/test/algorithms/set_operations/test_set_ops_linear_linear.hpp similarity index 98% rename from test/algorithms/test_set_ops_linear_linear.hpp rename to test/algorithms/set_operations/test_set_ops_linear_linear.hpp index c3ff6757d..c208f1b74 100644 --- a/test/algorithms/test_set_ops_linear_linear.hpp +++ b/test/algorithms/set_operations/test_set_ops_linear_linear.hpp @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -266,6 +267,8 @@ void set_operation_output(std::string const& set_op_id, G1 const& g1, G2 const& g2, Output const& output) { + boost::ignore_unused(set_op_id, caseid, g1, g2, output); + #if defined(TEST_WITH_SVG) typedef typename bg::coordinate_type::type coordinate_type; typedef typename bg::point_type::type point_type; diff --git a/test/algorithms/test_set_ops_pl_pl.hpp b/test/algorithms/set_operations/test_set_ops_pl_pl.hpp similarity index 98% rename from test/algorithms/test_set_ops_pl_pl.hpp rename to test/algorithms/set_operations/test_set_ops_pl_pl.hpp index c2b884a0b..fd825d003 100644 --- a/test/algorithms/test_set_ops_pl_pl.hpp +++ b/test/algorithms/set_operations/test_set_ops_pl_pl.hpp @@ -15,11 +15,13 @@ namespace bg = ::boost::geometry; -#include "from_wkt.hpp" -#include "to_svg.hpp" +#include +#include #include #include +#include + #include #include @@ -43,6 +45,8 @@ void set_operation_output(std::string const& set_op_id, G1 const& g1, G2 const& g2, Output const& output) { + boost::ignore_unused(set_op_id, caseid, g1, g2, output); + #if defined(TEST_WITH_SVG) typedef typename bg::coordinate_type::type coordinate_type; typedef typename bg::point_type::type point_type; diff --git a/test/algorithms/set_operations/union/Jamfile.v2 b/test/algorithms/set_operations/union/Jamfile.v2 new file mode 100644 index 000000000..d4df3ea5c --- /dev/null +++ b/test/algorithms/set_operations/union/Jamfile.v2 @@ -0,0 +1,23 @@ +# Boost.Geometry (aka GGL, Generic Geometry Library) +# +# Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. +# Copyright (c) 2008-2014 Bruno Lalande, Paris, France. +# Copyright (c) 2009-2014 Mateusz Loskot, London, UK. +# +# This file was modified by Oracle on 2014. +# 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 +# http://www.boost.org/LICENSE_1_0.txt) + +test-suite boost-geometry-algorithms-union + : + [ run multi_union.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE msvc:/bigobj ] + [ run union.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE msvc:/bigobj ] + [ run union_linear_linear.cpp ] + [ run union_pl_pl.cpp ] + ; diff --git a/test/multi/algorithms/multi_union.cpp b/test/algorithms/set_operations/union/multi_union.cpp similarity index 98% rename from test/multi/algorithms/multi_union.cpp rename to test/algorithms/set_operations/union/multi_union.cpp index 2e1e309a6..b90459236 100644 --- a/test/multi/algorithms/multi_union.cpp +++ b/test/algorithms/set_operations/union/multi_union.cpp @@ -14,9 +14,9 @@ // This multi_union currently contains no tests for double which then fail // #define BOOST_GEOMETRY_NO_ROBUSTNESS -#include +#include "test_union.hpp" #include -#include +#include #include #include diff --git a/test/algorithms/test_union.hpp b/test/algorithms/set_operations/union/test_union.hpp similarity index 100% rename from test/algorithms/test_union.hpp rename to test/algorithms/set_operations/union/test_union.hpp diff --git a/test/algorithms/test_union_linear_linear.hpp b/test/algorithms/set_operations/union/test_union_linear_linear.hpp similarity index 98% rename from test/algorithms/test_union_linear_linear.hpp rename to test/algorithms/set_operations/union/test_union_linear_linear.hpp index c106a51c8..2fd16fbfb 100644 --- a/test/algorithms/test_union_linear_linear.hpp +++ b/test/algorithms/set_operations/union/test_union_linear_linear.hpp @@ -10,10 +10,10 @@ #ifndef BOOST_GEOMETRY_TEST_UNION_LINEAR_LINEAR_HPP #define BOOST_GEOMETRY_TEST_UNION_LINEAR_LINEAR_HPP -#include "from_wkt.hpp" #include -#include "test_set_ops_linear_linear.hpp" -#include "to_svg.hpp" +#include "../test_set_ops_linear_linear.hpp" +#include +#include //================================================================== diff --git a/test/algorithms/union.cpp b/test/algorithms/set_operations/union/union.cpp similarity index 99% rename from test/algorithms/union.cpp rename to test/algorithms/set_operations/union/union.cpp index b5dfbf237..5be277cbf 100644 --- a/test/algorithms/union.cpp +++ b/test/algorithms/set_operations/union/union.cpp @@ -19,7 +19,7 @@ // Test which would fail then are disabled automatically // #define BOOST_GEOMETRY_NO_ROBUSTNESS -#include +#include "test_union.hpp" #include #include diff --git a/test/algorithms/union_linear_linear.cpp b/test/algorithms/set_operations/union/union_linear_linear.cpp similarity index 100% rename from test/algorithms/union_linear_linear.cpp rename to test/algorithms/set_operations/union/union_linear_linear.cpp diff --git a/test/algorithms/union_pl_pl.cpp b/test/algorithms/set_operations/union/union_pl_pl.cpp similarity index 99% rename from test/algorithms/union_pl_pl.cpp rename to test/algorithms/set_operations/union/union_pl_pl.cpp index 160d86646..05be9f1f6 100644 --- a/test/algorithms/union_pl_pl.cpp +++ b/test/algorithms/set_operations/union/union_pl_pl.cpp @@ -20,7 +20,7 @@ #include -#include "test_set_ops_pl_pl.hpp" +#include "../test_set_ops_pl_pl.hpp" #include diff --git a/test/algorithms/test_convex_hull.hpp b/test/algorithms/test_convex_hull.hpp index a11b42dd7..d299394c5 100644 --- a/test/algorithms/test_convex_hull.hpp +++ b/test/algorithms/test_convex_hull.hpp @@ -2,6 +2,12 @@ // Unit Test // 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) @@ -53,18 +59,49 @@ void check_convex_hull(Geometry const& geometry, Hull const& hull, BOOST_CHECK_CLOSE(ah, expected_area, 0.001); } +namespace resolve_variant { + +struct closure_visitor : public boost::static_visitor +{ + template + bg::closure_selector operator()(Geometry const&) const + { + return bg::closure::value; + } +}; + +template +inline bg::closure_selector get_closure(Geometry const&) +{ + return bg::closure::value; +} + +template +inline bg::closure_selector get_closure(boost::variant const& v) +{ + return boost::apply_visitor(closure_visitor(), v); +} + +} // namespace resolve_variant + template void test_convex_hull(Geometry const& geometry, - std::size_t size_original, std::size_t size_hull, + std::size_t size_original, std::size_t size_hull_closed, double expected_area, bool reverse) { + bool const is_original_closed = resolve_variant::get_closure(geometry) != bg::open; + static bool const is_hull_closed = bg::closure::value != bg::open; + + // convex_hull_insert() uses the original Geometry as a source of the info about the order and closure + std::size_t const size_hull_from_orig = is_original_closed ? size_hull_closed : size_hull_closed - 1; + std::size_t const size_hull = is_hull_closed ? size_hull_closed : size_hull_closed - 1; + Hull hull; // Test version with output iterator bg::detail::convex_hull::convex_hull_insert(geometry, std::back_inserter(hull.outer())); - check_convex_hull(geometry, hull, - size_original, size_hull, expected_area, reverse); + check_convex_hull(geometry, hull, size_original, size_hull_from_orig, expected_area, reverse); // Test version with ring as output bg::clear(hull); @@ -84,19 +121,20 @@ void test_convex_hull(Geometry const& geometry, // Test version with output iterator and strategy bg::clear(hull); bg::detail::convex_hull::convex_hull_insert(geometry, std::back_inserter(hull.outer()), Strategy()); - check_convex_hull(geometry, hull, size_original, size_hull, expected_area, reverse); + check_convex_hull(geometry, hull, size_original, size_hull_from_orig, expected_area, reverse); } -template +template void test_geometry_order(std::string const& wkt, - std::size_t size_original, std::size_t size_hull, + std::size_t size_original, std::size_t size_hull_closed, double expected_area) { typedef bg::model::polygon < typename bg::point_type::type, - Clockwise + Clockwise, + Closed > hull_type; typedef bg::strategy::convex_hull::graham_andrew @@ -109,17 +147,19 @@ void test_geometry_order(std::string const& wkt, bg::read_wkt(wkt, geometry); boost::variant v(geometry); - test_convex_hull(geometry, size_original, size_hull, expected_area, !Clockwise); - test_convex_hull(v, size_original, size_hull, expected_area, !Clockwise); + test_convex_hull(geometry, size_original, size_hull_closed, expected_area, !Clockwise); + test_convex_hull(v, size_original, size_hull_closed, expected_area, !Clockwise); } template void test_geometry(std::string const& wkt, - std::size_t size_original, std::size_t size_hull, + std::size_t size_original, std::size_t size_hull_closed, double expected_area) { - test_geometry_order(wkt, size_original, size_hull, expected_area); - test_geometry_order(wkt, size_original, size_hull, expected_area); + test_geometry_order(wkt, size_original, size_hull_closed, expected_area); + test_geometry_order(wkt, size_original, size_hull_closed, expected_area); + test_geometry_order(wkt, size_original, size_hull_closed, expected_area); + test_geometry_order(wkt, size_original, size_hull_closed, expected_area); } template diff --git a/test/algorithms/from_wkt.hpp b/test/from_wkt.hpp similarity index 100% rename from test/algorithms/from_wkt.hpp rename to test/from_wkt.hpp diff --git a/test/multi/io/dsv/Jamfile.v2 b/test/io/dsv/Jamfile.v2 similarity index 92% rename from test/multi/io/dsv/Jamfile.v2 rename to test/io/dsv/Jamfile.v2 index 1a855ae27..73d818db7 100644 --- a/test/multi/io/dsv/Jamfile.v2 +++ b/test/io/dsv/Jamfile.v2 @@ -8,7 +8,7 @@ # Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) -test-suite boost-geometry-multi-io-dsv +test-suite boost-geometry-io-dsv : [ run multi_dsv.cpp ] ; diff --git a/test/multi/io/dsv/multi_dsv.cpp b/test/io/dsv/multi_dsv.cpp similarity index 100% rename from test/multi/io/dsv/multi_dsv.cpp rename to test/io/dsv/multi_dsv.cpp diff --git a/test/io/wkt/Jamfile.v2 b/test/io/wkt/Jamfile.v2 index c93e26a8e..27813bbf6 100644 --- a/test/io/wkt/Jamfile.v2 +++ b/test/io/wkt/Jamfile.v2 @@ -10,6 +10,7 @@ test-suite boost-geometry-io-wkt : + [ run multi_wkt.cpp ] [ run wkt.cpp ] ; diff --git a/test/multi/io/wkt/multi_wkt.cpp b/test/io/wkt/multi_wkt.cpp similarity index 100% rename from test/multi/io/wkt/multi_wkt.cpp rename to test/io/wkt/multi_wkt.cpp diff --git a/test/iterators/concatenate_iterator.cpp b/test/iterators/concatenate_iterator.cpp index 230f920a0..15de3082a 100644 --- a/test/iterators/concatenate_iterator.cpp +++ b/test/iterators/concatenate_iterator.cpp @@ -27,6 +27,8 @@ #include #include +#include + #include "test_iterator_common.hpp" #include @@ -106,6 +108,8 @@ struct test_concatenate_iterator std::string const& case_id, std::string const& containers_id) { + boost::ignore_unused(case_id, containers_id); + #ifdef BOOST_GEOMETRY_TEST_DEBUG std::stringstream sstream; sstream << case_id << " [" << containers_id << "]"; diff --git a/test/iterators/flatten_iterator.cpp b/test/iterators/flatten_iterator.cpp index 73e7ff12e..9f989594e 100644 --- a/test/iterators/flatten_iterator.cpp +++ b/test/iterators/flatten_iterator.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -151,6 +152,8 @@ struct test_flatten_iterator std::string const& case_id, std::string const& container_id) { + boost::ignore_unused(case_id, container_id); + #ifdef BOOST_GEOMETRY_TEST_DEBUG std::stringstream sstream; sstream << case_id << " [" << container_id << "]"; diff --git a/test/iterators/point_iterator.cpp b/test/iterators/point_iterator.cpp index dff15eabe..b07d64ea2 100644 --- a/test/iterators/point_iterator.cpp +++ b/test/iterators/point_iterator.cpp @@ -22,8 +22,11 @@ #include #include - +#include +#include +#include #include +#include #include #include @@ -93,6 +96,36 @@ inline std::ostream& print_point_range(std::ostream& os, return os; } + +template +< + typename Geometry, + bool IsConst = boost::is_const::value +> +struct test_iterator_concepts +{ + typedef bg::point_iterator iterator; + BOOST_CONCEPT_ASSERT(( boost::BidirectionalIteratorConcept )); + BOOST_CONCEPT_ASSERT(( boost_concepts::ReadableIteratorConcept )); + BOOST_CONCEPT_ASSERT(( boost_concepts::LvalueIteratorConcept )); + BOOST_CONCEPT_ASSERT + (( boost_concepts::BidirectionalTraversalConcept )); +}; + +template +struct test_iterator_concepts + : test_iterator_concepts +{ + typedef bg::point_iterator iterator; + BOOST_CONCEPT_ASSERT + (( boost::Mutable_BidirectionalIteratorConcept )); + BOOST_CONCEPT_ASSERT + (( boost_concepts::WritableIteratorConcept )); + BOOST_CONCEPT_ASSERT + (( boost_concepts::SwappableIteratorConcept )); +}; + + struct equals { template @@ -205,6 +238,8 @@ struct test_point_iterator_of_geometry { typedef bg::point_iterator point_iterator; + test_iterator_concepts(); + point_iterator begin = bg::points_begin(geometry); point_iterator end = bg::points_end(geometry); @@ -217,6 +252,8 @@ struct test_point_iterator_of_geometry bg::points_end(point_range)) ); + boost::ignore_unused(header); + #ifdef BOOST_GEOMETRY_TEST_DEBUG std::cout << header << " geometry: " << bg::wkt(geometry) << std::endl; print_point_range(std::cout, begin, end, "point range: "); diff --git a/test/iterators/segment_iterator.cpp b/test/iterators/segment_iterator.cpp index 167ff9326..f464eceeb 100644 --- a/test/iterators/segment_iterator.cpp +++ b/test/iterators/segment_iterator.cpp @@ -22,9 +22,9 @@ #include #include - +#include #include - +#include #include #include @@ -94,6 +94,16 @@ inline std::ostream& print_geometry_range(std::ostream& os, return os; } +template +struct test_iterator_concepts +{ + typedef bg::segment_iterator iterator; + BOOST_CONCEPT_ASSERT(( boost::BidirectionalIteratorConcept )); + BOOST_CONCEPT_ASSERT(( boost_concepts::ReadableIteratorConcept )); + BOOST_CONCEPT_ASSERT + (( boost_concepts::BidirectionalTraversalConcept )); +}; + struct equals { template @@ -155,6 +165,8 @@ struct test_segment_iterator_of_geometry { typedef bg::segment_iterator segment_iterator; + test_iterator_concepts(); + segment_iterator begin = bg::segments_begin(geometry); segment_iterator end = bg::segments_end(geometry); diff --git a/test/iterators/test_iterator_common.hpp b/test/iterators/test_iterator_common.hpp index db8a8283c..05b84a463 100644 --- a/test/iterators/test_iterator_common.hpp +++ b/test/iterators/test_iterator_common.hpp @@ -88,8 +88,8 @@ template inline void test_size(CombinedIterator first, CombinedIterator beyond, CombinedContainer const& combined) { - std::size_t size = std::distance(first, beyond); - BOOST_CHECK( combined.size() == std::distance(first, beyond) ); + std::size_t size = static_cast(std::distance(first, beyond)); + BOOST_CHECK( combined.size() == size ); size = 0; for (CombinedIterator it = first; it != beyond; ++it) diff --git a/test/multi/Jamfile.v2 b/test/multi/Jamfile.v2 deleted file mode 100644 index b38d8c5ad..000000000 --- a/test/multi/Jamfile.v2 +++ /dev/null @@ -1,12 +0,0 @@ -# Boost.Geometry (aka GGL, Generic Geometry Library) -# -# Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -# Copyright (c) 2008-2012 Bruno Lalande, Paris, France. -# Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -# -# 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) - -build-project algorithms ; -build-project io ; \ No newline at end of file diff --git a/test/multi/algorithms/Jamfile.v2 b/test/multi/algorithms/Jamfile.v2 deleted file mode 100644 index ef1d6b2c8..000000000 --- a/test/multi/algorithms/Jamfile.v2 +++ /dev/null @@ -1,42 +0,0 @@ -# Boost.Geometry (aka GGL, Generic Geometry Library) -# -# Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. -# Copyright (c) 2008-2014 Bruno Lalande, Paris, France. -# Copyright (c) 2009-2014 Mateusz Loskot, London, UK. -# -# Use, modification and distribution is subject to the Boost Software License, -# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -test-suite boost-geometry-multi-algorithms - : - [ run multi_area.cpp ] - [ run multi_centroid.cpp ] - [ run multi_convert.cpp ] - [ run multi_convex_hull.cpp ] - [ run multi_correct.cpp ] - [ run multi_covered_by.cpp ] - [ run multi_difference.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE msvc:/bigobj ] - [ run multi_difference_spike.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE msvc:/bigobj ] - [ run multi_disjoint.cpp ] - [ run multi_envelope.cpp ] - [ run multi_equals.cpp ] - [ run multi_for_each.cpp ] - [ run multi_intersection.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE msvc:/bigobj ] - [ run multi_intersects.cpp ] - [ run multi_length.cpp ] - [ run multi_num_geometries.cpp ] - [ run multi_num_interior_rings.cpp ] - [ run multi_num_points.cpp ] - [ run multi_perimeter.cpp ] - [ run multi_reverse.cpp ] - [ run multi_simplify.cpp ] - [ run multi_touches.cpp ] - [ run multi_transform.cpp ] - [ run multi_union.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE msvc:/bigobj ] - [ run multi_unique.cpp ] - [ run multi_within.cpp ] - ; - -build-project overlay - ; diff --git a/test/multi/algorithms/overlay/Jamfile.v2 b/test/multi/algorithms/overlay/Jamfile.v2 deleted file mode 100644 index 2ea7594e1..000000000 --- a/test/multi/algorithms/overlay/Jamfile.v2 +++ /dev/null @@ -1,14 +0,0 @@ -# Boost.Geometry (aka GGL, Generic Geometry Library) -# -# Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -# Copyright (c) 2008-2012 Bruno Lalande, Paris, France. -# Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -# -# Use, modification and distribution is subject to the Boost Software License, -# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -test-suite boost-geometry-multi-algorithms-overlay - : - [ run multi_traverse.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE BOOST_GEOMETRY_RESCALE_TO_ROBUST ] - ; diff --git a/test/multi/io/Jamfile.v2 b/test/multi/io/Jamfile.v2 deleted file mode 100644 index 6985a7ab9..000000000 --- a/test/multi/io/Jamfile.v2 +++ /dev/null @@ -1,12 +0,0 @@ -# Boost.Geometry (aka GGL, Generic Geometry Library) -# -# Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -# Copyright (c) 2008-2012 Bruno Lalande, Paris, France. -# Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -# -# 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) - -build-project wkt ; -build-project dsv ; diff --git a/test/multi/io/wkt/Jamfile.v2 b/test/multi/io/wkt/Jamfile.v2 deleted file mode 100644 index 50c17cf68..000000000 --- a/test/multi/io/wkt/Jamfile.v2 +++ /dev/null @@ -1,15 +0,0 @@ -# Boost.Geometry (aka GGL, Generic Geometry Library) -# -# Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -# Copyright (c) 2008-2012 Bruno Lalande, Paris, France. -# Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -# -# Use, modification and distribution is subject to the Boost Software License, -# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -test-suite boost-geometry-multi-io-wkt - : - [ run multi_wkt.cpp ] - ; - diff --git a/test/point_concept/Jamfile.v2 b/test/point_concept/Jamfile.v2 index 7c4b8aed6..c8bc7c157 100644 --- a/test/point_concept/Jamfile.v2 +++ b/test/point_concept/Jamfile.v2 @@ -11,12 +11,17 @@ test-suite boost-geometry-point-concept : [ compile concept_checker.cpp ] + [ compile well_formed_non_cartesian_point.cpp ] [ compile well_formed_point.cpp ] [ compile well_formed_point_traits.cpp ] [ compile array_point.cpp ] + [ compile-fail geographic_custom_point_with_wrong_units.cpp ] + [ compile-fail geographic_point_with_wrong_units.cpp ] [ compile-fail point_without_coordinate_type.cpp ] [ compile-fail point_without_dimension.cpp ] [ compile-fail point_without_getter.cpp ] [ compile-fail point_without_setter.cpp ] [ compile-fail point_with_incorrect_dimension.cpp ] + [ compile-fail spherical_equatorial_custom_point_with_wrong_units.cpp ] + [ compile-fail spherical_equatorial_point_with_wrong_units.cpp ] ; diff --git a/test/point_concept/geographic_custom_point_with_wrong_units.cpp b/test/point_concept/geographic_custom_point_with_wrong_units.cpp new file mode 100644 index 000000000..f2985b841 --- /dev/null +++ b/test/point_concept/geographic_custom_point_with_wrong_units.cpp @@ -0,0 +1,29 @@ +// 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 + +#include + +#include +#include + + +namespace bg = boost::geometry; + +struct dummy {}; + +int main() +{ + bg::concept::check + < + ro_lon_lat_point > const + >(); + + return 0; +} diff --git a/test/point_concept/geographic_point_with_wrong_units.cpp b/test/point_concept/geographic_point_with_wrong_units.cpp new file mode 100644 index 000000000..ab5fdc704 --- /dev/null +++ b/test/point_concept/geographic_point_with_wrong_units.cpp @@ -0,0 +1,29 @@ +// 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 + +#include + +#include +#include +#include + + +namespace bg = boost::geometry; + + +int main() +{ + bg::concept::check + < + bg::model::point > + >(); + + return 0; +} diff --git a/test/point_concept/spherical_equatorial_custom_point_with_wrong_units.cpp b/test/point_concept/spherical_equatorial_custom_point_with_wrong_units.cpp new file mode 100644 index 000000000..f5c5bb573 --- /dev/null +++ b/test/point_concept/spherical_equatorial_custom_point_with_wrong_units.cpp @@ -0,0 +1,28 @@ +// 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 + +#include + +#include +#include + + +namespace bg = boost::geometry; + + +int main() +{ + bg::concept::check + < + rw_lon_lat_point > + >(); + + return 0; +} diff --git a/test/point_concept/spherical_equatorial_point_with_wrong_units.cpp b/test/point_concept/spherical_equatorial_point_with_wrong_units.cpp new file mode 100644 index 000000000..960db4a4d --- /dev/null +++ b/test/point_concept/spherical_equatorial_point_with_wrong_units.cpp @@ -0,0 +1,26 @@ +// 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 + +#include + +#include +#include +#include + + +namespace bg = boost::geometry; + + +int main() +{ + bg::model::point > p; + + return 0; +} diff --git a/test/point_concept/well_formed_non_cartesian_point.cpp b/test/point_concept/well_formed_non_cartesian_point.cpp new file mode 100644 index 000000000..e6817adb3 --- /dev/null +++ b/test/point_concept/well_formed_non_cartesian_point.cpp @@ -0,0 +1,64 @@ +// 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 + +#include + +#include +#include +#include + + +namespace bg = boost::geometry; + + +template +inline void test_coordinate_system() +{ + typedef bg::model::point bg_double_point; + typedef bg::model::point bg_int_point; + + typedef rw_lon_lat_point rw_double_point; + typedef ro_lon_lat_point ro_double_point; + + typedef rw_lon_lat_point rw_int_point; + typedef ro_lon_lat_point ro_int_point; + + bg::concept::check(); + bg::concept::check(); + + bg::concept::check(); + bg::concept::check(); + + bg::concept::check(); + bg::concept::check(); + bg::concept::check(); + + bg::concept::check(); + bg::concept::check(); + bg::concept::check(); +} + + +int main() +{ + test_coordinate_system >(); + test_coordinate_system >(); + + test_coordinate_system >(); + test_coordinate_system >(); + + test_coordinate_system >(); + test_coordinate_system >(); + + test_coordinate_system >(); + test_coordinate_system >(); + + return 0; +} diff --git a/test/strategies/Jamfile.v2 b/test/strategies/Jamfile.v2 index 474378a27..d32c10737 100644 --- a/test/strategies/Jamfile.v2 +++ b/test/strategies/Jamfile.v2 @@ -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 # # Use, modification and distribution is subject to the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -16,8 +17,11 @@ test-suite boost-geometry-strategies : [ run cross_track.cpp ] + [ run crossings_multiply.cpp ] [ run distance_default_result.cpp ] + [ run franklin.cpp ] [ run haversine.cpp ] + [ run point_in_box.cpp ] [ run projected_point.cpp ] [ run projected_point_ax.cpp ] [ run pythagoras.cpp ] @@ -26,5 +30,5 @@ test-suite boost-geometry-strategies [ run segment_intersection_collinear.cpp ] [ run transform_cs.cpp ] [ run transformer.cpp ] - [ run winding_franklin_crossmult.cpp ] + [ run winding.cpp ] ; diff --git a/test/strategies/crossings_multiply.cpp b/test/strategies/crossings_multiply.cpp new file mode 100644 index 000000000..f57d383f1 --- /dev/null +++ b/test/strategies/crossings_multiply.cpp @@ -0,0 +1,87 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// Unit Test + +// Copyright (c) 2010-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) + + +#include + + +template +void test_all() +{ + typedef bg::model::polygon polygon; + + std::string const box = "POLYGON((0 0,0 2,2 2,2 0,0 0))"; + std::string const triangle = "POLYGON((0 0,0 4,6 0,0 0))"; + std::string const with_hole = "POLYGON((0 0,0 3,3 3,3 0,0 0),(1 1,2 1,2 2,1 2,1 1))"; + + bg::strategy::within::crossings_multiply s; + + + test_geometry("b1", "POINT(1 1)", box, s, true); + test_geometry("b2", "POINT(3 3)", box, s, false); + + // Test ALL corners (officialy false but some strategies might answer true) + test_geometry("b3a", "POINT(0 0)", box, s, false); + test_geometry("b3b", "POINT(0 2)", box, s, false); + test_geometry("b3c", "POINT(2 2)", box, s, false); + test_geometry("b3d", "POINT(2 0)", box, s, false); + + // Test ALL sides (officialy false but some strategies might answer true) + test_geometry("b4a", "POINT(0 1)", box, s, false); + test_geometry("b4b", "POINT(1 2)", box, s, true); // different + test_geometry("b4c", "POINT(2 1)", box, s, false); + test_geometry("b4d", "POINT(1 0)", box, s, false); + + + test_geometry("t1", "POINT(1 1)", triangle, s, true); + test_geometry("t2", "POINT(3 3)", triangle, s, false); + + test_geometry("t3a", "POINT(0 0)", triangle, s, false); + test_geometry("t3b", "POINT(0 4)", triangle, s, true); // diff + test_geometry("t3c", "POINT(5 0)", triangle, s, false); + + test_geometry("t4a", "POINT(0 2)", triangle, s, false); + test_geometry("t4b", "POINT(3 2)", triangle, s, false); + test_geometry("t4c", "POINT(2 0)", triangle, s, false); + + + test_geometry("h1", "POINT(0.5 0.5)", with_hole, s, true); + test_geometry("h2a", "POINT(1.5 1.5)", with_hole, s, false); + test_geometry("h2b", "POINT(5 5)", with_hole, s, false); + + test_geometry("h3a", "POINT(1 1)", with_hole, s, true); // diff + test_geometry("h3b", "POINT(2 2)", with_hole, s, false); + test_geometry("h3c", "POINT(0 0)", with_hole, s, false); + + test_geometry("h4a", "POINT(1 1.5)", with_hole, s, false); + test_geometry("h4b", "POINT(1.5 2)", with_hole, s, false); + + // Lying ON (one of the sides of) interior ring + test_geometry("#77-1", "POINT(6 3.5)", + "POLYGON((5 3,5 4,4 4,4 5,3 5,3 6,5 6,5 5,7 5,7 6,8 6,8 5,9 5,9 2,8 2,8 1,7 1,7 2,5 2,5 3),(6 3,8 3,8 4,6 4,6 3))", + s, false); +} + + +int test_main(int, char* []) +{ + test_all >(); + test_all >(); + +#if defined(HAVE_TTMATH) + test_all >(); +#endif + + return 0; +} diff --git a/test/strategies/franklin.cpp b/test/strategies/franklin.cpp new file mode 100644 index 000000000..6a6c5fe17 --- /dev/null +++ b/test/strategies/franklin.cpp @@ -0,0 +1,86 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// Unit Test + +// Copyright (c) 2010-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) + + +#include + + +template +void test_all() +{ + typedef bg::model::polygon polygon; + + std::string const box = "POLYGON((0 0,0 2,2 2,2 0,0 0))"; + std::string const triangle = "POLYGON((0 0,0 4,6 0,0 0))"; + std::string const with_hole = "POLYGON((0 0,0 3,3 3,3 0,0 0),(1 1,2 1,2 2,1 2,1 1))"; + + bg::strategy::within::franklin s; + + test_geometry("b1", "POINT(1 1)", box, s, true); + test_geometry("b2", "POINT(3 3)", box, s, false); + + // Test ALL corners (officialy false but some strategies might answer true) + test_geometry("b3a", "POINT(0 0)", box, s, true); // different + test_geometry("b3b", "POINT(0 2)", box, s, false); + test_geometry("b3c", "POINT(2 2)", box, s, false); + test_geometry("b3d", "POINT(2 0)", box, s, false); + + // Test ALL sides (officialy false but some strategies might answer true) + test_geometry("b4a", "POINT(0 1)", box, s, true); // different + test_geometry("b4b", "POINT(1 2)", box, s, false); + test_geometry("b4c", "POINT(2 1)", box, s, false); + test_geometry("b4d", "POINT(1 0)", box, s, true); // different + + + test_geometry("t1", "POINT(1 1)", triangle, s, true); + test_geometry("t2", "POINT(3 3)", triangle, s, false); + + test_geometry("t3a", "POINT(0 0)", triangle, s, true); // diff + test_geometry("t3b", "POINT(0 4)", triangle, s, false); + test_geometry("t3c", "POINT(5 0)", triangle, s, true); // diff + + test_geometry("t4a", "POINT(0 2)", triangle, s, true); // diff + test_geometry("t4b", "POINT(3 2)", triangle, s, false); + test_geometry("t4c", "POINT(2 0)", triangle, s, true); // diff + + + test_geometry("h1", "POINT(0.5 0.5)", with_hole, s, true); + test_geometry("h2a", "POINT(1.5 1.5)", with_hole, s, false); + test_geometry("h2b", "POINT(5 5)", with_hole, s, false); + + test_geometry("h3a", "POINT(1 1)", with_hole, s, false); + test_geometry("h3b", "POINT(2 2)", with_hole, s, true); // diff + test_geometry("h3c", "POINT(0 0)", with_hole, s, true); // diff + + test_geometry("h4a", "POINT(1 1.5)", with_hole, s, false); + test_geometry("h4b", "POINT(1.5 2)", with_hole, s, true); // diff + + // Lying ON (one of the sides of) interior ring + test_geometry("#77-1", "POINT(6 3.5)", + "POLYGON((5 3,5 4,4 4,4 5,3 5,3 6,5 6,5 5,7 5,7 6,8 6,8 5,9 5,9 2,8 2,8 1,7 1,7 2,5 2,5 3),(6 3,8 3,8 4,6 4,6 3))", + s, false); +} + + +int test_main(int, char* []) +{ + test_all >(); + test_all >(); + +#if defined(HAVE_TTMATH) + test_all >(); +#endif + + return 0; +} diff --git a/test/strategies/point_in_box.cpp b/test/strategies/point_in_box.cpp new file mode 100644 index 000000000..1c5e04879 --- /dev/null +++ b/test/strategies/point_in_box.cpp @@ -0,0 +1,81 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// Unit Test + +// Copyright (c) 2010-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) + + +#include + + +template +void test_box_of(std::string const& wkt_point, std::string const& wkt_box, + bool expected_within, bool expected_covered_by) +{ + typedef bg::model::box box_type; + + Point point; + box_type box; + bg::read_wkt(wkt_point, point); + bg::read_wkt(wkt_box, box); + + bool detected_within = bg::within(point, box); + bool detected_covered_by = bg::covered_by(point, box); + BOOST_CHECK_EQUAL(detected_within, expected_within); + BOOST_CHECK_EQUAL(detected_covered_by, expected_covered_by); + + // Also test with the non-default agnostic side version + namespace wi = bg::strategy::within; + wi::point_in_box_by_side within_strategy; + wi::point_in_box_by_side covered_by_strategy; + + detected_within = bg::within(point, box, within_strategy); + detected_covered_by = bg::covered_by(point, box, covered_by_strategy); + BOOST_CHECK_EQUAL(detected_within, expected_within); + BOOST_CHECK_EQUAL(detected_covered_by, expected_covered_by); + + // We might exchange strategies between within/covered by. + // So the lines below might seem confusing, but are as intended + detected_within = bg::covered_by(point, box, within_strategy); + detected_covered_by = bg::within(point, box, covered_by_strategy); + BOOST_CHECK_EQUAL(detected_within, expected_within); + BOOST_CHECK_EQUAL(detected_covered_by, expected_covered_by); + + // Finally we call the strategies directly + detected_within = within_strategy.apply(point, box); + detected_covered_by = covered_by_strategy.apply(point, box); + BOOST_CHECK_EQUAL(detected_within, expected_within); + BOOST_CHECK_EQUAL(detected_covered_by, expected_covered_by); +} + +template +void test_box() +{ + test_box_of("POINT(1 1)", "BOX(0 0,2 2)", true, true); + test_box_of("POINT(0 0)", "BOX(0 0,2 2)", false, true); + test_box_of("POINT(2 2)", "BOX(0 0,2 2)", false, true); + test_box_of("POINT(0 1)", "BOX(0 0,2 2)", false, true); + test_box_of("POINT(1 0)", "BOX(0 0,2 2)", false, true); + test_box_of("POINT(3 3)", "BOX(0 0,2 2)", false, false); +} + + +int test_main(int, char* []) +{ + test_box >(); + test_box >(); + +#if defined(HAVE_TTMATH) + test_box >(); +#endif + + return 0; +} diff --git a/test/strategies/test_within.hpp b/test/strategies/test_within.hpp new file mode 100644 index 000000000..4ceb2608e --- /dev/null +++ b/test/strategies/test_within.hpp @@ -0,0 +1,106 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// Unit Test + +// Copyright (c) 2010-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_TEST_STRATEGIES_TEST_WITHIN_HPP +#define BOOST_GEOMETRY_TEST_STRATEGIES_TEST_WITHIN_HPP + + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + + +#include +#include +#include + +#include + + +template +inline const char * strategy_name(Strategy const&) +{ + return typeid(Strategy).name(); +} + +template +inline const char * strategy_name(bg::strategy::within::crossings_multiply const&) +{ + return "crossings_multiply"; +} + +template +inline const char * strategy_name(bg::strategy::within::franklin const&) +{ + return "franklin"; +} + +template +inline const char * strategy_name(bg::strategy::within::winding const&) +{ + return "winding"; +} + + +template +void test_point_in_polygon(std::string const& case_id, + Point const& point, + Polygon const& polygon, + Strategy const& strategy, + bool expected, + bool use_within = true) +{ + BOOST_CONCEPT_ASSERT( (bg::concept::WithinStrategyPolygonal) ); + bool detected = use_within ? + bg::within(point, polygon, strategy) : + bg::covered_by(point, polygon, strategy); + + BOOST_CHECK_MESSAGE(detected == expected, + (use_within ? "within: " : "covered_by: ") << case_id + << " strategy: " << strategy_name(strategy) + << " output expected: " << int(expected) + << " detected: " << int(detected) + ); +} + + +template +void test_geometry(std::string const& case_id, + std::string const& wkt_point, + std::string const& wkt_polygon, + Strategy const& strategy, + bool expected, + bool use_within = true) +{ + Point point; + Polygon polygon; + bg::read_wkt(wkt_point, point); + bg::read_wkt(wkt_polygon, polygon); + + test_point_in_polygon(case_id, point, polygon, strategy, expected, use_within); +} + + +#endif // BOOST_GEOMETRY_TEST_STRATEGIES_TEST_WITHIN_HPP diff --git a/test/strategies/winding.cpp b/test/strategies/winding.cpp new file mode 100644 index 000000000..ff0f3605a --- /dev/null +++ b/test/strategies/winding.cpp @@ -0,0 +1,227 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// Unit Test + +// Copyright (c) 2010-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) + + +#include + + +template +void test_cartesian() +{ + typedef bg::model::polygon polygon; + + std::string const box = "POLYGON((0 0,0 2,2 2,2 0,0 0))"; + std::string const triangle = "POLYGON((0 0,0 4,6 0,0 0))"; + std::string const with_hole = "POLYGON((0 0,0 3,3 3,3 0,0 0),(1 1,2 1,2 2,1 2,1 1))"; + + bg::strategy::within::winding s; + + + test_geometry("b1", "POINT(1 1)", box, s, true); + test_geometry("b2", "POINT(3 3)", box, s, false); + + // Test ALL corners (officialy false but some strategies might answer true) + test_geometry("b3a", "POINT(0 0)", box, s, false); + test_geometry("b3b", "POINT(0 2)", box, s, false); + test_geometry("b3c", "POINT(2 2)", box, s, false); + test_geometry("b3d", "POINT(2 0)", box, s, false); + + // Test ALL sides (officialy false but some strategies might answer true) + test_geometry("b4a", "POINT(0 1)", box, s, false); + test_geometry("b4b", "POINT(1 2)", box, s, false); + test_geometry("b4c", "POINT(2 1)", box, s, false); + test_geometry("b4d", "POINT(1 0)", box, s, false); + + + test_geometry("t1", "POINT(1 1)", triangle, s, true); + test_geometry("t2", "POINT(3 3)", triangle, s, false); + + test_geometry("t3a", "POINT(0 0)", triangle, s, false); + test_geometry("t3b", "POINT(0 4)", triangle, s, false); + test_geometry("t3c", "POINT(5 0)", triangle, s, false); + + test_geometry("t4a", "POINT(0 2)", triangle, s, false); + test_geometry("t4b", "POINT(3 2)", triangle, s, false); + test_geometry("t4c", "POINT(2 0)", triangle, s, false); + + + test_geometry("h1", "POINT(0.5 0.5)", with_hole, s, true); + test_geometry("h2a", "POINT(1.5 1.5)", with_hole, s, false); + test_geometry("h2b", "POINT(5 5)", with_hole, s, false); + + test_geometry("h3a", "POINT(1 1)", with_hole, s, false); + test_geometry("h3b", "POINT(2 2)", with_hole, s, false); + test_geometry("h3c", "POINT(0 0)", with_hole, s, false); + + test_geometry("h4a", "POINT(1 1.5)", with_hole, s, false); + test_geometry("h4b", "POINT(1.5 2)", with_hole, s, false); + + // Lying ON (one of the sides of) interior ring + test_geometry("#77-1", "POINT(6 3.5)", + "POLYGON((5 3,5 4,4 4,4 5,3 5,3 6,5 6,5 5,7 5,7 6,8 6,8 5,9 5,9 2,8 2,8 1,7 1,7 2,5 2,5 3),(6 3,8 3,8 4,6 4,6 3))", + s, false); +} + +template +void test_spherical() +{ + typedef bg::model::point > point; + typedef bg::model::polygon polygon; + + bg::strategy::within::winding s; + + + // Ticket #9354 + test_geometry( + "#9354", + "POINT(-78.1239 25.9556)", + "POLYGON((-97.08466667 25.95683333, -97.13683333 25.954, -97.1 26, -97.08466667 25.95683333))", + s, + false); + +#ifdef BOOST_GEOMETRY_TEST_STRATEGIES_WINDING_ENABLE_FAILING_TESTS + + test_geometry( + "sph1N", + "POINT(0 10.001)", + "POLYGON((-10 10, 10 10, 10 -10, -10 -10, -10 10))", + s, + bg::strategy::side::spherical_side_formula<>::apply( + point(-10, 10), + point(10, 10), + point(0, (T)10.001)) == -1 // right side + /*true*/); + test_geometry( + "sph1S", + "POINT(0 -10.001)", + "POLYGON((-10 10, 10 10, 10 -10, -10 -10, -10 10))", + s, + bg::strategy::side::spherical_side_formula<>::apply( + point(10, -10), + point(-10, -10), + point(0, (T)-10.001)) == -1 // right side + /*true*/); + + test_geometry( + "sph2S", + "POINT(0 10.001)", + "POLYGON((-10 20, 10 20, 10 10, -10 10, -10 20))", + s, + bg::strategy::side::spherical_side_formula<>::apply( + point(10, 10), + point(-10, 10), + point(0, (T)10.001)) == -1 // right side + /*false*/); + + test_geometry( + "sph3N", + "POINT(0 10)", + "POLYGON((-10 10, 10 10, 10 -10, -10 -10, -10 10))", + s, + bg::strategy::side::spherical_side_formula<>::apply( + point(-10, 10), + point(10, 10), + point(0, (T)10.001)) == -1 // right side + /*true*/); + test_geometry( + "sph3S", + "POINT(0 -10)", + "POLYGON((-10 10, 10 10, 10 -10, -10 -10, -10 10))", + s, + bg::strategy::side::spherical_side_formula<>::apply( + point(10, -10), + point(-10, -10), + point(0, (T)-10.001)) == -1 // right side + /*true*/); + +#endif // BOOST_GEOMETRY_TEST_STRATEGIES_WINDING_ENABLE_FAILING_TESTS + + test_geometry( + "sphEq1", + "POINT(179 10)", + "POLYGON((170 10, -170 10, -170 0, 170 0, 170 10))", + s, + true, + false); + test_geometry( + "sphEq2", + "POINT(179 10)", + "POLYGON((170 20, -170 20, -170 10, 170 10, 170 20))", + s, + true, + false); + test_geometry( + "sphEq3", + "POINT(-179 10)", + "POLYGON((170 10, -170 10, -170 0, 170 0, 170 10))", + s, + true, + false); + test_geometry( + "sphEq4", + "POINT(-179 10)", + "POLYGON((170 20, -170 20, -170 10, 170 10, 170 20))", + s, + true, + false); + +#ifdef BOOST_GEOMETRY_TEST_STRATEGIES_WINDING_ENABLE_FAILING_TESTS + + test_geometry( + "sphEq5", + "POINT(169 10)", + "POLYGON((170 20, -170 20, -170 10, 170 10, 170 20))", + s, + false, + false); + test_geometry( + "sphEq6", + "POINT(-169 10)", + "POLYGON((170 20, -170 20, -170 10, 170 10, 170 20))", + s, + false, + false); + test_geometry( + "sphEq7", + "POINT(169 10)", + "POLYGON((170 10, -170 10, -170 0, 170 0, 170 10))", + s, + false, + false); + test_geometry( + "sphEq8", + "POINT(-169 10)", + "POLYGON((170 10, -170 10, -170 0, 170 0, 170 10))", + s, + false, + false); + +#endif // BOOST_GEOMETRY_TEST_STRATEGIES_WINDING_ENABLE_FAILING_TESTS +} + +int test_main(int, char* []) +{ + test_cartesian >(); + test_cartesian >(); + + test_spherical(); + test_spherical(); + +#if defined(HAVE_TTMATH) + test_cartesian >(); + test_spherical(); +#endif + + return 0; +} diff --git a/test/strategies/winding_franklin_crossmult.cpp b/test/strategies/winding_franklin_crossmult.cpp deleted file mode 100644 index 427e82c87..000000000 --- a/test/strategies/winding_franklin_crossmult.cpp +++ /dev/null @@ -1,326 +0,0 @@ -// Boost.Geometry (aka GGL, Generic Geometry Library) -// Unit Test - -// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands. - -// Use, modification and distribution is subject to the Boost Software License, -// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// Tests with-strategies, especially point-in-polygon - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - - -#include -#include -#include - -#include - - - - - - -template -void test_point_in_polygon(std::string const& case_id, - Point const& point, Polygon const& polygon, - Strategy const& strategy, std::string const& strategy_id, - bool expected, bool use_within = true) -{ - BOOST_CONCEPT_ASSERT( (bg::concept::WithinStrategyPolygonal) ); - bool detected = use_within ? - bg::within(point, polygon, strategy) : - bg::covered_by(point, polygon, strategy); - - BOOST_CHECK_MESSAGE(detected == expected, - (use_within ? "within: " : "covered_by: ") << case_id - << " strategy: " << strategy_id // typeid(strategy).name() is too long - << " output expected: " << int(expected) - << " detected: " << int(detected) - ); -} - -template -void test_geometry(std::string const& case_id, std::string const& wkt_point - , std::string const& wkt_polygon - , bool expected - , std::string const& deviations = "" - , bool use_within = true) -{ - Point point; - Polygon polygon; - bg::read_wkt(wkt_point, point); - bg::read_wkt(wkt_polygon, polygon); - - namespace sw = bg::strategy::within; - test_point_in_polygon(case_id, point, polygon, sw::winding(), - "winding", expected, use_within); - test_point_in_polygon(case_id, point, polygon, sw::franklin(), - "franklin", boost::contains(deviations, "f") ? !expected : expected, use_within); - test_point_in_polygon(case_id, point, polygon, sw::crossings_multiply(), - "cross.mult", boost::contains(deviations, "c") ? !expected : expected, use_within); -} - -template -void test_geometry_default(std::string const& case_id, std::string const& wkt_point - , std::string const& wkt_polygon - , bool expected - , bool use_within = true) -{ - Point point; - Polygon polygon; - bg::read_wkt(wkt_point, point); - bg::read_wkt(wkt_polygon, polygon); - - namespace sw = bg::strategy::within; - test_point_in_polygon(case_id, point, polygon, sw::winding(), - "winding", expected, use_within); -} - -template -void test_box_of(std::string const& wkt_point, std::string const& wkt_box, - bool expected_within, bool expected_covered_by) -{ - typedef bg::model::box box_type; - - Point point; - box_type box; - bg::read_wkt(wkt_point, point); - bg::read_wkt(wkt_box, box); - - bool detected_within = bg::within(point, box); - bool detected_covered_by = bg::covered_by(point, box); - BOOST_CHECK_EQUAL(detected_within, expected_within); - BOOST_CHECK_EQUAL(detected_covered_by, expected_covered_by); - - // Also test with the non-default agnostic side version - namespace wi = bg::strategy::within; - wi::point_in_box_by_side within_strategy; - wi::point_in_box_by_side covered_by_strategy; - - detected_within = bg::within(point, box, within_strategy); - detected_covered_by = bg::covered_by(point, box, covered_by_strategy); - BOOST_CHECK_EQUAL(detected_within, expected_within); - BOOST_CHECK_EQUAL(detected_covered_by, expected_covered_by); - - // We might exchange strategies between within/covered by. - // So the lines below might seem confusing, but are as intended - detected_within = bg::covered_by(point, box, within_strategy); - detected_covered_by = bg::within(point, box, covered_by_strategy); - BOOST_CHECK_EQUAL(detected_within, expected_within); - BOOST_CHECK_EQUAL(detected_covered_by, expected_covered_by); - - // Finally we call the strategies directly - detected_within = within_strategy.apply(point, box); - detected_covered_by = covered_by_strategy.apply(point, box); - BOOST_CHECK_EQUAL(detected_within, expected_within); - BOOST_CHECK_EQUAL(detected_covered_by, expected_covered_by); -} - -template -void test_box() -{ - test_box_of("POINT(1 1)", "BOX(0 0,2 2)", true, true); - test_box_of("POINT(0 0)", "BOX(0 0,2 2)", false, true); - test_box_of("POINT(2 2)", "BOX(0 0,2 2)", false, true); - test_box_of("POINT(0 1)", "BOX(0 0,2 2)", false, true); - test_box_of("POINT(1 0)", "BOX(0 0,2 2)", false, true); - test_box_of("POINT(3 3)", "BOX(0 0,2 2)", false, false); -} - - -template -void test_all() -{ - test_box(); - - typedef bg::model::polygon polygon; - - std::string const box = "POLYGON((0 0,0 2,2 2,2 0,0 0))"; - std::string const triangle = "POLYGON((0 0,0 4,6 0,0 0))"; - std::string const with_hole = "POLYGON((0 0,0 3,3 3,3 0,0 0),(1 1,2 1,2 2,1 2,1 1))"; - - - test_geometry("b1", "POINT(1 1)", box, true); - test_geometry("b2", "POINT(3 3)", box, false); - - // Test ALL corners (officialy false but some strategies might answer true) - test_geometry("b3a", "POINT(0 0)", box, false, "f"); - test_geometry("b3b", "POINT(0 2)", box, false); - test_geometry("b3c", "POINT(2 2)", box, false); - test_geometry("b3d", "POINT(2 0)", box, false); - - // Test ALL sides (officialy false but some strategies might answer true) - test_geometry("b4a", "POINT(0 1)", box, false, "f"); - test_geometry("b4b", "POINT(1 2)", box, false, "c"); - test_geometry("b4c", "POINT(2 1)", box, false); - test_geometry("b4d", "POINT(1 0)", box, false, "f"); - - - test_geometry("t1", "POINT(1 1)", triangle, true); - test_geometry("t2", "POINT(3 3)", triangle, false); - - test_geometry("t3a", "POINT(0 0)", triangle, false, "f"); - test_geometry("t3b", "POINT(0 4)", triangle, false, "c"); - test_geometry("t3c", "POINT(5 0)", triangle, false, "f"); - - test_geometry("t4a", "POINT(0 2)", triangle, false, "f"); - test_geometry("t4b", "POINT(3 2)", triangle, false); - test_geometry("t4c", "POINT(2 0)", triangle, false, "f"); - - - test_geometry("h1", "POINT(0.5 0.5)", with_hole, true); - test_geometry("h2a", "POINT(1.5 1.5)", with_hole, false); - test_geometry("h2b", "POINT(5 5)", with_hole, false); - - test_geometry("h3a", "POINT(1 1)", with_hole, false, "c"); - test_geometry("h3b", "POINT(2 2)", with_hole, false, "f"); - test_geometry("h3c", "POINT(0 0)", with_hole, false, "f"); - - test_geometry("h4a", "POINT(1 1.5)", with_hole, false); - test_geometry("h4b", "POINT(1.5 2)", with_hole, false, "f"); - - // Lying ON (one of the sides of) interior ring - test_geometry("#77-1", "POINT(6 3.5)", "POLYGON((5 3,5 4,4 4,4 5,3 5,3 6,5 6,5 5,7 5,7 6,8 6,8 5,9 5,9 2,8 2,8 1,7 1,7 2,5 2,5 3),(6 3,8 3,8 4,6 4,6 3))", false); -} - - -void test_spherical() -{ - typedef bg::model::point > point; - typedef bg::model::polygon polygon; - - // Ticket #9354 - test_geometry_default( - "#9354", - "POINT(-78.1239 25.9556)", - "POLYGON((-97.08466667 25.95683333, -97.13683333 25.954, -97.1 26, -97.08466667 25.95683333))", - false); - - test_geometry_default( - "sph1N", - "POINT(0 10.001)", - "POLYGON((-10 10, 10 10, 10 -10, -10 -10, -10 10))", - bg::strategy::side::spherical_side_formula<>::apply( - point(-10, 10), - point(10, 10), - point(0, 10.001)) == -1 // right side - /*true*/); - test_geometry_default( - "sph1S", - "POINT(0 -10.001)", - "POLYGON((-10 10, 10 10, 10 -10, -10 -10, -10 10))", - bg::strategy::side::spherical_side_formula<>::apply( - point(10, -10), - point(-10, -10), - point(0, -10.001)) == -1 // right side - /*true*/); - - test_geometry_default( - "sph2S", - "POINT(0 10.001)", - "POLYGON((-10 20, 10 20, 10 10, -10 10, -10 20))", - bg::strategy::side::spherical_side_formula<>::apply( - point(10, 10), - point(-10, 10), - point(0, 10.001)) == -1 // right side - /*false*/); - - test_geometry_default( - "sph3N", - "POINT(0 10)", - "POLYGON((-10 10, 10 10, 10 -10, -10 -10, -10 10))", - bg::strategy::side::spherical_side_formula<>::apply( - point(-10, 10), - point(10, 10), - point(0, 10.001)) == -1 // right side - /*true*/); - test_geometry_default( - "sph3S", - "POINT(0 -10)", - "POLYGON((-10 10, 10 10, 10 -10, -10 -10, -10 10))", - bg::strategy::side::spherical_side_formula<>::apply( - point(10, -10), - point(-10, -10), - point(0, -10.001)) == -1 // right side - /*true*/); - - test_geometry_default( - "sphEq1", - "POINT(179 10)", - "POLYGON((170 10, -170 10, -170 0, 170 0, 170 10))", - true, - false); - test_geometry_default( - "sphEq2", - "POINT(179 10)", - "POLYGON((170 20, -170 20, -170 10, 170 10, 170 20))", - true, - false); - test_geometry_default( - "sphEq3", - "POINT(-179 10)", - "POLYGON((170 10, -170 10, -170 0, 170 0, 170 10))", - true, - false); - test_geometry_default( - "sphEq4", - "POINT(-179 10)", - "POLYGON((170 20, -170 20, -170 10, 170 10, 170 20))", - true, - false); - - test_geometry_default( - "sphEq5", - "POINT(169 10)", - "POLYGON((170 20, -170 20, -170 10, 170 10, 170 20))", - false, - false); - test_geometry_default( - "sphEq6", - "POINT(-169 10)", - "POLYGON((170 20, -170 20, -170 10, 170 10, 170 20))", - false, - false); - test_geometry_default( - "sphEq7", - "POINT(169 10)", - "POLYGON((170 10, -170 10, -170 0, 170 0, 170 10))", - false, - false); - test_geometry_default( - "sphEq8", - "POINT(-169 10)", - "POLYGON((170 10, -170 10, -170 0, 170 0, 170 10))", - false, - false); -} - -int test_main(int, char* []) -{ - test_all >(); - test_all >(); - - test_spherical(); - -#if defined(HAVE_TTMATH) - test_all >(); -#endif - - return 0; -} diff --git a/test/test_common/test_point.hpp b/test/test_common/test_point.hpp index 54616f0db..31b124867 100644 --- a/test/test_common/test_point.hpp +++ b/test/test_common/test_point.hpp @@ -106,6 +106,6 @@ template<> struct access BOOST_GEOMETRY_REGISTER_POINT_3D_CONST(test::test_const_point, float, boost::geometry::cs::cartesian, - c1, c2, c3); + c1, c2, c3) #endif // GEOMETRY_TEST_TEST_COMMON_TEST_POINT_HPP diff --git a/test/test_geometries/custom_lon_lat_point.hpp b/test/test_geometries/custom_lon_lat_point.hpp new file mode 100644 index 000000000..7758a1370 --- /dev/null +++ b/test/test_geometries/custom_lon_lat_point.hpp @@ -0,0 +1,140 @@ +// 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_GEOMETRY_TEST_TEST_GEOMETRIES_CUSTOM_LON_LAT_POINT_HPP +#define BOOST_GEOMETRY_TEST_TEST_GEOMETRIES_CUSTOM_LON_LAT_POINT_HPP + +#include + +#include +#include +#include +#include +#include +#include + + +// read/write longitude/latitude point +template +struct rw_lon_lat_point +{ + CoordinateType longitude, latitude; +}; + + +namespace boost { namespace geometry { namespace traits +{ +template +struct tag > +{ + typedef point_tag type; +}; + +template +struct coordinate_type > +{ + typedef CoordinateType type; +}; + +template +struct coordinate_system > +{ + typedef CoordinateSystem type; +}; + +template +struct dimension > + : boost::mpl::int_<2> +{}; + +template +< + typename CoordinateType, + typename CoordinateSystem, + std::size_t Dimension +> +struct access, Dimension> +{ + static inline CoordinateType + get(rw_lon_lat_point const& p) + { + return (Dimension == 0) ? p.longitude : p.latitude; + } + + static inline + void set(rw_lon_lat_point& p, + CoordinateType const& value) + { + if (Dimension == 0) + { + p.longitude = value; + } + else + { + p.latitude = value; + } + } +}; + +}}} // namespace boost::geometry::traits + + +// read-only longitude/latitude point +template +struct ro_lon_lat_point +{ + CoordinateType longitude, latitude; +}; + + +namespace boost { namespace geometry { namespace traits +{ +template +struct tag > +{ + typedef point_tag type; +}; + +template +struct coordinate_type > +{ + typedef CoordinateType type; +}; + +template +struct coordinate_system > +{ + typedef CoordinateSystem type; +}; + +template +struct dimension > + : boost::mpl::int_<2> +{}; + +template +< + typename CoordinateType, + typename CoordinateSystem, + std::size_t Dimension +> +struct access, Dimension> +{ + static inline CoordinateType + get(ro_lon_lat_point const& p) + { + return (Dimension == 0) ? p.longitude : p.latitude; + } +}; + +}}} // namespace boost::geometry::traits + + +#endif // BOOST_GEOMETRY_TEST_TEST_GEOMETRIES_CUSTOM_LON_LAT_POINT_HPP diff --git a/test/to_svg.hpp b/test/to_svg.hpp index da1fea778..e2eccd54f 100644 --- a/test/to_svg.hpp +++ b/test/to_svg.hpp @@ -187,6 +187,52 @@ inline void turns_to_svg(Turns const& turns, Mapper & mapper, bool /*enrich*/ = } } +template +inline void geom_to_svg(G1 const& g1, bg::svg_mapper

& mapper) +{ + mapper.add(g1); + + mapper.map(g1, "fill-opacity:0.5;fill:rgb(153,204,0);" + "stroke:rgb(153,204,0);stroke-width:3"); +} + +template +inline void geom_to_svg(G1 const& g1, G2 const& g2, bg::svg_mapper

& mapper) +{ + mapper.add(g1); + mapper.add(g2); + + mapper.map(g1, "fill-opacity:0.5;fill:rgb(153,204,0);" + "stroke:rgb(153,204,0);stroke-width:3"); + mapper.map(g2, "fill-opacity:0.3;fill:rgb(51,51,153);" + "stroke:rgb(51,51,153);stroke-width:3"); +} + +template +inline void geom_to_svg(G1 const& g1, std::string const& filename) +{ + namespace bg = boost::geometry; + typedef typename bg::point_type::type mapper_point_type; + + std::ofstream svg(filename.c_str(), std::ios::trunc); + bg::svg_mapper mapper(svg, 500, 500); + + geom_to_svg(g1, mapper); +} + +template +inline void geom_to_svg(G1 const& g1, G2 const& g2, std::string const& filename) +{ + namespace bg = boost::geometry; + typedef typename bg::point_type::type mapper_point_type; + + std::ofstream svg(filename.c_str(), std::ios::trunc); + bg::svg_mapper mapper(svg, 500, 500); + + geom_to_svg(g1, g2, mapper); +} + + struct to_svg_assign_policy : bg::detail::overlay::assign_null_policy { diff --git a/test/views/closeable_view.cpp b/test/views/closeable_view.cpp index dde61a067..3cbabbf95 100644 --- a/test/views/closeable_view.cpp +++ b/test/views/closeable_view.cpp @@ -22,7 +22,7 @@ #include #include -BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian); +BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)