diff --git a/README.md b/README.md new file mode 100644 index 000000000..cb69a03c9 --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +![Boost.Geometry](./doc/other/logo/logo_bkg.png) + +Boost.Geometry, part of collection of the [Boost C++ Libraries](http://github.com/boostorg), defines concepts, primitives and algorithms for solving geometry problems. + +### Directories + +* **doc** - QuickBook documentation sources +* **examples** - Boost.Geometry examples +* **_extensions_** - examples and tests for the extensions - _develop branch_ +* **include** - the sourcecode of Boost.Geometry +* **index** - examples and tests for the Spatial Index +* **test** - Boost.Geometry unit tests + +### More information + +* [Wiki](http://github.com/boostorg/geometry/wiki) +* [Documentation](http://boost.org/libs/geometry) diff --git a/doc/other/logo/DENMARK.TTF b/doc/other/logo/DENMARK.TTF new file mode 100644 index 000000000..c2623381f Binary files /dev/null and b/doc/other/logo/DENMARK.TTF differ diff --git a/doc/other/logo/favicon.ico b/doc/other/logo/favicon.ico new file mode 100644 index 000000000..fa937082d Binary files /dev/null and b/doc/other/logo/favicon.ico differ diff --git a/doc/other/logo/logo.svg b/doc/other/logo/logo.svg new file mode 100644 index 000000000..5cb2b0630 --- /dev/null +++ b/doc/other/logo/logo.svg @@ -0,0 +1,5012 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GEOMETRY + + + boost + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GEOMETRY + + + boost + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GEOMETRY + + + boost + + + + diff --git a/doc/other/logo/logo128x128.png b/doc/other/logo/logo128x128.png new file mode 100644 index 000000000..4001bca1b Binary files /dev/null and b/doc/other/logo/logo128x128.png differ diff --git a/doc/other/logo/logo_400x400.png b/doc/other/logo/logo_400x400.png new file mode 100644 index 000000000..1db4eca0d Binary files /dev/null and b/doc/other/logo/logo_400x400.png differ diff --git a/doc/other/logo/logo_bkg.png b/doc/other/logo/logo_bkg.png new file mode 100644 index 000000000..06e66a434 Binary files /dev/null and b/doc/other/logo/logo_bkg.png differ diff --git a/doc/other/logo/logo_tr_blue.png b/doc/other/logo/logo_tr_blue.png new file mode 100644 index 000000000..55844a953 Binary files /dev/null and b/doc/other/logo/logo_tr_blue.png differ diff --git a/doc/other/logo/logo_tr_white.png b/doc/other/logo/logo_tr_white.png new file mode 100644 index 000000000..d9b425919 Binary files /dev/null and b/doc/other/logo/logo_tr_white.png differ diff --git a/include/boost/geometry/algorithms/covered_by.hpp b/include/boost/geometry/algorithms/covered_by.hpp index 01405d81b..2846d5673 100644 --- a/include/boost/geometry/algorithms/covered_by.hpp +++ b/include/boost/geometry/algorithms/covered_by.hpp @@ -4,6 +4,9 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 2013. +// Modifications copyright (c) 2013, Oracle and/or its affiliates. + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -77,14 +80,7 @@ struct covered_by template static inline bool apply(Point const& point, Ring const& ring, Strategy const& strategy) { - return detail::within::point_in_ring - < - Point, - Ring, - order_as_direction::value>::value, - geometry::closure::value, - Strategy - >::apply(point, ring, strategy) >= 0; + return detail::within::point_in_geometry(point, ring, strategy) >= 0; } }; @@ -94,14 +90,17 @@ struct covered_by template static inline bool apply(Point const& point, Polygon const& polygon, Strategy const& strategy) { - return detail::within::point_in_polygon - < - Point, - Polygon, - order_as_direction::value>::value, - geometry::closure::value, - Strategy - >::apply(point, polygon, strategy) >= 0; + return detail::within::point_in_geometry(point, polygon, strategy) >= 0; + } +}; + +template +struct covered_by +{ + template static inline + bool apply(Point const& point, Linestring const& linestring, Strategy const& strategy) + { + return detail::within::point_in_geometry(point, linestring, strategy) >= 0; } }; diff --git a/include/boost/geometry/algorithms/detail/disjoint.hpp b/include/boost/geometry/algorithms/detail/disjoint.hpp index f25e8a843..d1b30e0ab 100644 --- a/include/boost/geometry/algorithms/detail/disjoint.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint.hpp @@ -3,6 +3,7 @@ // 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) 2013 Adam Wulkiewicz, Lodz, Poland // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -30,6 +31,7 @@ #include +#include namespace boost { namespace geometry @@ -65,38 +67,6 @@ struct disjoint_interrupt_policy -template -< - typename Point1, typename Point2, - std::size_t Dimension, std::size_t DimensionCount -> -struct point_point -{ - static inline bool apply(Point1 const& p1, Point2 const& p2) - { - if (! geometry::math::equals(get(p1), get(p2))) - { - return true; - } - return point_point - < - Point1, Point2, - Dimension + 1, DimensionCount - >::apply(p1, p2); - } -}; - - -template -struct point_point -{ - static inline bool apply(Point1 const& , Point2 const& ) - { - return false; - } -}; - - template < typename Point, typename Box, @@ -318,44 +288,10 @@ inline bool disjoint_box_box(Box1 const& box1, Box2 const& box2) } - -/*! - \brief Internal utility function to detect of points are disjoint - \note To avoid circular references - */ -template -inline bool disjoint_point_point(Point1 const& point1, Point2 const& point2) -{ - return point_point - < - Point1, Point2, - 0, dimension::type::value - >::apply(point1, point2); -} - - }} // namespace detail::disjoint #endif // DOXYGEN_NO_DETAIL -#ifndef DOXYGEN_NO_DETAIL -namespace detail { namespace equals -{ - -/*! - \brief Internal utility function to detect of points are disjoint - \note To avoid circular references - */ -template -inline bool equals_point_point(Point1 const& point1, Point2 const& point2) -{ - return ! detail::disjoint::disjoint_point_point(point1, point2); -} - - -}} // namespace detail::equals -#endif // DOXYGEN_NO_DETAIL - }} // namespace boost::geometry #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_HPP diff --git a/include/boost/geometry/algorithms/detail/disjoint/point_point.hpp b/include/boost/geometry/algorithms/detail/disjoint/point_point.hpp new file mode 100644 index 000000000..e762e1fdd --- /dev/null +++ b/include/boost/geometry/algorithms/detail/disjoint/point_point.hpp @@ -0,0 +1,104 @@ +// 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) 2013 Adam Wulkiewicz, Lodz, Poland + +// 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_DISJOINT_POINT_POINT_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_POINT_POINT_HPP + +#include + +#include +#include + +#include + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace disjoint +{ + +template +< + typename Point1, typename Point2, + std::size_t Dimension, std::size_t DimensionCount +> +struct point_point +{ + static inline bool apply(Point1 const& p1, Point2 const& p2) + { + if (! geometry::math::equals(get(p1), get(p2))) + { + return true; + } + return point_point + < + Point1, Point2, + Dimension + 1, DimensionCount + >::apply(p1, p2); + } +}; + + +template +struct point_point +{ + static inline bool apply(Point1 const& , Point2 const& ) + { + return false; + } +}; + + +/*! + \brief Internal utility function to detect of points are disjoint + \note To avoid circular references + */ +template +inline bool disjoint_point_point(Point1 const& point1, Point2 const& point2) +{ + return point_point + < + Point1, Point2, + 0, dimension::type::value + >::apply(point1, point2); +} + + +}} // namespace detail::disjoint +#endif // DOXYGEN_NO_DETAIL + + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace equals +{ + +/*! + \brief Internal utility function to detect of points are disjoint + \note To avoid circular references + */ +template +inline bool equals_point_point(Point1 const& point1, Point2 const& point2) +{ + return ! detail::disjoint::disjoint_point_point(point1, point2); +} + + +}} // namespace detail::equals +#endif // DOXYGEN_NO_DETAIL + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_POINT_POINT_HPP diff --git a/include/boost/geometry/algorithms/detail/overlay/do_reverse.hpp b/include/boost/geometry/algorithms/detail/overlay/do_reverse.hpp new file mode 100644 index 000000000..15100f8d0 --- /dev/null +++ b/include/boost/geometry/algorithms/detail/overlay/do_reverse.hpp @@ -0,0 +1,47 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_DO_REVERSE_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_DO_REVERSE_HPP + +#include + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace overlay +{ + +// Metafunction helper for intersection and union +template +struct do_reverse {}; + +template <> +struct do_reverse : boost::false_type {}; + +template <> +struct do_reverse : boost::true_type {}; + +template <> +struct do_reverse : boost::true_type {}; + +template <> +struct do_reverse : boost::false_type {}; + + +}} // namespace detail::overlay +#endif // DOXYGEN_NO_DETAIL + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_DO_REVERSE_HPP diff --git a/include/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp b/include/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp index 5f7f08af4..c06c612a9 100644 --- a/include/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp @@ -329,7 +329,7 @@ private : inline bool consider_iu_iu(Indexed const& left, Indexed const& right, - std::string const& header) const + std::string const& header, bool redo = false) const { //debug_consider(0, left, right, header); @@ -437,6 +437,13 @@ private : std::cout << " iu/iu unhandled" << std::endl; debug_consider(0, left, right, header, false, "unhandled", left.index < right.index); #endif + if (! redo) + { + // In some cases behaviour is not symmetrical. TODO: fix this properly + // OR: alternatively we might consider calling all these functions one-way anyway + return ! consider_iu_iu(right, left, header, true); + } + return left.index < right.index; } diff --git a/include/boost/geometry/algorithms/detail/overlay/overlay.hpp b/include/boost/geometry/algorithms/detail/overlay/overlay.hpp index a13da97a9..99d897070 100644 --- a/include/boost/geometry/algorithms/detail/overlay/overlay.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/overlay.hpp @@ -1,6 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -36,7 +37,7 @@ #include #include #include - +#include #ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE # include @@ -309,24 +310,6 @@ std::cout << "traverse" << std::endl; }; -// Metafunction helper for intersection and union -template -struct do_reverse {}; - -template <> -struct do_reverse : boost::false_type {}; - -template <> -struct do_reverse : boost::true_type {}; - -template <> -struct do_reverse : boost::true_type {}; - -template <> -struct do_reverse : boost::false_type {}; - - - }} // namespace detail::overlay #endif // DOXYGEN_NO_DETAIL diff --git a/include/boost/geometry/algorithms/detail/sub_geometry.hpp b/include/boost/geometry/algorithms/detail/sub_geometry.hpp new file mode 100644 index 000000000..b6e8f2f14 --- /dev/null +++ b/include/boost/geometry/algorithms/detail/sub_geometry.hpp @@ -0,0 +1,128 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. + +// This file was modified by Oracle on 2013. +// Modifications copyright (c) 2013, Oracle and/or its affiliates. + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_MYSQL_ALGORITHMS_DETAIL_SUB_GEOMETRY_HPP +#define BOOST_GEOMETRY_MYSQL_ALGORITHMS_DETAIL_SUB_GEOMETRY_HPP + +namespace boost { namespace geometry { + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace sub_geometry { + +// TODO: later implement Geometry-specialized index_type +// polygons/multi_polygons also need ring_index member +struct index_type +{ + index_type() : multi_index(-1) {} + + int multi_index; + + inline bool operator<(index_type const& i) const + { + return multi_index < i.multi_index; + } + + inline bool operator==(index_type const& i) const + { + return multi_index == i.multi_index; + } +}; + +// TODO: later remove IsMulti and move to multi directory +template ::type, + bool IsMulti = boost::is_base_of::value> +struct get_dispatch +{ + BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY, (Geometry, Tag)); +}; + +template +struct get_dispatch +{ + typedef Geometry & result_type; + + template static inline + result_type apply(Geometry & geometry, Id const&) + { + return geometry; + } +}; + +template +struct get_dispatch +{ + typedef typename geometry::ring_type::type & result_type; + + template static inline + result_type apply(Geometry & geometry, Id const& id) + { + if ( id.ring_index < 0 ) + return geometry::exterior_ring(geometry); + else + { + BOOST_ASSERT( id.ring_index < boost::size(geometry::interior_rings(geometry)) ); + + return *(boost::begin(geometry::interior_rings(geometry)) + id.ring_index); + } + } +}; + +template +struct get_dispatch +{ + typedef typename boost::range_value::type sub_type; + typedef typename get_dispatch::result_type result_type; + + template static inline + result_type apply(Geometry & geometry, Id const& id) + { + BOOST_ASSERT(0 <= id.multi_index); + return get_dispatch::apply(*(boost::begin(geometry) + id.multi_index), id); + } +}; + +template +struct result_type +{ + typedef typename get_dispatch::result_type type; +}; + +//template +//struct result_type +//{ +// typedef typename get_dispatch::result_type type; +//}; + +// This function also works for geometry::segment_identifier + +template inline +typename get_dispatch::result_type +get(Geometry & g, Id const& id) +{ + return get_dispatch::apply(g, id); +}; + +//template inline +//typename get_dispatch::result_type +//get(Geometry const& g, Id const& id) +//{ +// return get_dispatch::apply(g, id); +//}; + +} // namespace sub_geometry + +} // namespace detail +#endif + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_MYSQL_ALGORITHMS_DETAIL_SUB_GEOMETRY_HPP diff --git a/include/boost/geometry/algorithms/detail/within/point_in_geometry.hpp b/include/boost/geometry/algorithms/detail/within/point_in_geometry.hpp new file mode 100644 index 000000000..f31087e56 --- /dev/null +++ b/include/boost/geometry/algorithms/detail/within/point_in_geometry.hpp @@ -0,0 +1,217 @@ +// 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. + +// This file was modified by Oracle on 2013. +// Modifications copyright (c) 2013, Oracle and/or its affiliates. + +// 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_WITHIN_POINT_IN_GEOMETRY_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_POINT_IN_GEOMETRY_HPP + +#include + +#include +#include +#include +#include + +namespace boost { namespace geometry { + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace within { + +template inline +int point_in_range(Point const& point, Range const& range, Strategy const& strategy) +{ + typedef typename boost::range_iterator::type iterator_type; + typename Strategy::state_type state; + iterator_type it = boost::begin(range); + iterator_type end = boost::end(range); + + bool stop = false; + for ( iterator_type previous = it++ ; + it != end && ! stop ; + ++previous, ++it ) + { + if ( ! strategy.apply(point, *previous, *it, state) ) + { + stop = true; + } + } + + return strategy.result(state); +} + +// checks the relation between a point P and geometry G +// returns 1 if P is in the interior of G +// returns 0 if P is on the boundry of G +// returns -1 if P is in the exterior of G + +template ::type> +struct point_in_geometry_dispatch +{ + BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (T)); +}; + +template +struct point_in_geometry_dispatch +{ + template static inline + int apply(Point const& pt, Box const& box, Strategy const& strategy) + { + // this is different Strategy concept than the one used for ranges + return strategy.apply(pt, box); + } +}; + +template +struct point_in_geometry_dispatch +{ + template static inline + int apply(Point const& pt, Linestring const& ls, Strategy const& strategy) + { + std::size_t count = boost::size(ls); + if ( 2 <= count ) + { + if ( 0 != detail::within::point_in_range(pt, ls, strategy) ) + return -1; + + // if the linestring doesn't have a boundary + if ( detail::equals::equals_point_point(*boost::begin(ls), *(--boost::end(ls))) ) + return 1; + // else if the point is equal to the one of the terminal points + else if ( detail::equals::equals_point_point(pt, *boost::begin(ls)) + || detail::equals::equals_point_point(pt, *(--boost::end(ls))) ) + return 0; + else + return 1; + } + else if ( 1 == count + && detail::equals::equals_point_point(pt, *boost::begin(ls)) ) + return 0; + + return -1; + } +}; + +template +struct point_in_geometry_dispatch +{ + template static inline + int apply(Point const& point, Ring const& ring, Strategy const& strategy) + { + static const iterate_direction direction = order_as_direction::value>::value; + static const closure_selector closure = geometry::closure::value; + + if (int(boost::size(ring)) + < core_detail::closure::minimum_ring_size::value) + { + return -1; + } + + typedef typename reversible_view::type rev_view_type; + typedef typename closeable_view + < + rev_view_type const, closure + >::type cl_view_type; + typedef typename boost::range_iterator::type iterator_type; + + rev_view_type rev_view(ring); + cl_view_type view(rev_view); + + return point_in_range(point, view, strategy); + } +}; + +//// Polygon: in exterior ring, and if so, not within interior ring(s) +template +struct point_in_geometry_dispatch +{ + template + static inline int apply(Point const& point, Polygon const& poly, + Strategy const& strategy) + { + int const code = point_in_geometry_dispatch + < + typename ring_type::type + >::apply(point, exterior_ring(poly), strategy); + + if (code == 1) + { + typename interior_return_type::type rings + = interior_rings(poly); + for (BOOST_AUTO_TPL(it, boost::begin(rings)); + it != boost::end(rings); + ++it) + { + int const interior_code = point_in_geometry_dispatch + < + typename ring_type::type + >::apply(point, *it, strategy); + + if (interior_code != -1) + { + // If 0, return 0 (touch) + // If 1 (inside hole) return -1 (outside polygon) + // If -1 (outside hole) check other holes if any + return -interior_code; + } + } + } + return code; + } +}; + +// 1 - in the interior +// 0 - in the boundry +// -1 - in the exterior +template inline +int point_in_geometry(P const& p, G const& g, Strategy const& strategy) +{ + BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategyPolygonal) ); + + return point_in_geometry_dispatch::apply(p, g, strategy); +} + +template inline +int point_in_geometry(P const& p, G const& g) +{ + typedef typename point_type

::type point_type1; + typedef typename point_type::type point_type2; + + typedef typename strategy::within::services::default_strategy + < + typename tag

::type, + typename tag::type, + typename tag

::type, + typename tag_cast::type, areal_tag>::type, + typename tag_cast + < + typename cs_tag::type, spherical_tag + >::type, + typename tag_cast + < + typename cs_tag::type, spherical_tag + >::type, + P, + G + >::type strategy_type; + + return point_in_geometry(p, g, strategy_type()); +} + +}} // namespace detail::within +#endif // DOXYGEN_NO_DETAIL + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_POINT_IN_GEOMETRY_HPP diff --git a/include/boost/geometry/algorithms/detail/within/within_no_turns.hpp b/include/boost/geometry/algorithms/detail/within/within_no_turns.hpp new file mode 100644 index 000000000..3540985af --- /dev/null +++ b/include/boost/geometry/algorithms/detail/within/within_no_turns.hpp @@ -0,0 +1,216 @@ +// 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. + +// This file was modified by Oracle on 2013. +// Modifications copyright (c) 2013, Oracle and/or its affiliates. + +// 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_WITHIN_WITHIN_NO_TURNS_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_WITHIN_NO_TURNS_HPP + +#include +#include + +namespace boost { namespace geometry { + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace within { + +// returns true if G1 is within G2 +// this function should be called only if there are no intersection points +// otherwise it may return invalid result +// e.g. when non-first point of G1 is outside G2 or when some rings of G1 are the same as rings of G2 + +template ::type, typename T2 = typename geometry::tag::type> +struct within_no_turns_dispatch +{ + template static inline + bool apply(G1 const& g1, G2 const& g2, S const& s) + { + typedef typename geometry::point_type::type point1_type; + point1_type p; + if ( !geometry::point_on_border(p, g1) ) + return false; + + return point_in_geometry(p, g2, s) >= 0; + } +}; + +template +struct within_no_turns_dispatch +{ + template static inline + bool apply(G1 const& g1, G2 const& g2, S const& s) + { + typedef typename geometry::point_type::type point1_type; + typedef typename geometry::point_type::type point2_type; + point1_type p; + if ( !geometry::point_on_border(p, g1) ) + return false; + // check if one of ring points is outside the polygon + if ( point_in_geometry(p, g2, s) < 0 ) + return false; + // Now check if holes of G2 aren't inside G1 + typedef typename boost::range_const_iterator + < + typename geometry::interior_type::type + >::type iterator; + for ( iterator it = boost::begin(geometry::interior_rings(g2)) ; + it != boost::end(geometry::interior_rings(g2)) ; + ++it ) + { + point2_type p; + if ( !geometry::point_on_border(p, *it) ) + return false; + if ( point_in_geometry(p, g1, s) > 0 ) + return false; + } + return true; + } +}; + +template +struct within_no_turns_dispatch +{ + template static inline + bool apply(G1 const& g1, G2 const& g2, S const& s) + { + typedef typename geometry::point_type::type point1_type; + typedef typename geometry::point_type::type point2_type; + point1_type p; + if ( !geometry::point_on_border(p, g1) ) + return false; + // check if one of ring points is outside the polygon + if ( point_in_geometry(p, g2, s) < 0 ) + return false; + // Now check if holes of G2 aren't inside G1 + typedef typename boost::range_const_iterator + < + typename geometry::interior_type::type + >::type iterator2; + for ( iterator2 it = boost::begin(geometry::interior_rings(g2)) ; + it != boost::end(geometry::interior_rings(g2)) ; + ++it ) + { + point2_type p2; + if ( !geometry::point_on_border(p2, *it) ) + return false; + // if the hole of G2 is inside G1 + if ( point_in_geometry(p2, g1, s) > 0 ) + { + // if it's also inside one of the G1 holes, it's ok + bool ok = false; + typedef typename boost::range_const_iterator + < + typename geometry::interior_type::type + >::type iterator1; + for ( iterator1 it1 = boost::begin(geometry::interior_rings(g1)) ; + it1 != boost::end(geometry::interior_rings(g1)) ; + ++it1 ) + { + if ( point_in_geometry(p2, *it1, s) < 0 ) + { + ok = true; + break; + } + } + if ( !ok ) + return false; + } + } + return true; + } +}; + +// TODO: later move it to directory boost/geometry/multi/algorithms/detail/within + +template ::type, + typename T2 = typename geometry::tag::type, + bool IsMulti1 = boost::is_base_of::value, + bool IsMulti2 = boost::is_base_of::value> +struct within_no_turns_multi_dispatch +{ + template static inline + bool apply(G1 const& g1, G2 const& g2, S const& s) + { + return within_no_turns_dispatch::apply(g1, g2, s); + } +}; + +template +struct within_no_turns_multi_dispatch +{ + template static inline + bool apply(G1 const& g1, G2 const& g2, S const& s) + { + // All values of G1 must be inside G2 + typedef typename boost::range_value::type subgeometry1; + typedef typename boost::range_const_iterator::type iterator; + for ( iterator it = boost::begin(g1) ; it != boost::end(g1) ; ++it ) + { + if ( !within_no_turns_dispatch::apply(*it, g2, s) ) + return false; + } + return true; + } +}; + +template +struct within_no_turns_multi_dispatch +{ + template static inline + bool apply(G1 const& g1, G2 const& g2, S const& s) + { + // G1 must be within at least one value of G2 + typedef typename boost::range_value::type subgeometry2; + typedef typename boost::range_const_iterator::type iterator; + for ( iterator it = boost::begin(g2) ; it != boost::end(g2) ; ++it ) + { + if ( within_no_turns_dispatch::apply(g1, *it, s) ) + return true; + } + return false; + } +}; + +template +struct within_no_turns_multi_dispatch +{ + template static inline + bool apply(G1 const& g1, G2 const& g2, S const& s) + { + // each value of G1 must be inside at least one value of G2 + typedef typename boost::range_value::type subgeometry1; + typedef typename boost::range_const_iterator::type iterator; + for ( iterator it = boost::begin(g1) ; it != boost::end(g1) ; ++it ) + { + if ( !within_no_turns_multi_dispatch::apply(*it, g2, s) ) + return false; + } + return true; + } +}; + +template inline +bool within_no_turns(G1 const& g1, G2 const& g2, S const& s) +{ + return within_no_turns_multi_dispatch::apply(g1, g2, s); +} + +}} // namespace detail::within +#endif // DOXYGEN_NO_DETAIL + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_WITHIN_NO_TURNS_HPP diff --git a/include/boost/geometry/algorithms/disjoint.hpp b/include/boost/geometry/algorithms/disjoint.hpp index d7bc4d58a..239f83145 100644 --- a/include/boost/geometry/algorithms/disjoint.hpp +++ b/include/boost/geometry/algorithms/disjoint.hpp @@ -5,6 +5,9 @@ // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland. +// This file was modified by Oracle on 2013. +// Modifications copyright (c) 2013, Oracle and/or its affiliates. + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -42,6 +45,10 @@ #include +#include +#include +#include + namespace boost { namespace geometry { @@ -115,21 +122,20 @@ struct disjoint_linear typedef overlay::turn_info turn_info; std::deque turns; + static const bool reverse1 = overlay::do_reverse::value>::value; // should be false + static const bool reverse2 = overlay::do_reverse::value>::value; // should be false + // Specify two policies: // 1) Stop at any intersection // 2) In assignment, include also degenerate points (which are normally skipped) disjoint_interrupt_policy policy; geometry::get_turns < - false, false, + reverse1, reverse2, assign_disjoint_policy >(geometry1, geometry2, detail::no_rescale_policy(), turns, policy); - if (policy.has_intersections) - { - return false; - } - return true; + return !policy.has_intersections; } }; @@ -230,6 +236,59 @@ struct disjoint_linestring_box } }; +template +struct disjoint_point_linear +{ + static inline + bool apply(Point const& pt, Geometry const& g) + { + return !geometry::covered_by(pt, g); + } +}; + +// computes disjointness of segment and linestring +template +struct disjoint_linestring_segment +{ + static inline + bool apply(Linestring const& ls, Segment const& seg) + { + return disjoint_linear + < + Linestring, segment_view + >::apply(ls, geometry::segment_view(seg)); + } +}; + +template +struct disjoint_linear_areal +{ + static inline + bool apply(Geometry1 const& g1, Geometry2 const& g2) + { + // if there are intersections - return false + if ( !disjoint_linear::apply(g1, g2) ) + return false; + + typedef typename point_type::type point1_type; + point1_type p; + geometry::point_on_border(p, g1); + return !geometry::covered_by(p, g2); + } +}; + +template +struct disjoint_segment_areal +{ + static inline + bool apply(Segment const& seg, Geometry const& g) + { + return disjoint_linear_areal + < + segment_view, Geometry + >::apply(segment_view(seg), g); + } +}; }} // namespace detail::disjoint #endif // DOXYGEN_NO_DETAIL @@ -312,11 +371,6 @@ struct disjoint : detail::disjoint::disjoint_segment {}; -template -struct disjoint - : detail::disjoint::disjoint_linear -{}; - template struct disjoint : detail::disjoint::disjoint_segment_box @@ -327,6 +381,72 @@ struct disjoint {}; +//template +//struct disjoint +// : detail::disjoint::disjoint_linear +//{}; +template +struct disjoint + : detail::disjoint::disjoint_linestring_segment +{}; + +template +struct disjoint + : detail::disjoint::disjoint_segment_areal +{}; + +template +struct disjoint +{ + static inline + bool apply(Polygon const& g1, Segment const& g2) + { + return detail::disjoint::disjoint_segment_areal::apply(g2, g1); + } +}; + +template +struct disjoint + : public detail::disjoint::disjoint_linear_areal +{}; + +template +struct disjoint + : public detail::disjoint::disjoint_linear_areal +{}; + +// move the following specializations to multi/algorithms/disjoint.hpp? + +template +struct disjoint + : public detail::disjoint::disjoint_linear_areal +{}; + +template +struct disjoint + : public detail::disjoint::disjoint_linear_areal +{}; + +template +struct disjoint + : public detail::disjoint::disjoint_linear_areal +{}; + +template +struct disjoint + : public detail::disjoint::disjoint_linear_areal +{}; + +template +struct disjoint + : public detail::disjoint::disjoint_point_linear +{}; + +template +struct disjoint + : public detail::disjoint::disjoint_point_linear +{}; + } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH diff --git a/include/boost/geometry/algorithms/touches.hpp b/include/boost/geometry/algorithms/touches.hpp index 18c37c86d..2523a26d2 100644 --- a/include/boost/geometry/algorithms/touches.hpp +++ b/include/boost/geometry/algorithms/touches.hpp @@ -5,6 +5,9 @@ // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland. +// This file was modified by Oracle on 2013. +// Modifications copyright (c) 2013, Oracle and/or its affiliates. + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -26,6 +29,7 @@ #include #include +#include namespace boost { namespace geometry { @@ -34,55 +38,210 @@ namespace boost { namespace geometry namespace detail { namespace touches { -template -inline bool ok_for_touch(Turn const& turn) +struct areal_interrupt_policy { - return turn.both(detail::overlay::operation_union) - || turn.both(detail::overlay::operation_blocked) - || turn.combination(detail::overlay::operation_union, detail::overlay::operation_blocked) - ; -} + static bool const enabled = true; + bool found_touch; + bool found_not_touch; -template -inline bool has_only_turns(Turns const& turns) -{ - bool has_touch = false; - typedef typename boost::range_iterator::type iterator_type; - for (iterator_type it = boost::begin(turns); it != boost::end(turns); ++it) + // dummy variable required by self_get_turn_points::get_turns + static bool const has_intersections = false; + + inline bool result() { - if (it->has(detail::overlay::operation_intersection)) + return found_touch && !found_not_touch; + } + + inline areal_interrupt_policy() + : found_touch(false), found_not_touch(false) + {} + + template + inline bool apply(Range const& range) + { + // if already rejected (temp workaround?) + if ( found_not_touch ) + return true; + + typedef typename boost::range_iterator::type iterator; + for ( iterator it = boost::begin(range) ; it != boost::end(range) ; ++it ) { - return false; + if ( it->has(overlay::operation_intersection) ) + { + found_not_touch = true; + return true; + } + + switch(it->method) + { + case overlay::method_crosses: + found_not_touch = true; + return true; + case overlay::method_equal: + // Segment spatially equal means: at the right side + // the polygon internally overlaps. So return false. + found_not_touch = true; + return true; + case overlay::method_touch: + case overlay::method_touch_interior: + case overlay::method_collinear: + if ( ok_for_touch(*it) ) + { + found_touch = true; + } + else + { + found_not_touch = true; + return true; + } + break; + case overlay::method_none : + case overlay::method_disjoint : + case overlay::method_error : + break; + } } - switch(it->method) + return false; + } + + template + inline bool ok_for_touch(Turn const& turn) + { + return turn.both(overlay::operation_union) + || turn.both(overlay::operation_blocked) + || turn.combination(overlay::operation_union, overlay::operation_blocked) + ; + } +}; + +template +struct linear_areal_interrupt_policy +{ + static bool const enabled = true; + bool found_touch; + bool found_not_touch; + + Linear const& linear; + + // dummy variable required by self_get_turn_points::get_turns + static bool const has_intersections = false; + + inline bool result() + { + return found_touch && !found_not_touch; + } + + inline linear_areal_interrupt_policy(Linear const& l) + : found_touch(false), found_not_touch(false), linear(l) + {} + + template + inline bool apply(Range const& range) + { + // if already rejected (temp workaround?) + if ( found_not_touch ) + return true; + + typedef typename boost::range_iterator::type iterator; + for ( iterator it = boost::begin(range) ; it != boost::end(range) ; ++it ) { - case detail::overlay::method_crosses: - return false; - case detail::overlay::method_equal: - // Segment spatially equal means: at the right side - // the polygon internally overlaps. So return false. - return false; - case detail::overlay::method_touch: - case detail::overlay::method_touch_interior: - case detail::overlay::method_collinear: - if (ok_for_touch(*it)) + if ( it->operations[0].operation == overlay::operation_intersection ) + { + if ( it->operations[1].operation == overlay::operation_union && + is_turn_on_last_point(*it) ) { - has_touch = true; + found_touch = true; + continue; } else { - return false; + found_not_touch = true; + return true; } - break; - case detail::overlay::method_none : - case detail::overlay::method_disjoint : - case detail::overlay::method_error : - break; + } + + switch(it->method) + { + case overlay::method_crosses: + found_not_touch = true; + return true; + case overlay::method_equal: + case overlay::method_touch: + case overlay::method_touch_interior: + case overlay::method_collinear: + if ( ok_for_touch(*it) ) + { + found_touch = true; + } + else + { + found_not_touch = true; + return true; + } + break; + case overlay::method_none : + case overlay::method_disjoint : + case overlay::method_error : + break; + } } + + return false; } - return has_touch; -} + + template + inline bool ok_for_touch(Turn const& turn) + { + return turn.both(overlay::operation_union) + || turn.both(overlay::operation_blocked) + || turn.combination(overlay::operation_union, overlay::operation_blocked) + + || turn.both(overlay::operation_continue) + || turn.combination(overlay::operation_union, overlay::operation_intersection) + ; + } + + template + inline bool is_turn_on_last_point(Turn const& turn) + { + typename sub_geometry::result_type::type + g = sub_geometry::get(linear, turn.operations[0].seg_id); + + std::size_t s = boost::size(g); + + if ( s == 0 ) + return false; // shouldn't return here + else if ( s == 1 ) + return equals::equals_point_point(turn.point, *boost::begin(g)); // nor here + else + return equals::equals_point_point(turn.point, *(boost::end(g)-1)); + } +}; + +template +struct turns_count_interrupt_policy +{ + static bool const enabled = true; + std::size_t turns_count; + + // dummy variable required by self_get_turn_points::get_turns + static bool const has_intersections = false; + + inline turns_count_interrupt_policy() + : turns_count(0) + {} + + template + inline bool apply(Range const& range) + { + turns_count += boost::size(range); + if ( Max < turns_count ) + return true; + return false; + } +}; + template struct check_each_ring_for_within @@ -107,6 +266,8 @@ struct check_each_ring_for_within } }; +// TODO: currently this function checks if a point of at least one range from g2 is within g1 +// shouldn't it check the opposite? template inline bool rings_containing(FirstGeometry const& geometry1, @@ -117,10 +278,180 @@ inline bool rings_containing(FirstGeometry const& geometry1, return checker.has_within; } +template +struct areal_areal +{ + static inline + bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2) + { + typedef detail::overlay::turn_info + < + typename geometry::point_type::type + > turn_info; + + typedef detail::overlay::get_turn_info + < + detail::overlay::assign_null_policy + > policy_type; + + std::deque turns; + detail::touches::areal_interrupt_policy policy; + boost::geometry::get_turns + < + detail::overlay::do_reverse::value>::value, + detail::overlay::do_reverse::value>::value, + detail::overlay::assign_null_policy + >(geometry1, geometry2, detail::no_rescale_policy(), turns, policy); + + return policy.result() + && ! geometry::detail::touches::rings_containing(geometry1, geometry2) + && ! geometry::detail::touches::rings_containing(geometry2, geometry1); + } +}; + +template +struct linear_areal +{ + static inline + bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2) + { + typedef detail::overlay::turn_info + < + typename geometry::point_type::type + > turn_info; + + typedef detail::overlay::get_turn_info + < + detail::overlay::assign_null_policy + > policy_type; + + std::deque turns; + detail::touches::linear_areal_interrupt_policy policy(geometry1); + boost::geometry::get_turns + < + detail::overlay::do_reverse::value>::value, + detail::overlay::do_reverse::value>::value, + detail::overlay::assign_null_policy + >(geometry1, geometry2, detail::no_rescale_policy(), turns, policy); + + return policy.result() + && ! geometry::detail::touches::rings_containing(geometry2, geometry1); + } +}; + +template +struct point_geometry +{ + static inline + bool apply(Point const& point, Geometry const& geometry) + { + return detail::within::point_in_geometry(point, geometry) == 0; + } +}; + +template +struct linestring_linestring +{ + static inline + bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2) + { + std::size_t s1 = boost::size(geometry1); + std::size_t s2 = boost::size(geometry2); + // TODO: throw on empty input? + if ( s1 == 0 || s2 == 0 ) + return false; + + typedef detail::overlay::turn_info + < + typename geometry::point_type::type + > turn_info; + + typedef detail::overlay::get_turn_info + < + detail::overlay::assign_null_policy + > policy_type; + + std::deque turns; + turns_count_interrupt_policy<2> policy; + boost::geometry::get_turns + < + detail::overlay::do_reverse::value>::value, + detail::overlay::do_reverse::value>::value, + detail::overlay::assign_null_policy + >(geometry1, geometry2, detail::no_rescale_policy(), turns, policy); + + if ( 2 < policy.turns_count ) + return false; + else if ( 2 == policy.turns_count ) + { + return ( detail::equals::equals_point_point(turns[0].point, *(boost::end(geometry1)-1)) + && detail::equals::equals_point_point(turns[1].point, *(boost::end(geometry2)-1)) ) + || ( detail::equals::equals_point_point(turns[0].point, *(boost::end(geometry2)-1)) + && detail::equals::equals_point_point(turns[1].point, *(boost::end(geometry1)-1)) ); + } + else if ( 1 == policy.turns_count ) + { + return detail::equals::equals_point_point(turns[0].point, *(boost::end(geometry1)-1)) + || detail::equals::equals_point_point(turns[0].point, *(boost::end(geometry2)-1)); + } + else + { + return detail::within::point_in_geometry(*boost::begin(geometry1), geometry2) >= 0 + || detail::within::point_in_geometry(*boost::begin(geometry2), geometry1) >= 0; + } + } +}; }} #endif // DOXYGEN_NO_DETAIL +#ifndef DOXYGEN_NO_DISPATCH +namespace dispatch { + +template +< + typename Geometry1, typename Geometry2, + typename Tag1 = typename tag::type, + typename Tag2 = typename tag::type, + bool Reverse = reverse_dispatch::type::value +> +struct touches + : detail::touches::areal_areal +{}; + +// If reversal is needed, perform it +template +< + typename Geometry1, typename Geometry2, + typename Tag1, typename Tag2 +> +struct touches + : touches +{ + static inline bool apply(Geometry1 const& g1, Geometry2 const& g2) + { + return touches::apply(g2, g1); + } +}; + +template +struct touches + : detail::touches::point_geometry +{}; + +template +struct touches + : detail::touches::linestring_linestring +{}; + +template +struct touches + : detail::touches::linear_areal +{}; + +} // namespace dispatch +#endif // DOXYGEN_NO_DISPATCH + /*! \brief \brief_check{has at least one touching point (self-tangency)} \note This function can be called for one geometry (self-tangency) and @@ -150,13 +481,13 @@ inline bool touches(Geometry const& geometry) > policy_type; std::deque turns; - detail::self_get_turn_points::no_interrupt_policy policy; + detail::touches::areal_interrupt_policy policy; detail::self_get_turn_points::get_turns < policy_type >::apply(geometry, detail::no_rescale_policy(), turns, policy); - return detail::touches::has_only_turns(turns); + return policy.result(); } @@ -178,34 +509,10 @@ inline bool touches(Geometry1 const& geometry1, Geometry2 const& geometry2) concept::check(); concept::check(); - - typedef detail::overlay::turn_info - < - typename geometry::point_type::type - > turn_info; - - typedef detail::overlay::get_turn_info - < - detail::overlay::assign_null_policy - > policy_type; - - std::deque turns; - detail::get_turns::no_interrupt_policy policy; - boost::geometry::get_turns - < - detail::overlay::do_reverse::value>::value, - detail::overlay::do_reverse::value>::value, - detail::overlay::assign_null_policy - >(geometry1, geometry2, detail::no_rescale_policy(), turns, policy); - - return detail::touches::has_only_turns(turns) - && ! geometry::detail::touches::rings_containing(geometry1, geometry2) - && ! geometry::detail::touches::rings_containing(geometry2, geometry1) - ; + return dispatch::touches::apply(geometry1, geometry2); } - }} // namespace boost::geometry #endif // BOOST_GEOMETRY_ALGORITHMS_TOUCHES_HPP diff --git a/include/boost/geometry/algorithms/within.hpp b/include/boost/geometry/algorithms/within.hpp index 4eec6a43d..6d6c0f938 100644 --- a/include/boost/geometry/algorithms/within.hpp +++ b/include/boost/geometry/algorithms/within.hpp @@ -4,6 +4,9 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 2013. +// Modifications copyright (c) 2013, Oracle and/or its affiliates. + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -46,125 +49,11 @@ #include #include +#include namespace boost { namespace geometry { -#ifndef DOXYGEN_NO_DETAIL -namespace detail { namespace within -{ - - -template -< - typename Point, - typename Ring, - iterate_direction Direction, - closure_selector Closure, - typename Strategy -> -struct point_in_ring -{ - BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategyPolygonal) ); - - static inline int apply(Point const& point, Ring const& ring, - Strategy const& strategy) - { - boost::ignore_unused_variable_warning(strategy); - if (int(boost::size(ring)) - < core_detail::closure::minimum_ring_size::value) - { - return -1; - } - - typedef typename reversible_view::type rev_view_type; - typedef typename closeable_view - < - rev_view_type const, Closure - >::type cl_view_type; - typedef typename boost::range_iterator::type iterator_type; - - rev_view_type rev_view(ring); - cl_view_type view(rev_view); - typename Strategy::state_type state; - iterator_type it = boost::begin(view); - iterator_type end = boost::end(view); - - bool stop = false; - for (iterator_type previous = it++; - it != end && ! stop; - ++previous, ++it) - { - if (! strategy.apply(point, *previous, *it, state)) - { - stop = true; - } - } - - return strategy.result(state); - } -}; - - -// Polygon: in exterior ring, and if so, not within interior ring(s) -template -< - typename Point, - typename Polygon, - iterate_direction Direction, - closure_selector Closure, - typename Strategy -> -struct point_in_polygon -{ - BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategyPolygonal) ); - - static inline int apply(Point const& point, Polygon const& poly, - Strategy const& strategy) - { - int const code = point_in_ring - < - Point, - typename ring_type::type, - Direction, - Closure, - Strategy - >::apply(point, exterior_ring(poly), strategy); - - if (code == 1) - { - typename interior_return_type::type rings - = interior_rings(poly); - for (BOOST_AUTO_TPL(it, boost::begin(rings)); - it != boost::end(rings); - ++it) - { - int const interior_code = point_in_ring - < - Point, - typename ring_type::type, - Direction, - Closure, - Strategy - >::apply(point, *it, strategy); - - if (interior_code != -1) - { - // If 0, return 0 (touch) - // If 1 (inside hole) return -1 (outside polygon) - // If -1 (outside hole) check other holes if any - return -interior_code; - } - } - } - return code; - } -}; - -}} // namespace detail::within -#endif // DOXYGEN_NO_DETAIL - - #ifndef DOXYGEN_NO_DISPATCH namespace dispatch { @@ -211,14 +100,7 @@ struct within template static inline bool apply(Point const& point, Ring const& ring, Strategy const& strategy) { - return detail::within::point_in_ring - < - Point, - Ring, - order_as_direction::value>::value, - geometry::closure::value, - Strategy - >::apply(point, ring, strategy) == 1; + return detail::within::point_in_geometry(point, ring, strategy) == 1; } }; @@ -228,14 +110,17 @@ struct within template static inline bool apply(Point const& point, Polygon const& polygon, Strategy const& strategy) { - return detail::within::point_in_polygon - < - Point, - Polygon, - order_as_direction::value>::value, - geometry::closure::value, - Strategy - >::apply(point, polygon, strategy) == 1; + return detail::within::point_in_geometry(point, polygon, strategy) == 1; + } +}; + +template +struct within +{ + template static inline + bool apply(Point const& point, Linestring const& linestring, Strategy const& strategy) + { + return detail::within::point_in_geometry(point, linestring, strategy) == 1; } }; diff --git a/include/boost/geometry/multi/algorithms/covered_by.hpp b/include/boost/geometry/multi/algorithms/covered_by.hpp index 17de720bd..8c80aa554 100644 --- a/include/boost/geometry/multi/algorithms/covered_by.hpp +++ b/include/boost/geometry/multi/algorithms/covered_by.hpp @@ -3,6 +3,10 @@ // 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) 2013 Adam Wulkiewicz, Lodz, Poland. + +// This file was modified by Oracle on 2013. +// Modifications copyright (c) 2013, Oracle and/or its affiliates. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -43,21 +47,24 @@ struct covered_by Point, MultiPolygon, Strategy, - detail::within::point_in_polygon - < - Point, - typename boost::range_value::type, - order_as_direction - < - geometry::point_order::value - >::value, - geometry::closure::value, - Strategy - > + detail::within::point_in_geometry_dispatch + < + typename boost::range_value::type + > >::apply(point, multi_polygon, strategy) >= 0; } }; +template +struct covered_by +{ + template + static inline bool apply(Point const& point, + MultiLinestring const& multi_linestring, Strategy const& strategy) + { + return detail::within::point_in_geometry(point, multi_linestring, strategy) >= 0; + } +}; } // namespace dispatch diff --git a/include/boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp b/include/boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp index 940480b3c..3f0eea575 100644 --- a/include/boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp +++ b/include/boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp @@ -2,6 +2,9 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2013. +// Modifications copyright (c) 2013, Oracle and/or its affiliates. + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -91,6 +94,36 @@ struct copy_segment_point > {}; +template +< + typename MultiGeometry, + bool Reverse, + typename SegmentIdentifier, + typename PointOut +> +struct copy_segment_point + < + multi_linestring_tag, + MultiGeometry, + Reverse, + SegmentIdentifier, + PointOut + > + : detail::copy_segments::copy_segment_point_multi + < + MultiGeometry, + SegmentIdentifier, + PointOut, + detail::copy_segments::copy_segment_point_range + < + typename boost::range_value::type, + Reverse, + SegmentIdentifier, + PointOut + > + > +{}; + } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH diff --git a/include/boost/geometry/multi/algorithms/detail/point_on_border.hpp b/include/boost/geometry/multi/algorithms/detail/point_on_border.hpp index dd3bcd5d1..bbf958571 100644 --- a/include/boost/geometry/multi/algorithms/detail/point_on_border.hpp +++ b/include/boost/geometry/multi/algorithms/detail/point_on_border.hpp @@ -4,6 +4,9 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 2013. +// Modifications copyright (c) 2013, Oracle and/or its affiliates. + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -84,7 +87,19 @@ struct point_on_border > {}; - +template +struct point_on_border + : detail::point_on_border::point_on_multi + < + Point, + Multi, + detail::point_on_border::point_on_range + < + Point, + typename boost::range_value::type + > + > +{}; } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH diff --git a/include/boost/geometry/multi/algorithms/detail/sections/range_by_section.hpp b/include/boost/geometry/multi/algorithms/detail/sections/range_by_section.hpp index 47bc8a863..b5b041c1f 100644 --- a/include/boost/geometry/multi/algorithms/detail/sections/range_by_section.hpp +++ b/include/boost/geometry/multi/algorithms/detail/sections/range_by_section.hpp @@ -4,6 +4,9 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 2013. +// Modifications copyright (c) 2013, Oracle and/or its affiliates. + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -79,6 +82,19 @@ struct range_by_section > {}; +template +struct range_by_section + : detail::section::full_section_multi + < + MultiLinestring, + Section, + detail::section::full_section_range + < + typename boost::range_value::type, + Section + > + > +{}; } // namespace dispatch #endif diff --git a/include/boost/geometry/multi/algorithms/detail/sections/sectionalize.hpp b/include/boost/geometry/multi/algorithms/detail/sections/sectionalize.hpp index 447f24929..29bea08db 100644 --- a/include/boost/geometry/multi/algorithms/detail/sections/sectionalize.hpp +++ b/include/boost/geometry/multi/algorithms/detail/sections/sectionalize.hpp @@ -4,6 +4,9 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 2013. +// Modifications copyright (c) 2013, Oracle and/or its affiliates. + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -75,7 +78,7 @@ template bool Reverse, std::size_t DimensionCount > -struct sectionalize +struct sectionalize : detail::sectionalize::sectionalize_multi < DimensionCount, @@ -88,6 +91,25 @@ struct sectionalize {}; +template +< + typename MultiLinestring, + bool Reverse, + std::size_t DimensionCount +> +struct sectionalize + : detail::sectionalize::sectionalize_multi + < + DimensionCount, + detail::sectionalize::sectionalize_range + < + closed, false, + typename point_type::type, + DimensionCount + > + > + +{}; } // namespace dispatch #endif diff --git a/include/boost/geometry/multi/algorithms/detail/within/point_in_geometry.hpp b/include/boost/geometry/multi/algorithms/detail/within/point_in_geometry.hpp new file mode 100644 index 000000000..1ff46d70e --- /dev/null +++ b/include/boost/geometry/multi/algorithms/detail/within/point_in_geometry.hpp @@ -0,0 +1,112 @@ +// 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) 2013 Adam Wulkiewicz, Lodz, Poland. + +// This file was modified by Oracle on 2013. +// Modifications copyright (c) 2013, Oracle and/or its affiliates. + +// 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_MULTI_ALGORITHMS_DETAIL_WITHIN_POINT_IN_GEOMETRY_HPP +#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_WITHIN_POINT_IN_GEOMETRY_HPP + +#include + +namespace boost { namespace geometry { + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace within { + +template +struct point_in_geometry_dispatch +{ + template static inline + int apply(P const& p, G const& g, S const& s) + { + // For invalid multipolygons + //int res = -1; // outside + + typedef typename boost::range_value::type polygon_type; + typedef typename boost::range_const_iterator::type iterator; + for ( iterator it = boost::begin(g) ; it != boost::end(g) ; ++it ) + { + int pip = detail::within::point_in_geometry_dispatch::apply(p, *it, s); + + if ( 1 == pip ) // inside polygon + return 1; + // Only for valid multi-polygons + if ( 0 == pip ) + return 0; + // For invalid multi-polygons + //if ( res < pip ) // point must be inside at least one polygon + // res = pip; + } + + //return res; // for invalid multipolygons + return -1; // for valid multipolygons + } +}; + +template +struct point_in_geometry_dispatch +{ + template static inline + int apply(P const& p, G const& g, S const& s) + { + int pip = -1; // outside + + typedef typename boost::range_value::type linestring_type; + typedef typename boost::range_value::type point_type; + typedef typename boost::range_iterator::type iterator; + iterator it = boost::begin(g); + for ( ; it != boost::end(g) ; ++it ) + { + pip = detail::within::point_in_geometry_dispatch::apply(p, *it, s); + + if ( 0 <= pip ) + { + ++it; + break; + } + } + + // outside + if ( pip < 0 ) + return -1; + + unsigned boundaries = pip == 0 ? 1 : 0; + + for ( ; it != boost::end(g) ; ++it ) + { + if ( boost::size(*it) < 2 ) + continue; + + point_type const& front = *boost::begin(*it); + point_type const& back = *(--boost::end(*it)); + // is closed_ring + if ( detail::equals::equals_point_point(front, back) ) + continue; + if ( detail::equals::equals_point_point(p, front) + || detail::equals::equals_point_point(p, back) ) + ++boundaries; + } + + // if the number of boundaries is odd, the point is on the boundary + return boundaries % 2 ? 0 : 1; + } +}; + +}} // namespace detail::within +#endif // DOXYGEN_NO_DETAIL + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_WITHIN_POINT_IN_GEOMETRY_HPP diff --git a/include/boost/geometry/multi/algorithms/within.hpp b/include/boost/geometry/multi/algorithms/within.hpp index a9a458776..7b9a45cae 100644 --- a/include/boost/geometry/multi/algorithms/within.hpp +++ b/include/boost/geometry/multi/algorithms/within.hpp @@ -3,6 +3,10 @@ // 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) 2013 Adam Wulkiewicz, Lodz, Poland. + +// This file was modified by Oracle on 2013. +// Modifications copyright (c) 2013, Oracle and/or its affiliates. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -23,6 +27,8 @@ #include #include +#include + namespace boost { namespace geometry { @@ -82,21 +88,25 @@ struct within Point, MultiPolygon, Strategy, - detail::within::point_in_polygon - < - Point, - typename boost::range_value::type, - order_as_direction - < - geometry::point_order::value - >::value, - geometry::closure::value, - Strategy - > + detail::within::point_in_geometry_dispatch + < + typename boost::range_value::type + > >::apply(point, multi_polygon, strategy) == 1; } }; +template +struct within +{ + template + static inline bool apply(Point const& point, + MultiLinestring const& multi_linestring, Strategy const& strategy) + { + return detail::within::point_in_geometry(point, multi_linestring, strategy) == 1; + } +}; + } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH diff --git a/include/boost/geometry/multi/core/ring_type.hpp b/include/boost/geometry/multi/core/ring_type.hpp index faafaed02..f03564dde 100644 --- a/include/boost/geometry/multi/core/ring_type.hpp +++ b/include/boost/geometry/multi/core/ring_type.hpp @@ -4,6 +4,9 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 2013. +// Modifications copyright (c) 2013, Oracle and/or its affiliates. + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -45,6 +48,21 @@ struct ring_return_type >::type type; }; +template +struct ring_return_type +{ + typedef typename ring_return_type + < + linestring_tag, + typename mpl::if_ + < + boost::is_const, + typename boost::range_value::type const, + typename boost::range_value::type + >::type + >::type type; +}; + template struct ring_type @@ -55,6 +73,15 @@ struct ring_type >::type type; }; +template +struct ring_type +{ + typedef typename boost::remove_reference + < + typename ring_return_type::type + >::type type; +}; + } // namespace core_dispatch #endif diff --git a/include/boost/geometry/multi/multi.hpp b/include/boost/geometry/multi/multi.hpp index df10392cb..f2f5b3a72 100644 --- a/include/boost/geometry/multi/multi.hpp +++ b/include/boost/geometry/multi/multi.hpp @@ -4,6 +4,9 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 2013. +// Modifications copyright (c) 2013, Oracle and/or its affiliates. + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -49,6 +52,9 @@ #include #include +#include +#include + #include #include #include diff --git a/include/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp b/include/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp index 69188650d..ecd25832f 100644 --- a/include/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp +++ b/include/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp @@ -1,6 +1,10 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland. + +// This file was modified by Oracle on 2013. +// Modifications copyright (c) 2013, Oracle and/or its affiliates. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -194,6 +198,18 @@ struct default_strategy::type> type; }; +template +struct default_strategy +{ + typedef strategy::within::winding::type> type; +}; + +// TODO: later move it to multi/strategies/agnostic +template +struct default_strategy +{ + typedef strategy::within::winding::type> type; +}; } // namespace services @@ -221,6 +237,18 @@ struct default_strategy::type> type; }; +template +struct default_strategy +{ + typedef strategy::within::winding::type> type; +}; + +// TODO: later move it to multi/strategies/agnostic +template +struct default_strategy +{ + typedef strategy::within::winding::type> type; +}; }}} // namespace strategy::covered_by::services #endif diff --git a/test/algorithms/covered_by.cpp b/test/algorithms/covered_by.cpp index a1b19b404..e1692a32e 100644 --- a/test/algorithms/covered_by.cpp +++ b/test/algorithms/covered_by.cpp @@ -1,6 +1,8 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// + // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland. + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -37,6 +39,17 @@ void test_all() */ + // linestrings + typedef bg::model::linestring

ls; + test_geometry("POINT(0 0)", "LINESTRING(0 0,1 1,2 2)", true); + test_geometry("POINT(3 3)", "LINESTRING(0 0,1 1,2 2)", false); + test_geometry("POINT(1 1)", "LINESTRING(0 0,2 2,3 3)", true); + + // multi_linestrings + typedef bg::model::multi_linestring mls; + test_geometry("POINT(0 0)", "MULTILINESTRING((0 0,1 1,2 2),(0 0,0 1))", true); + test_geometry("POINT(0 0)", "MULTILINESTRING((0 0,1 1,2 2),(0 0,0 1),(0 0,1 0))", true); + typedef bg::model::box

box_type; test_geometry("POINT(1 1)", "BOX(0 0,2 2)", true); diff --git a/test/algorithms/intersects.cpp b/test/algorithms/intersects.cpp index 5d25ad9ce..df7a65840 100644 --- a/test/algorithms/intersects.cpp +++ b/test/algorithms/intersects.cpp @@ -1,8 +1,11 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// + // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland. -// + +// This file was modified by Oracle on 2013. +// Modifications copyright (c) 2013, Oracle and/or its affiliates. + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -15,6 +18,96 @@ #include +template +void test_intersects_polygon_polygon() +{ + typedef bg::model::polygon poly_ccw_o; + test_geometry("POLYGON((1 1, 3 3, 2 5))", "POLYGON((0 0, 9 0, 9 9, 0 9),(5 5,5 8,8 8,8 5))", true); + test_geometry("POLYGON((6 6, 7 6, 7 7, 6 7))", "POLYGON((0 0, 9 0, 9 9, 0 9),(5 5,5 8,8 8,8 5))", false); + test_geometry("POLYGON((7 7, 9 7, 9 9, 7 9))", "POLYGON((0 0, 9 0, 9 9, 0 9),(5 5,5 8,8 8,8 5))", true); +} + +template +void test_intersects_linestring_segment() +{ + typedef bg::model::linestring

ls; + typedef bg::model::segment

seg; + + test_geometry("LINESTRING(1 1, 3 3, 2 5)", "SEGMENT(2 0, 2 6)", true); + test_geometry("LINESTRING(1 1, 3 3)", "SEGMENT(1 0, 1 1)", true); + test_geometry("LINESTRING(1 1, 3 3)", "SEGMENT(2 0, 2 2)", true); + test_geometry("LINESTRING(1 1, 3 3)", "SEGMENT(3 0, 4 1)", false); +} + +template +void test_intersects_linestring_polygon() +{ + typedef bg::model::linestring

ls; + typedef bg::model::multi_linestring mls; + typedef bg::model::polygon

poly_cw_c; + typedef bg::model::polygon poly_ccw_c; + typedef bg::model::polygon poly_ccw_o; + typedef bg::model::multi_polygon mpoly_ccw_c; + + test_geometry("LINESTRING(1 1,2 2)", "POLYGON((0 0,10 0,10 10,0 10,0 0))", true); + test_geometry("LINESTRING(1 0,2 2)", "POLYGON((0 0,10 0,10 10,0 10,0 0))", true); + test_geometry("LINESTRING(11 0,12 12)", "POLYGON((0 0,10 0,10 10,0 10,0 0))", false); + + test_geometry("LINESTRING(1 1, 3 3, 2 5)", "POLYGON((0 0, 9 0, 9 9, 0 9),(5 5,5 8,8 8,8 5))", true); + test_geometry("LINESTRING(6 6, 7 6, 7 7, 6 7)", "POLYGON((0 0, 9 0, 9 9, 0 9),(5 5,5 8,8 8,8 5))", false); + test_geometry("LINESTRING(7 7, 9 7, 9 9, 7 9)", "POLYGON((0 0, 9 0, 9 9, 0 9),(5 5,5 8,8 8,8 5))", true); + + test_geometry("POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))", "LINESTRING(-2 -2, 12 7)", true); + test_geometry("POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))", "LINESTRING(5 5, 15 4)", true); + test_geometry("POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))", "LINESTRING(7 6, 15 4)", true); + test_geometry("POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))", "LINESTRING(6 2, 12 1)", true); + + // MULTI + test_geometry("LINESTRING(1 1,2 2)", "MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)))", true); + test_geometry("MULTILINESTRING((1 1,2 2))", "MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)))", true); +} + +template +void test_intersects_linestring_ring() +{ + typedef bg::model::linestring

ls; + typedef bg::model::multi_linestring mls; + typedef bg::model::ring ring_ccw_c; + + test_geometry("LINESTRING(1 1,2 2)", "POLYGON((0 0,10 0,10 10,0 10,0 0))", true); + test_geometry("LINESTRING(1 0,2 2)", "POLYGON((0 0,10 0,10 10,0 10,0 0))", true); + test_geometry("LINESTRING(11 0,12 12)", "POLYGON((0 0,10 0,10 10,0 10,0 0))", false); + + // MULTI + test_geometry("MULTILINESTRING((1 1,2 2))", "POLYGON((0 0,10 0,10 10,0 10,0 0))", true); +} + +template +void test_intersects_ring_polygon() +{ + typedef bg::model::ring ring_ccw_o; + typedef bg::model::polygon poly_ccw_o; + + test_geometry("POLYGON((1 1, 3 3, 2 5))", "POLYGON((0 0, 9 0, 9 9, 0 9),(5 5,5 8,8 8,8 5))", true); + test_geometry("POLYGON((6 6, 7 6, 7 7, 6 7))", "POLYGON((0 0, 9 0, 9 9, 0 9),(5 5,5 8,8 8,8 5))", false); + test_geometry("POLYGON((7 7, 9 7, 9 9, 7 9))", "POLYGON((0 0, 9 0, 9 9, 0 9),(5 5,5 8,8 8,8 5))", true); + + test_geometry("POLYGON((6 6,7 6,7 7,6 7))", "POLYGON((0 0, 9 0, 9 9, 0 9),(5 5,5 8,8 8,8 5))", false); +} + +template +void test_intersects_point_linestring() +{ + typedef bg::model::linestring

ls; + typedef bg::model::multi_linestring mls; + + test_geometry("POINT(0 0)", "LINESTRING(0 0,2 2,4 0)", true); + test_geometry("POINT(1 1)", "LINESTRING(0 0,2 2,4 0)", true); + test_geometry("POINT(1 0)", "LINESTRING(0 0,2 2,4 0)", false); + + // MULTI + test_geometry("POINT(0 0)", "MULTILINESTRING((0 0,2 2,4 0))", true); +} template void test_all() @@ -39,6 +132,12 @@ void test_all() "POLYGON((1941 2066,2055 2066,2055 2166,1941 2166))", "BOX(1941 2066, 2055 2166)", true); + test_intersects_point_linestring

(); + test_intersects_polygon_polygon

(); + test_intersects_linestring_polygon

(); + test_intersects_linestring_ring

(); + test_intersects_linestring_segment

(); + test_intersects_ring_polygon

(); // self-intersecting is not tested in disjoint, so that is done here. diff --git a/test/algorithms/test_covered_by.hpp b/test/algorithms/test_covered_by.hpp index 79abbd5f3..b9d8f5853 100644 --- a/test/algorithms/test_covered_by.hpp +++ b/test/algorithms/test_covered_by.hpp @@ -2,6 +2,8 @@ // Unit Test // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland. + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -23,6 +25,9 @@ #include +#include +#include +#include template void check_geometry(Geometry1 const& geometry1, diff --git a/test/algorithms/test_intersects.hpp b/test/algorithms/test_intersects.hpp index afc68eefa..7a8af7161 100644 --- a/test/algorithms/test_intersects.hpp +++ b/test/algorithms/test_intersects.hpp @@ -2,6 +2,8 @@ // Unit Test // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland. + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -20,6 +22,18 @@ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include template void test_geometry(std::string const& wkt1, diff --git a/test/algorithms/test_touches.hpp b/test/algorithms/test_touches.hpp index dfe57f6c2..5df70fbfe 100644 --- a/test/algorithms/test_touches.hpp +++ b/test/algorithms/test_touches.hpp @@ -2,6 +2,10 @@ // Unit Test // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. + +// This file was modified by Oracle on 2013. +// Modifications copyright (c) 2013, Oracle and/or its affiliates. + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -17,9 +21,19 @@ #include #include #include +#include #include +#include +#include +#include +#include + +#include +#include + +#include template void test_touches(std::string const& wkt1, @@ -38,6 +52,14 @@ void test_touches(std::string const& wkt1, << " with " << wkt2 << " -> Expected: " << expected << " detected: " << detected); + + detected = bg::touches(geometry2, geometry1); + + BOOST_CHECK_MESSAGE(detected == expected, + "touches: " << wkt2 + << " with " << wkt1 + << " -> Expected: " << expected + << " detected: " << detected); } diff --git a/test/algorithms/test_within.hpp b/test/algorithms/test_within.hpp index 04cae6027..e242580c6 100644 --- a/test/algorithms/test_within.hpp +++ b/test/algorithms/test_within.hpp @@ -2,6 +2,8 @@ // Unit Test // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland. + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -27,6 +29,9 @@ #include #include +#include +#include +#include template void check_geometry(Geometry1 const& geometry1, diff --git a/test/algorithms/touches.cpp b/test/algorithms/touches.cpp index dac7c8ab9..551b30bb1 100644 --- a/test/algorithms/touches.cpp +++ b/test/algorithms/touches.cpp @@ -1,6 +1,10 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // // Copyright (c) 2012 Barend Gehrels, Amsterdam, the Netherlands. + +// This file was modified by Oracle on 2013. +// Modifications copyright (c) 2013, Oracle and/or its affiliates. + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -17,6 +21,9 @@ template void test_all() { typedef bg::model::polygon

polygon; + typedef bg::model::linestring

linestring; + typedef bg::model::multi_polygon mpolygon; + typedef bg::model::multi_linestring mlinestring; // Just a normal polygon test_self_touches("POLYGON((0 0,0 4,1.5 2.5,2.5 1.5,4 0,0 0))", false); @@ -126,6 +133,59 @@ void test_all() true ); + // Point-Polygon + test_touches("POINT(40 50)", "POLYGON((40 40,40 60,60 60,60 40,40 40))", true); + test_touches("POINT(60 60)", "POLYGON((40 40,40 60,60 60,60 40,40 40))", true); + test_touches("POINT(50 50)", "POLYGON((40 40,40 60,60 60,60 40,40 40))", false); + test_touches("POINT(30 50)", "POLYGON((40 40,40 60,60 60,60 40,40 40))", false); + + // Point-MultiPolygon + test_touches("POINT(40 50)", "MULTIPOLYGON(((40 40,40 60,60 60,60 40,40 40)),((0 0,0 10,10 10,10 0)))", true); + + // Point-Linestring + test_touches("POINT(0 0)", "LINESTRING(0 0, 2 2, 10 2)", true); + test_touches("POINT(2 2)", "LINESTRING(0 0, 2 2, 10 2)", false); + test_touches("POINT(1 1)", "LINESTRING(0 0, 2 2, 10 2)", false); + test_touches("POINT(5 5)", "LINESTRING(0 0, 2 2, 10 2)", false); + + // Point-MultiLinestring + test_touches("POINT(0 0)", "MULTILINESTRING((0 0, 2 2, 10 2),(5 5, 6 6))", true); + test_touches("POINT(0 0)", "MULTILINESTRING((0 0, 2 2, 10 2),(0 0, 6 6))", false); + + // Linestring-Linestring + test_touches("LINESTRING(0 0,2 0)", "LINESTRING(0 0,0 2)", true); + test_touches("LINESTRING(0 0,2 0)", "LINESTRING(2 0,2 2)", true); + test_touches("LINESTRING(0 0,2 0)", "LINESTRING(0 2,0 0)", true); + test_touches("LINESTRING(0 0,2 0)", "LINESTRING(2 2,2 0)", true); + test_touches("LINESTRING(2 0,0 0)", "LINESTRING(0 0,0 2)", true); + test_touches("LINESTRING(2 0,0 0)", "LINESTRING(2 0,2 2)", true); + test_touches("LINESTRING(2 0,0 0)", "LINESTRING(0 2,0 0)", true); + test_touches("LINESTRING(2 0,0 0)", "LINESTRING(2 2,2 0)", true); + test_touches("LINESTRING(0 0,2 0)", "LINESTRING(1 0,1 1)", true); + test_touches("LINESTRING(0 0,2 0)", "LINESTRING(1 1,1 0)", true); + test_touches("LINESTRING(2 0,0 0)", "LINESTRING(1 0,1 1)", true); + test_touches("LINESTRING(2 0,0 0)", "LINESTRING(1 1,1 0)", true); + + test_touches("LINESTRING(0 0,10 0)", "LINESTRING(0 0,5 5,10 0)", true); + test_touches("LINESTRING(0 0,10 10)", "LINESTRING(0 0,0 5,10 5)", false); + + test_touches("LINESTRING(0 5,5 6,10 5)", "LINESTRING(0 7,5 6,10 7)", false); + test_touches("LINESTRING(0 5,5 6,10 5)", "LINESTRING(10 7,5 6,0 7)", false); + test_touches("LINESTRING(10 5,5 6,0 5)", "LINESTRING(0 7,5 6,10 7)", false); + test_touches("LINESTRING(10 5,5 6,0 5)", "LINESTRING(10 7,5 6,0 7)", false); + + test_touches("LINESTRING(0 0,1 1,2 2)", "LINESTRING(2 0,2 2,1 2,1 1)", true); + test_touches("LINESTRING(2 2,1 1,0 0)", "LINESTRING(2 0,2 2,1 2,1 1)", true); + test_touches("LINESTRING(0 0,1 1,2 2)", "LINESTRING(1 1,1 2,2 2,2 0)", true); + test_touches("LINESTRING(2 2,1 1,0 0)", "LINESTRING(1 1,1 2,2 2,2 0)", true); + + //Linestring-Polygon + test_touches("LINESTRING(10 0,15 5,10 10,5 15,5 10,0 10,5 15,5 10)", "POLYGON((0 0,0 10,10 10,10 0,0 0))", true); + test_touches("LINESTRING(5 10,5 15,0 10,5 10,5 15,10 10,15 5,10 0)", "POLYGON((0 0,0 10,10 10,10 0,0 0))", true); + test_touches("LINESTRING(5 10,5 15,0 10,5 10,5 15,10 10,5 5,10 0)", "POLYGON((0 0,0 10,10 10,10 0,0 0))", false); + test_touches("LINESTRING(0 15,5 5)", "POLYGON((0 0,0 10,10 10,10 0,0 0))", false); + test_touches("LINESTRING(0 15,5 10,5 5)", "POLYGON((0 0,0 10,10 10,10 0,0 0))", false); + test_touches("LINESTRING(10 15,5 10,0 5)", "POLYGON((0 0,0 10,10 10,10 0,0 0))", false); } @@ -151,4 +211,4 @@ select geometry::STGeomFromText('POLYGON((0 0,0 100,100 100,100 0,0 0))',0) as p ) -- select p from viewy union all select q from viewy select p.STTouches(q) from viewy -*/ \ No newline at end of file +*/ diff --git a/test/algorithms/within.cpp b/test/algorithms/within.cpp index 5865f3083..8ea79289e 100644 --- a/test/algorithms/within.cpp +++ b/test/algorithms/within.cpp @@ -1,6 +1,8 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// + // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland. + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -34,6 +36,17 @@ void test_all() test_geometry >("POINT(2 2)", "POLYGON((0 0,0 4,4 4,4 0,0 0),(1 1,3 1,3 3,1 3,1 1))", false); + // linestrings + typedef bg::model::linestring

ls; + test_geometry("POINT(0 0)", "LINESTRING(0 0,1 1,2 2)", false); + test_geometry("POINT(3 3)", "LINESTRING(0 0,1 1,2 2)", false); + test_geometry("POINT(1 1)", "LINESTRING(0 0,2 2,3 3)", true); + + // multi_linestrings + typedef bg::model::multi_linestring mls; + test_geometry("POINT(0 0)", "MULTILINESTRING((0 0,1 1,2 2),(0 0,0 1))", true); + test_geometry("POINT(0 0)", "MULTILINESTRING((0 0,1 1,2 2),(0 0,0 1),(0 0,1 0))", false); + typedef bg::model::box

box_type; test_geometry("POINT(1 1)", "BOX(0 0,2 2)", true);