Merge branch 'develop' into rescale_to_integer

This commit is contained in:
Barend Gehrels
2013-12-14 13:38:28 +01:00
39 changed files with 6820 additions and 335 deletions

17
README.md Normal file
View File

@@ -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)

BIN
doc/other/logo/DENMARK.TTF Normal file

Binary file not shown.

BIN
doc/other/logo/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

5012
doc/other/logo/logo.svg Normal file

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
doc/other/logo/logo_bkg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@@ -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<Point, Ring, point_tag, ring_tag>
template <typename Strategy>
static inline bool apply(Point const& point, Ring const& ring, Strategy const& strategy)
{
return detail::within::point_in_ring
<
Point,
Ring,
order_as_direction<geometry::point_order<Ring>::value>::value,
geometry::closure<Ring>::value,
Strategy
>::apply(point, ring, strategy) >= 0;
return detail::within::point_in_geometry(point, ring, strategy) >= 0;
}
};
@@ -94,14 +90,17 @@ struct covered_by<Point, Polygon, point_tag, polygon_tag>
template <typename Strategy>
static inline bool apply(Point const& point, Polygon const& polygon, Strategy const& strategy)
{
return detail::within::point_in_polygon
<
Point,
Polygon,
order_as_direction<geometry::point_order<Polygon>::value>::value,
geometry::closure<Polygon>::value,
Strategy
>::apply(point, polygon, strategy) >= 0;
return detail::within::point_in_geometry(point, polygon, strategy) >= 0;
}
};
template <typename Point, typename Linestring>
struct covered_by<Point, Linestring, point_tag, linestring_tag>
{
template <typename Strategy> static inline
bool apply(Point const& point, Linestring const& linestring, Strategy const& strategy)
{
return detail::within::point_in_geometry(point, linestring, strategy) >= 0;
}
};

View File

@@ -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 <boost/geometry/util/math.hpp>
#include <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
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<Dimension>(p1), get<Dimension>(p2)))
{
return true;
}
return point_point
<
Point1, Point2,
Dimension + 1, DimensionCount
>::apply(p1, p2);
}
};
template <typename Point1, typename Point2, std::size_t DimensionCount>
struct point_point<Point1, Point2, DimensionCount, DimensionCount>
{
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 <typename Point1, typename Point2>
inline bool disjoint_point_point(Point1 const& point1, Point2 const& point2)
{
return point_point
<
Point1, Point2,
0, dimension<Point1>::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 <typename Point1, typename Point2>
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

View File

@@ -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 <cstddef>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/util/math.hpp>
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<Dimension>(p1), get<Dimension>(p2)))
{
return true;
}
return point_point
<
Point1, Point2,
Dimension + 1, DimensionCount
>::apply(p1, p2);
}
};
template <typename Point1, typename Point2, std::size_t DimensionCount>
struct point_point<Point1, Point2, DimensionCount, DimensionCount>
{
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 <typename Point1, typename Point2>
inline bool disjoint_point_point(Point1 const& point1, Point2 const& point2)
{
return point_point
<
Point1, Point2,
0, dimension<Point1>::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 <typename Point1, typename Point2>
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

View File

@@ -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 <boost/geometry/core/point_order.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace overlay
{
// Metafunction helper for intersection and union
template <order_selector Selector, bool Reverse = false>
struct do_reverse {};
template <>
struct do_reverse<clockwise, false> : boost::false_type {};
template <>
struct do_reverse<clockwise, true> : boost::true_type {};
template <>
struct do_reverse<counterclockwise, false> : boost::true_type {};
template <>
struct do_reverse<counterclockwise, true> : boost::false_type {};
}} // namespace detail::overlay
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_DO_REVERSE_HPP

View File

@@ -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;
}

View File

@@ -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 <boost/geometry/algorithms/detail/overlay/assign_parents.hpp>
#include <boost/geometry/algorithms/detail/overlay/ring_properties.hpp>
#include <boost/geometry/algorithms/detail/overlay/select_rings.hpp>
#include <boost/geometry/algorithms/detail/overlay/do_reverse.hpp>
#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
# include <boost/geometry/io/dsv/write.hpp>
@@ -309,24 +310,6 @@ std::cout << "traverse" << std::endl;
};
// Metafunction helper for intersection and union
template <order_selector Selector, bool Reverse = false>
struct do_reverse {};
template <>
struct do_reverse<clockwise, false> : boost::false_type {};
template <>
struct do_reverse<clockwise, true> : boost::true_type {};
template <>
struct do_reverse<counterclockwise, false> : boost::true_type {};
template <>
struct do_reverse<counterclockwise, true> : boost::false_type {};
}} // namespace detail::overlay
#endif // DOXYGEN_NO_DETAIL

View File

@@ -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 <typename Geometry,
typename Tag = typename geometry::tag<Geometry>::type,
bool IsMulti = boost::is_base_of<multi_tag, Tag>::value>
struct get_dispatch
{
BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY, (Geometry, Tag));
};
template <typename Geometry, typename Tag>
struct get_dispatch<Geometry, Tag, false>
{
typedef Geometry & result_type;
template <typename Id> static inline
result_type apply(Geometry & geometry, Id const&)
{
return geometry;
}
};
template <typename Geometry>
struct get_dispatch<Geometry, polygon_tag, false>
{
typedef typename geometry::ring_type<Geometry>::type & result_type;
template <typename Id> 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 <typename Geometry, typename Tag>
struct get_dispatch<Geometry, Tag, true>
{
typedef typename boost::range_value<Geometry>::type sub_type;
typedef typename get_dispatch<sub_type>::result_type result_type;
template <typename Id> static inline
result_type apply(Geometry & geometry, Id const& id)
{
BOOST_ASSERT(0 <= id.multi_index);
return get_dispatch<sub_type>::apply(*(boost::begin(geometry) + id.multi_index), id);
}
};
template <typename Geometry>
struct result_type
{
typedef typename get_dispatch<Geometry>::result_type type;
};
//template <typename Geometry>
//struct result_type<Geometry const>
//{
// typedef typename get_dispatch<Geometry const>::result_type type;
//};
// This function also works for geometry::segment_identifier
template <typename Geometry, typename Id> inline
typename get_dispatch<Geometry>::result_type
get(Geometry & g, Id const& id)
{
return get_dispatch<Geometry>::apply(g, id);
};
//template <typename Geometry, typename Id> inline
//typename get_dispatch<Geometry>::result_type
//get(Geometry const& g, Id const& id)
//{
// return get_dispatch<Geometry const>::apply(g, id);
//};
} // namespace sub_geometry
} // namespace detail
#endif
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_MYSQL_ALGORITHMS_DETAIL_SUB_GEOMETRY_HPP

View File

@@ -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 <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/strategies/concepts/within_concept.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
#include <boost/geometry/strategies/within.hpp>
namespace boost { namespace geometry {
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace within {
template <typename Point, typename Range, typename Strategy> inline
int point_in_range(Point const& point, Range const& range, Strategy const& strategy)
{
typedef typename boost::range_iterator<Range const>::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 <typename G, typename T = typename geometry::tag<G>::type>
struct point_in_geometry_dispatch
{
BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (T));
};
template <typename Box>
struct point_in_geometry_dispatch<Box, box_tag>
{
template <typename Point, typename Strategy> 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 <typename Linestring>
struct point_in_geometry_dispatch<Linestring, linestring_tag>
{
template <typename Point, typename Strategy> 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 <typename Ring>
struct point_in_geometry_dispatch<Ring, ring_tag>
{
template <typename Point, typename Strategy> static inline
int apply(Point const& point, Ring const& ring, Strategy const& strategy)
{
static const iterate_direction direction = order_as_direction<geometry::point_order<Ring>::value>::value;
static const closure_selector closure = geometry::closure<Ring>::value;
if (int(boost::size(ring))
< core_detail::closure::minimum_ring_size<closure>::value)
{
return -1;
}
typedef typename reversible_view<Ring const, direction>::type rev_view_type;
typedef typename closeable_view
<
rev_view_type const, closure
>::type cl_view_type;
typedef typename boost::range_iterator<cl_view_type const>::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 <typename Polygon>
struct point_in_geometry_dispatch<Polygon, polygon_tag>
{
template <typename Point, typename Strategy>
static inline int apply(Point const& point, Polygon const& poly,
Strategy const& strategy)
{
int const code = point_in_geometry_dispatch
<
typename ring_type<Polygon>::type
>::apply(point, exterior_ring(poly), strategy);
if (code == 1)
{
typename interior_return_type<Polygon const>::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<Polygon>::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 <typename P, typename G, typename Strategy> inline
int point_in_geometry(P const& p, G const& g, Strategy const& strategy)
{
BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategyPolygonal<Strategy>) );
return point_in_geometry_dispatch<G>::apply(p, g, strategy);
}
template <typename P, typename G> inline
int point_in_geometry(P const& p, G const& g)
{
typedef typename point_type<P>::type point_type1;
typedef typename point_type<G>::type point_type2;
typedef typename strategy::within::services::default_strategy
<
typename tag<P>::type,
typename tag<G>::type,
typename tag<P>::type,
typename tag_cast<typename tag<G>::type, areal_tag>::type,
typename tag_cast
<
typename cs_tag<point_type1>::type, spherical_tag
>::type,
typename tag_cast
<
typename cs_tag<point_type2>::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

View File

@@ -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 <boost/geometry/algorithms/detail/point_on_border.hpp>
#include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
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 <typename G1, typename G2, typename T1 = typename geometry::tag<G1>::type, typename T2 = typename geometry::tag<G2>::type>
struct within_no_turns_dispatch
{
template <typename S> static inline
bool apply(G1 const& g1, G2 const& g2, S const& s)
{
typedef typename geometry::point_type<G1>::type point1_type;
point1_type p;
if ( !geometry::point_on_border(p, g1) )
return false;
return point_in_geometry(p, g2, s) >= 0;
}
};
template <typename G1, typename G2>
struct within_no_turns_dispatch<G1, G2, ring_tag, polygon_tag>
{
template <typename S> static inline
bool apply(G1 const& g1, G2 const& g2, S const& s)
{
typedef typename geometry::point_type<G1>::type point1_type;
typedef typename geometry::point_type<G2>::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<G2>::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 <typename G1, typename G2>
struct within_no_turns_dispatch<G1, G2, polygon_tag, polygon_tag>
{
template <typename S> static inline
bool apply(G1 const& g1, G2 const& g2, S const& s)
{
typedef typename geometry::point_type<G1>::type point1_type;
typedef typename geometry::point_type<G2>::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<G2>::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<G1>::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 <typename G1,
typename G2,
typename T1 = typename geometry::tag<G1>::type,
typename T2 = typename geometry::tag<G2>::type,
bool IsMulti1 = boost::is_base_of<geometry::multi_tag, T1>::value,
bool IsMulti2 = boost::is_base_of<geometry::multi_tag, T2>::value>
struct within_no_turns_multi_dispatch
{
template <typename S> static inline
bool apply(G1 const& g1, G2 const& g2, S const& s)
{
return within_no_turns_dispatch<G1, G2>::apply(g1, g2, s);
}
};
template <typename G1, typename G2, typename T1, typename T2>
struct within_no_turns_multi_dispatch<G1, G2, T1, T2, true, false>
{
template <typename S> 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<G1>::type subgeometry1;
typedef typename boost::range_const_iterator<G1>::type iterator;
for ( iterator it = boost::begin(g1) ; it != boost::end(g1) ; ++it )
{
if ( !within_no_turns_dispatch<subgeometry1, G2>::apply(*it, g2, s) )
return false;
}
return true;
}
};
template <typename G1, typename G2, typename T1, typename T2>
struct within_no_turns_multi_dispatch<G1, G2, T1, T2, false, true>
{
template <typename S> 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<G2>::type subgeometry2;
typedef typename boost::range_const_iterator<G2>::type iterator;
for ( iterator it = boost::begin(g2) ; it != boost::end(g2) ; ++it )
{
if ( within_no_turns_dispatch<G1, subgeometry2>::apply(g1, *it, s) )
return true;
}
return false;
}
};
template <typename G1, typename G2, typename T1, typename T2>
struct within_no_turns_multi_dispatch<G1, G2, T1, T2, true, true>
{
template <typename S> 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<G1>::type subgeometry1;
typedef typename boost::range_const_iterator<G1>::type iterator;
for ( iterator it = boost::begin(g1) ; it != boost::end(g1) ; ++it )
{
if ( !within_no_turns_multi_dispatch<subgeometry1, G2>::apply(*it, g2, s) )
return false;
}
return true;
}
};
template <typename G1, typename G2, typename S> inline
bool within_no_turns(G1 const& g1, G2 const& g2, S const& s)
{
return within_no_turns_multi_dispatch<G1, G2>::apply(g1, g2, s);
}
}} // namespace detail::within
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_WITHIN_NO_TURNS_HPP

View File

@@ -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 <boost/geometry/util/math.hpp>
#include <boost/geometry/algorithms/detail/overlay/do_reverse.hpp>
#include <boost/geometry/views/segment_view.hpp>
#include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
namespace boost { namespace geometry
{
@@ -115,21 +122,20 @@ struct disjoint_linear
typedef overlay::turn_info<point_type> turn_info;
std::deque<turn_info> turns;
static const bool reverse1 = overlay::do_reverse<geometry::point_order<Geometry1>::value>::value; // should be false
static const bool reverse2 = overlay::do_reverse<geometry::point_order<Geometry2>::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<typename Point, typename Geometry>
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<typename Linestring, typename Segment>
struct disjoint_linestring_segment
{
static inline
bool apply(Linestring const& ls, Segment const& seg)
{
return disjoint_linear
<
Linestring, segment_view<Segment>
>::apply(ls, geometry::segment_view<Segment>(seg));
}
};
template<typename Geometry1, typename Geometry2>
struct disjoint_linear_areal
{
static inline
bool apply(Geometry1 const& g1, Geometry2 const& g2)
{
// if there are intersections - return false
if ( !disjoint_linear<Geometry1, Geometry2>::apply(g1, g2) )
return false;
typedef typename point_type<Geometry1>::type point1_type;
point1_type p;
geometry::point_on_border(p, g1);
return !geometry::covered_by(p, g2);
}
};
template<typename Segment, typename Geometry>
struct disjoint_segment_areal
{
static inline
bool apply(Segment const& seg, Geometry const& g)
{
return disjoint_linear_areal
<
segment_view<Segment>, Geometry
>::apply(segment_view<Segment>(seg), g);
}
};
}} // namespace detail::disjoint
#endif // DOXYGEN_NO_DETAIL
@@ -312,11 +371,6 @@ struct disjoint<Segment1, Segment2, 2, segment_tag, segment_tag, Reverse>
: detail::disjoint::disjoint_segment<Segment1, Segment2>
{};
template <typename Linestring, typename Segment, bool Reverse>
struct disjoint<Linestring, Segment, 2, linestring_tag, segment_tag, Reverse>
: detail::disjoint::disjoint_linear<Linestring, Segment>
{};
template <typename Segment, typename Box, std::size_t DimensionCount, bool Reverse>
struct disjoint<Segment, Box, DimensionCount, segment_tag, box_tag, Reverse>
: detail::disjoint::disjoint_segment_box<Segment, Box>
@@ -327,6 +381,72 @@ struct disjoint<Linestring, Box, DimensionCount, linestring_tag, box_tag, Revers
: detail::disjoint::disjoint_linestring_box<Linestring, Box>
{};
//template <typename Linestring, typename Segment, bool Reverse>
//struct disjoint<Linestring, Segment, 2, linestring_tag, segment_tag, Reverse>
// : detail::disjoint::disjoint_linear<Linestring, Segment>
//{};
template<typename Linestring, typename Segment, std::size_t DimensionCount, bool Reverse>
struct disjoint<Linestring, Segment, DimensionCount, linestring_tag, segment_tag, Reverse>
: detail::disjoint::disjoint_linestring_segment<Linestring, Segment>
{};
template<typename Segment, typename Ring, std::size_t DimensionCount, bool Reverse>
struct disjoint<Segment, Ring, DimensionCount, segment_tag, ring_tag, Reverse>
: detail::disjoint::disjoint_segment_areal<Segment, Ring>
{};
template<typename Polygon, typename Segment, std::size_t DimensionCount, bool Reverse>
struct disjoint<Polygon, Segment, DimensionCount, polygon_tag, segment_tag, Reverse>
{
static inline
bool apply(Polygon const& g1, Segment const& g2)
{
return detail::disjoint::disjoint_segment_areal<Segment, Polygon>::apply(g2, g1);
}
};
template<typename Linestring, typename Polygon, std::size_t DimensionCount, bool Reverse>
struct disjoint<Linestring, Polygon, DimensionCount, linestring_tag, polygon_tag, Reverse>
: public detail::disjoint::disjoint_linear_areal<Linestring, Polygon>
{};
template<typename Linestring, typename Ring, std::size_t DimensionCount, bool Reverse>
struct disjoint<Linestring, Ring, DimensionCount, linestring_tag, ring_tag, Reverse>
: public detail::disjoint::disjoint_linear_areal<Linestring, Ring>
{};
// move the following specializations to multi/algorithms/disjoint.hpp?
template<typename MultiLinestring, typename Polygon, std::size_t DimensionCount, bool Reverse>
struct disjoint<MultiLinestring, Polygon, DimensionCount, multi_linestring_tag, polygon_tag, Reverse>
: public detail::disjoint::disjoint_linear_areal<MultiLinestring, Polygon>
{};
template<typename MultiLinestring, typename Ring, std::size_t DimensionCount, bool Reverse>
struct disjoint<MultiLinestring, Ring, DimensionCount, multi_linestring_tag, ring_tag, Reverse>
: public detail::disjoint::disjoint_linear_areal<MultiLinestring, Ring>
{};
template<typename Linestring, typename MultiPolygon, std::size_t DimensionCount, bool Reverse>
struct disjoint<Linestring, MultiPolygon, DimensionCount, linestring_tag, multi_polygon_tag, Reverse>
: public detail::disjoint::disjoint_linear_areal<Linestring, MultiPolygon>
{};
template<typename MultiLinestring, typename MultiPolygon, std::size_t DimensionCount, bool Reverse>
struct disjoint<MultiLinestring, MultiPolygon, DimensionCount, multi_linestring_tag, multi_polygon_tag, Reverse>
: public detail::disjoint::disjoint_linear_areal<MultiLinestring, MultiPolygon>
{};
template<typename Point, typename Linestring, std::size_t DimensionCount, bool Reverse>
struct disjoint<Point, Linestring, DimensionCount, point_tag, linestring_tag, Reverse>
: public detail::disjoint::disjoint_point_linear<Point, Linestring>
{};
template<typename Point, typename MultiLinestring, std::size_t DimensionCount, bool Reverse>
struct disjoint<Point, MultiLinestring, DimensionCount, point_tag, multi_linestring_tag, Reverse>
: public detail::disjoint::disjoint_point_linear<Point, MultiLinestring>
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH

View File

@@ -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 <boost/geometry/algorithms/intersects.hpp>
#include <boost/geometry/algorithms/num_geometries.hpp>
#include <boost/geometry/algorithms/detail/sub_geometry.hpp>
namespace boost { namespace geometry
{
@@ -34,55 +38,210 @@ namespace boost { namespace geometry
namespace detail { namespace touches
{
template <typename Turn>
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 <typename Turns>
inline bool has_only_turns(Turns const& turns)
{
bool has_touch = false;
typedef typename boost::range_iterator<Turns const>::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 <typename Range>
inline bool apply(Range const& range)
{
// if already rejected (temp workaround?)
if ( found_not_touch )
return true;
typedef typename boost::range_iterator<Range const>::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 <typename Turn>
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 <typename Linear>
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 <typename Range>
inline bool apply(Range const& range)
{
// if already rejected (temp workaround?)
if ( found_not_touch )
return true;
typedef typename boost::range_iterator<Range const>::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 <typename Turn>
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 <typename Turn>
inline bool is_turn_on_last_point(Turn const& turn)
{
typename sub_geometry::result_type<Linear const>::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 <std::size_t Max>
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 <typename Range>
inline bool apply(Range const& range)
{
turns_count += boost::size(range);
if ( Max < turns_count )
return true;
return false;
}
};
template<typename Geometry>
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 <typename FirstGeometry, typename SecondGeometry>
inline bool rings_containing(FirstGeometry const& geometry1,
@@ -117,10 +278,180 @@ inline bool rings_containing(FirstGeometry const& geometry1,
return checker.has_within;
}
template <typename Geometry1, typename Geometry2>
struct areal_areal
{
static inline
bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
{
typedef detail::overlay::turn_info
<
typename geometry::point_type<Geometry1>::type
> turn_info;
typedef detail::overlay::get_turn_info
<
detail::overlay::assign_null_policy
> policy_type;
std::deque<turn_info> turns;
detail::touches::areal_interrupt_policy policy;
boost::geometry::get_turns
<
detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
detail::overlay::do_reverse<geometry::point_order<Geometry2>::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 <typename Geometry1, typename Geometry2>
struct linear_areal
{
static inline
bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
{
typedef detail::overlay::turn_info
<
typename geometry::point_type<Geometry1>::type
> turn_info;
typedef detail::overlay::get_turn_info
<
detail::overlay::assign_null_policy
> policy_type;
std::deque<turn_info> turns;
detail::touches::linear_areal_interrupt_policy<Geometry1> policy(geometry1);
boost::geometry::get_turns
<
detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
detail::overlay::do_reverse<geometry::point_order<Geometry2>::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 <typename Point, typename Geometry>
struct point_geometry
{
static inline
bool apply(Point const& point, Geometry const& geometry)
{
return detail::within::point_in_geometry(point, geometry) == 0;
}
};
template <typename Geometry1, typename Geometry2>
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<Geometry1>::type
> turn_info;
typedef detail::overlay::get_turn_info
<
detail::overlay::assign_null_policy
> policy_type;
std::deque<turn_info> turns;
turns_count_interrupt_policy<2> policy;
boost::geometry::get_turns
<
detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
detail::overlay::do_reverse<geometry::point_order<Geometry2>::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<Geometry1>::type,
typename Tag2 = typename tag<Geometry2>::type,
bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
>
struct touches
: detail::touches::areal_areal<Geometry1, Geometry2>
{};
// If reversal is needed, perform it
template
<
typename Geometry1, typename Geometry2,
typename Tag1, typename Tag2
>
struct touches<Geometry1, Geometry2, Tag1, Tag2, true>
: touches<Geometry2, Geometry1, Tag2, Tag1, false>
{
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
{
return touches<Geometry2, Geometry1>::apply(g2, g1);
}
};
template <typename Point, typename Geometry, typename Tag2>
struct touches<Point, Geometry, point_tag, Tag2, false>
: detail::touches::point_geometry<Point, Geometry>
{};
template <typename Linestring1, typename Linestring2>
struct touches<Linestring1, Linestring2, linestring_tag, linestring_tag, false>
: detail::touches::linestring_linestring<Linestring1, Linestring2>
{};
template <typename Linestring, typename Polygon>
struct touches<Linestring, Polygon, linestring_tag, polygon_tag, false>
: detail::touches::linear_areal<Linestring, Polygon>
{};
} // 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<turn_info> 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<Geometry1 const>();
concept::check<Geometry2 const>();
typedef detail::overlay::turn_info
<
typename geometry::point_type<Geometry1>::type
> turn_info;
typedef detail::overlay::get_turn_info
<
detail::overlay::assign_null_policy
> policy_type;
std::deque<turn_info> turns;
detail::get_turns::no_interrupt_policy policy;
boost::geometry::get_turns
<
detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
detail::overlay::do_reverse<geometry::point_order<Geometry2>::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<Geometry1, Geometry2>::apply(geometry1, geometry2);
}
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_TOUCHES_HPP

View File

@@ -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 <boost/geometry/views/closeable_view.hpp>
#include <boost/geometry/views/reversible_view.hpp>
#include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
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<Strategy>) );
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<Closure>::value)
{
return -1;
}
typedef typename reversible_view<Ring const, Direction>::type rev_view_type;
typedef typename closeable_view
<
rev_view_type const, Closure
>::type cl_view_type;
typedef typename boost::range_iterator<cl_view_type const>::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<Strategy>) );
static inline int apply(Point const& point, Polygon const& poly,
Strategy const& strategy)
{
int const code = point_in_ring
<
Point,
typename ring_type<Polygon>::type,
Direction,
Closure,
Strategy
>::apply(point, exterior_ring(poly), strategy);
if (code == 1)
{
typename interior_return_type<Polygon const>::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<Polygon>::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<Point, Ring, point_tag, ring_tag>
template <typename Strategy>
static inline bool apply(Point const& point, Ring const& ring, Strategy const& strategy)
{
return detail::within::point_in_ring
<
Point,
Ring,
order_as_direction<geometry::point_order<Ring>::value>::value,
geometry::closure<Ring>::value,
Strategy
>::apply(point, ring, strategy) == 1;
return detail::within::point_in_geometry(point, ring, strategy) == 1;
}
};
@@ -228,14 +110,17 @@ struct within<Point, Polygon, point_tag, polygon_tag>
template <typename Strategy>
static inline bool apply(Point const& point, Polygon const& polygon, Strategy const& strategy)
{
return detail::within::point_in_polygon
<
Point,
Polygon,
order_as_direction<geometry::point_order<Polygon>::value>::value,
geometry::closure<Polygon>::value,
Strategy
>::apply(point, polygon, strategy) == 1;
return detail::within::point_in_geometry(point, polygon, strategy) == 1;
}
};
template <typename Point, typename Linestring>
struct within<Point, Linestring, point_tag, linestring_tag>
{
template <typename Strategy> static inline
bool apply(Point const& point, Linestring const& linestring, Strategy const& strategy)
{
return detail::within::point_in_geometry(point, linestring, strategy) == 1;
}
};

View File

@@ -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, point_tag, multi_polygon_tag>
Point,
MultiPolygon,
Strategy,
detail::within::point_in_polygon
<
Point,
typename boost::range_value<MultiPolygon>::type,
order_as_direction
<
geometry::point_order<MultiPolygon>::value
>::value,
geometry::closure<MultiPolygon>::value,
Strategy
>
detail::within::point_in_geometry_dispatch
<
typename boost::range_value<MultiPolygon>::type
>
>::apply(point, multi_polygon, strategy) >= 0;
}
};
template <typename Point, typename MultiLinestring>
struct covered_by<Point, MultiLinestring, point_tag, multi_linestring_tag>
{
template <typename Strategy>
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

View File

@@ -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<MultiGeometry>::type,
Reverse,
SegmentIdentifier,
PointOut
>
>
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH

View File

@@ -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<multi_polygon_tag, Point, Multi>
>
{};
template<typename Point, typename Multi>
struct point_on_border<multi_linestring_tag, Point, Multi>
: detail::point_on_border::point_on_multi
<
Point,
Multi,
detail::point_on_border::point_on_range
<
Point,
typename boost::range_value<Multi>::type
>
>
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH

View File

@@ -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<multi_polygon_tag, MultiPolygon, Section>
>
{};
template <typename MultiLinestring, typename Section>
struct range_by_section<multi_linestring_tag, MultiLinestring, Section>
: detail::section::full_section_multi
<
MultiLinestring,
Section,
detail::section::full_section_range
<
typename boost::range_value<MultiLinestring>::type,
Section
>
>
{};
} // namespace dispatch
#endif

View File

@@ -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<multi_polygon_tag, MultiPolygon, Reverse, DimensionCount>
struct sectionalize<multi_polygon_tag, MultiPolygon, Reverse, DimensionCount>
: detail::sectionalize::sectionalize_multi
<
DimensionCount,
@@ -88,6 +91,25 @@ struct sectionalize<multi_polygon_tag, MultiPolygon, Reverse, DimensionCount>
{};
template
<
typename MultiLinestring,
bool Reverse,
std::size_t DimensionCount
>
struct sectionalize<multi_linestring_tag, MultiLinestring, Reverse, DimensionCount>
: detail::sectionalize::sectionalize_multi
<
DimensionCount,
detail::sectionalize::sectionalize_range
<
closed, false,
typename point_type<MultiLinestring>::type,
DimensionCount
>
>
{};
} // namespace dispatch
#endif

View File

@@ -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 <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
namespace boost { namespace geometry {
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace within {
template <typename G>
struct point_in_geometry_dispatch<G, multi_polygon_tag>
{
template <typename P, typename S> 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<G>::type polygon_type;
typedef typename boost::range_const_iterator<G>::type iterator;
for ( iterator it = boost::begin(g) ; it != boost::end(g) ; ++it )
{
int pip = detail::within::point_in_geometry_dispatch<polygon_type>::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 <typename G>
struct point_in_geometry_dispatch<G, multi_linestring_tag>
{
template <typename P, typename S> static inline
int apply(P const& p, G const& g, S const& s)
{
int pip = -1; // outside
typedef typename boost::range_value<G>::type linestring_type;
typedef typename boost::range_value<linestring_type>::type point_type;
typedef typename boost::range_iterator<G const>::type iterator;
iterator it = boost::begin(g);
for ( ; it != boost::end(g) ; ++it )
{
pip = detail::within::point_in_geometry_dispatch<linestring_type>::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

View File

@@ -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 <boost/geometry/multi/core/tags.hpp>
#include <boost/geometry/multi/geometries/concepts/check.hpp>
#include <boost/geometry/multi/algorithms/detail/within/point_in_geometry.hpp>
namespace boost { namespace geometry
{
@@ -82,21 +88,25 @@ struct within<Point, MultiPolygon, point_tag, multi_polygon_tag>
Point,
MultiPolygon,
Strategy,
detail::within::point_in_polygon
<
Point,
typename boost::range_value<MultiPolygon>::type,
order_as_direction
<
geometry::point_order<MultiPolygon>::value
>::value,
geometry::closure<MultiPolygon>::value,
Strategy
>
detail::within::point_in_geometry_dispatch
<
typename boost::range_value<MultiPolygon>::type
>
>::apply(point, multi_polygon, strategy) == 1;
}
};
template <typename Point, typename MultiLinestring>
struct within<Point, MultiLinestring, point_tag, multi_linestring_tag>
{
template <typename Strategy>
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

View File

@@ -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<multi_polygon_tag, MultiPolygon>
>::type type;
};
template <typename MultiLinestring>
struct ring_return_type<multi_linestring_tag, MultiLinestring>
{
typedef typename ring_return_type
<
linestring_tag,
typename mpl::if_
<
boost::is_const<MultiLinestring>,
typename boost::range_value<MultiLinestring>::type const,
typename boost::range_value<MultiLinestring>::type
>::type
>::type type;
};
template <typename MultiPolygon>
struct ring_type<multi_polygon_tag, MultiPolygon>
@@ -55,6 +73,15 @@ struct ring_type<multi_polygon_tag, MultiPolygon>
>::type type;
};
template <typename MultiLinestring>
struct ring_type<multi_linestring_tag, MultiLinestring>
{
typedef typename boost::remove_reference
<
typename ring_return_type<multi_linestring_tag, MultiLinestring>::type
>::type type;
};
} // namespace core_dispatch
#endif

View File

@@ -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 <boost/geometry/multi/algorithms/unique.hpp>
#include <boost/geometry/multi/algorithms/within.hpp>
#include <boost/geometry/multi/algorithms/detail/within/point_in_geometry.hpp>
#include <boost/geometry/multi/algorithms/detail/point_on_border.hpp>
#include <boost/geometry/multi/algorithms/detail/for_each_range.hpp>
#include <boost/geometry/multi/algorithms/detail/modify_with_predicate.hpp>
#include <boost/geometry/multi/algorithms/detail/multi_sum.hpp>

View File

@@ -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<point_tag, AnyTag, point_tag, areal_tag, spherical_tag,
typedef winding<Point, typename geometry::point_type<Geometry>::type> type;
};
template <typename Point, typename Geometry>
struct default_strategy<point_tag, linestring_tag, point_tag, linestring_tag, cartesian_tag, cartesian_tag, Point, Geometry>
{
typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
};
// TODO: later move it to multi/strategies/agnostic
template <typename Point, typename Geometry>
struct default_strategy<point_tag, multi_linestring_tag, point_tag, multi_linestring_tag, cartesian_tag, cartesian_tag, Point, Geometry>
{
typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
};
} // namespace services
@@ -221,6 +237,18 @@ struct default_strategy<point_tag, AnyTag, point_tag, areal_tag, spherical_tag,
typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
};
template <typename Point, typename Geometry>
struct default_strategy<point_tag, linestring_tag, point_tag, linestring_tag, cartesian_tag, cartesian_tag, Point, Geometry>
{
typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
};
// TODO: later move it to multi/strategies/agnostic
template <typename Point, typename Geometry>
struct default_strategy<point_tag, multi_linestring_tag, point_tag, multi_linestring_tag, cartesian_tag, cartesian_tag, Point, Geometry>
{
typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
};
}}} // namespace strategy::covered_by::services
#endif

View File

@@ -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<P> ls;
test_geometry<P, ls>("POINT(0 0)", "LINESTRING(0 0,1 1,2 2)", true);
test_geometry<P, ls>("POINT(3 3)", "LINESTRING(0 0,1 1,2 2)", false);
test_geometry<P, ls>("POINT(1 1)", "LINESTRING(0 0,2 2,3 3)", true);
// multi_linestrings
typedef bg::model::multi_linestring<ls> mls;
test_geometry<P, mls>("POINT(0 0)", "MULTILINESTRING((0 0,1 1,2 2),(0 0,0 1))", true);
test_geometry<P, mls>("POINT(0 0)", "MULTILINESTRING((0 0,1 1,2 2),(0 0,0 1),(0 0,1 0))", true);
typedef bg::model::box<P> box_type;
test_geometry<P, box_type>("POINT(1 1)", "BOX(0 0,2 2)", true);

View File

@@ -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 <boost/geometry/util/rational.hpp>
template <typename P>
void test_intersects_polygon_polygon()
{
typedef bg::model::polygon<P, false, false> poly_ccw_o;
test_geometry<poly_ccw_o, poly_ccw_o>("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<poly_ccw_o, poly_ccw_o>("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<poly_ccw_o, poly_ccw_o>("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 <typename P>
void test_intersects_linestring_segment()
{
typedef bg::model::linestring<P> ls;
typedef bg::model::segment<P> seg;
test_geometry<ls, seg>("LINESTRING(1 1, 3 3, 2 5)", "SEGMENT(2 0, 2 6)", true);
test_geometry<ls, seg>("LINESTRING(1 1, 3 3)", "SEGMENT(1 0, 1 1)", true);
test_geometry<ls, seg>("LINESTRING(1 1, 3 3)", "SEGMENT(2 0, 2 2)", true);
test_geometry<ls, seg>("LINESTRING(1 1, 3 3)", "SEGMENT(3 0, 4 1)", false);
}
template <typename P>
void test_intersects_linestring_polygon()
{
typedef bg::model::linestring<P> ls;
typedef bg::model::multi_linestring<ls> mls;
typedef bg::model::polygon<P> poly_cw_c;
typedef bg::model::polygon<P, false> poly_ccw_c;
typedef bg::model::polygon<P, false, false> poly_ccw_o;
typedef bg::model::multi_polygon<poly_ccw_c> mpoly_ccw_c;
test_geometry<ls, poly_ccw_c>("LINESTRING(1 1,2 2)", "POLYGON((0 0,10 0,10 10,0 10,0 0))", true);
test_geometry<ls, poly_ccw_c>("LINESTRING(1 0,2 2)", "POLYGON((0 0,10 0,10 10,0 10,0 0))", true);
test_geometry<ls, poly_ccw_c>("LINESTRING(11 0,12 12)", "POLYGON((0 0,10 0,10 10,0 10,0 0))", false);
test_geometry<ls, poly_ccw_o>("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<ls, poly_ccw_o>("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<ls, poly_ccw_o>("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<poly_cw_c, ls>("POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))", "LINESTRING(-2 -2, 12 7)", true);
test_geometry<poly_cw_c, ls>("POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))", "LINESTRING(5 5, 15 4)", true);
test_geometry<poly_cw_c, ls>("POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))", "LINESTRING(7 6, 15 4)", true);
test_geometry<poly_cw_c, ls>("POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))", "LINESTRING(6 2, 12 1)", true);
// MULTI
test_geometry<ls, mpoly_ccw_c>("LINESTRING(1 1,2 2)", "MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)))", true);
test_geometry<mls, mpoly_ccw_c>("MULTILINESTRING((1 1,2 2))", "MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)))", true);
}
template <typename P>
void test_intersects_linestring_ring()
{
typedef bg::model::linestring<P> ls;
typedef bg::model::multi_linestring<ls> mls;
typedef bg::model::ring<P, false> ring_ccw_c;
test_geometry<ls, ring_ccw_c>("LINESTRING(1 1,2 2)", "POLYGON((0 0,10 0,10 10,0 10,0 0))", true);
test_geometry<ls, ring_ccw_c>("LINESTRING(1 0,2 2)", "POLYGON((0 0,10 0,10 10,0 10,0 0))", true);
test_geometry<ls, ring_ccw_c>("LINESTRING(11 0,12 12)", "POLYGON((0 0,10 0,10 10,0 10,0 0))", false);
// MULTI
test_geometry<mls, ring_ccw_c>("MULTILINESTRING((1 1,2 2))", "POLYGON((0 0,10 0,10 10,0 10,0 0))", true);
}
template <typename P>
void test_intersects_ring_polygon()
{
typedef bg::model::ring<P, false, false> ring_ccw_o;
typedef bg::model::polygon<P, false, false> poly_ccw_o;
test_geometry<ring_ccw_o, poly_ccw_o>("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<ring_ccw_o, poly_ccw_o>("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<ring_ccw_o, poly_ccw_o>("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<ring_ccw_o, poly_ccw_o>("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 <typename P>
void test_intersects_point_linestring()
{
typedef bg::model::linestring<P> ls;
typedef bg::model::multi_linestring<ls> mls;
test_geometry<P, ls>("POINT(0 0)", "LINESTRING(0 0,2 2,4 0)", true);
test_geometry<P, ls>("POINT(1 1)", "LINESTRING(0 0,2 2,4 0)", true);
test_geometry<P, ls>("POINT(1 0)", "LINESTRING(0 0,2 2,4 0)", false);
// MULTI
test_geometry<P, mls>("POINT(0 0)", "MULTILINESTRING((0 0,2 2,4 0))", true);
}
template <typename P>
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<P>();
test_intersects_polygon_polygon<P>();
test_intersects_linestring_polygon<P>();
test_intersects_linestring_ring<P>();
test_intersects_linestring_segment<P>();
test_intersects_ring_polygon<P>();
// self-intersecting is not tested in disjoint, so that is done here.

View File

@@ -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 <boost/geometry/io/wkt/read.hpp>
#include <boost/geometry/multi/algorithms/covered_by.hpp>
#include <boost/geometry/multi/geometries/multi_linestring.hpp>
#include <boost/geometry/multi/io/wkt/read.hpp>
template <typename Geometry1, typename Geometry2>
void check_geometry(Geometry1 const& geometry1,

View File

@@ -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 <boost/geometry/io/wkt/read.hpp>
#include <boost/geometry/multi/core/geometry_id.hpp>
#include <boost/geometry/multi/core/point_order.hpp>
#include <boost/geometry/multi/core/ring_type.hpp>
#include <boost/geometry/multi/algorithms/covered_by.hpp>
#include <boost/geometry/multi/algorithms/detail/point_on_border.hpp>
#include <boost/geometry/multi/algorithms/detail/sections/sectionalize.hpp>
#include <boost/geometry/multi/algorithms/detail/sections/range_by_section.hpp>
#include <boost/geometry/multi/views/detail/range_type.hpp>
#include <boost/geometry/multi/geometries/multi_linestring.hpp>
#include <boost/geometry/multi/geometries/multi_polygon.hpp>
#include <boost/geometry/multi/io/wkt/read.hpp>
template <typename Geometry1, typename Geometry2>
void test_geometry(std::string const& wkt1,

View File

@@ -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 <boost/geometry/strategies/strategies.hpp>
#include <boost/geometry/geometries/ring.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/linestring.hpp>
#include <boost/geometry/io/wkt/read.hpp>
#include <boost/geometry/multi/core/point_order.hpp>
#include <boost/geometry/multi/core/geometry_id.hpp>
#include <boost/geometry/multi/algorithms/detail/for_each_range.hpp>
#include <boost/geometry/multi/algorithms/detail/within/point_in_geometry.hpp>
#include <boost/geometry/multi/geometries/multi_linestring.hpp>
#include <boost/geometry/multi/geometries/multi_polygon.hpp>
#include <boost/geometry/multi/io/wkt/read.hpp>
template <typename Geometry1, typename Geometry2>
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);
}

View File

@@ -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 <boost/geometry/strategies/cartesian/box_in_box.hpp>
#include <boost/geometry/strategies/agnostic/point_in_box_by_side.hpp>
#include <boost/geometry/multi/algorithms/covered_by.hpp>
#include <boost/geometry/multi/geometries/multi_linestring.hpp>
#include <boost/geometry/multi/io/wkt/read.hpp>
template <typename Geometry1, typename Geometry2>
void check_geometry(Geometry1 const& geometry1,

View File

@@ -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 <typename P>
void test_all()
{
typedef bg::model::polygon<P> polygon;
typedef bg::model::linestring<P> linestring;
typedef bg::model::multi_polygon<polygon> mpolygon;
typedef bg::model::multi_linestring<linestring> mlinestring;
// Just a normal polygon
test_self_touches<polygon>("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<P, polygon>("POINT(40 50)", "POLYGON((40 40,40 60,60 60,60 40,40 40))", true);
test_touches<P, polygon>("POINT(60 60)", "POLYGON((40 40,40 60,60 60,60 40,40 40))", true);
test_touches<P, polygon>("POINT(50 50)", "POLYGON((40 40,40 60,60 60,60 40,40 40))", false);
test_touches<P, polygon>("POINT(30 50)", "POLYGON((40 40,40 60,60 60,60 40,40 40))", false);
// Point-MultiPolygon
test_touches<P, mpolygon>("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<P, linestring>("POINT(0 0)", "LINESTRING(0 0, 2 2, 10 2)", true);
test_touches<P, linestring>("POINT(2 2)", "LINESTRING(0 0, 2 2, 10 2)", false);
test_touches<P, linestring>("POINT(1 1)", "LINESTRING(0 0, 2 2, 10 2)", false);
test_touches<P, linestring>("POINT(5 5)", "LINESTRING(0 0, 2 2, 10 2)", false);
// Point-MultiLinestring
test_touches<P, mlinestring>("POINT(0 0)", "MULTILINESTRING((0 0, 2 2, 10 2),(5 5, 6 6))", true);
test_touches<P, mlinestring>("POINT(0 0)", "MULTILINESTRING((0 0, 2 2, 10 2),(0 0, 6 6))", false);
// Linestring-Linestring
test_touches<linestring, linestring>("LINESTRING(0 0,2 0)", "LINESTRING(0 0,0 2)", true);
test_touches<linestring, linestring>("LINESTRING(0 0,2 0)", "LINESTRING(2 0,2 2)", true);
test_touches<linestring, linestring>("LINESTRING(0 0,2 0)", "LINESTRING(0 2,0 0)", true);
test_touches<linestring, linestring>("LINESTRING(0 0,2 0)", "LINESTRING(2 2,2 0)", true);
test_touches<linestring, linestring>("LINESTRING(2 0,0 0)", "LINESTRING(0 0,0 2)", true);
test_touches<linestring, linestring>("LINESTRING(2 0,0 0)", "LINESTRING(2 0,2 2)", true);
test_touches<linestring, linestring>("LINESTRING(2 0,0 0)", "LINESTRING(0 2,0 0)", true);
test_touches<linestring, linestring>("LINESTRING(2 0,0 0)", "LINESTRING(2 2,2 0)", true);
test_touches<linestring, linestring>("LINESTRING(0 0,2 0)", "LINESTRING(1 0,1 1)", true);
test_touches<linestring, linestring>("LINESTRING(0 0,2 0)", "LINESTRING(1 1,1 0)", true);
test_touches<linestring, linestring>("LINESTRING(2 0,0 0)", "LINESTRING(1 0,1 1)", true);
test_touches<linestring, linestring>("LINESTRING(2 0,0 0)", "LINESTRING(1 1,1 0)", true);
test_touches<linestring, linestring>("LINESTRING(0 0,10 0)", "LINESTRING(0 0,5 5,10 0)", true);
test_touches<linestring, linestring>("LINESTRING(0 0,10 10)", "LINESTRING(0 0,0 5,10 5)", false);
test_touches<linestring, linestring>("LINESTRING(0 5,5 6,10 5)", "LINESTRING(0 7,5 6,10 7)", false);
test_touches<linestring, linestring>("LINESTRING(0 5,5 6,10 5)", "LINESTRING(10 7,5 6,0 7)", false);
test_touches<linestring, linestring>("LINESTRING(10 5,5 6,0 5)", "LINESTRING(0 7,5 6,10 7)", false);
test_touches<linestring, linestring>("LINESTRING(10 5,5 6,0 5)", "LINESTRING(10 7,5 6,0 7)", false);
test_touches<linestring, linestring>("LINESTRING(0 0,1 1,2 2)", "LINESTRING(2 0,2 2,1 2,1 1)", true);
test_touches<linestring, linestring>("LINESTRING(2 2,1 1,0 0)", "LINESTRING(2 0,2 2,1 2,1 1)", true);
test_touches<linestring, linestring>("LINESTRING(0 0,1 1,2 2)", "LINESTRING(1 1,1 2,2 2,2 0)", true);
test_touches<linestring, linestring>("LINESTRING(2 2,1 1,0 0)", "LINESTRING(1 1,1 2,2 2,2 0)", true);
//Linestring-Polygon
test_touches<linestring, polygon>("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, polygon>("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, polygon>("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, polygon>("LINESTRING(0 15,5 5)", "POLYGON((0 0,0 10,10 10,10 0,0 0))", false);
test_touches<linestring, polygon>("LINESTRING(0 15,5 10,5 5)", "POLYGON((0 0,0 10,10 10,10 0,0 0))", false);
test_touches<linestring, polygon>("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
*/
*/

View File

@@ -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<P, bg::model::polygon<P> >("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<P> ls;
test_geometry<P, ls>("POINT(0 0)", "LINESTRING(0 0,1 1,2 2)", false);
test_geometry<P, ls>("POINT(3 3)", "LINESTRING(0 0,1 1,2 2)", false);
test_geometry<P, ls>("POINT(1 1)", "LINESTRING(0 0,2 2,3 3)", true);
// multi_linestrings
typedef bg::model::multi_linestring<ls> mls;
test_geometry<P, mls>("POINT(0 0)", "MULTILINESTRING((0 0,1 1,2 2),(0 0,0 1))", true);
test_geometry<P, mls>("POINT(0 0)", "MULTILINESTRING((0 0,1 1,2 2),(0 0,0 1),(0 0,1 0))", false);
typedef bg::model::box<P> box_type;
test_geometry<P, box_type>("POINT(1 1)", "BOX(0 0,2 2)", true);