mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-11 11:52:11 +00:00
Merge branch 'develop' of https://github.com/boostorg/geometry into feature/disjoint-1.57
This commit is contained in:
@@ -177,10 +177,12 @@ WARN_LOGFILE =
|
||||
INPUT = . .. ../../../../boost/geometry/core \
|
||||
../../../../boost/geometry/algorithms \
|
||||
../../../../boost/geometry/algorithms/detail \
|
||||
../../../../boost/geometry/algorithms/detail/buffer \
|
||||
../../../../boost/geometry/algorithms/detail/comparable_distance \
|
||||
../../../../boost/geometry/algorithms/detail/disjoint \
|
||||
../../../../boost/geometry/algorithms/detail/distance \
|
||||
../../../../boost/geometry/algorithms/detail/equals \
|
||||
../../../../boost/geometry/algorithms/detail/intersection \
|
||||
../../../../boost/geometry/algorithms/detail/is_simple \
|
||||
../../../../boost/geometry/algorithms/detail/is_valid \
|
||||
../../../../boost/geometry/algorithms/detail/overlay \
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
\defgroup num_geometries number of geometries: calculate the number of geometries in a multi-geometry
|
||||
\defgroup num_interior_rings number of interior rings: calculate the number of interior rings
|
||||
\defgroup num_points number of points: calculate number of points of a geometry
|
||||
\defgroup num_segments number of segments: calculate number of segments of a geometry
|
||||
\defgroup overlaps overlaps: detect overlap between two geometries
|
||||
\defgroup perimeter perimeter: calculate perimeter of a geometry
|
||||
\defgroup projection projection: Projection struct's, classes
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
[import src/examples/algorithms/num_geometries.cpp]
|
||||
[import src/examples/algorithms/num_interior_rings.cpp]
|
||||
[import src/examples/algorithms/num_points.cpp]
|
||||
[import src/examples/algorithms/num_segments.cpp]
|
||||
[import src/examples/algorithms/reverse.cpp]
|
||||
[import src/examples/algorithms/return_envelope.cpp]
|
||||
[import src/examples/algorithms/simplify.cpp]
|
||||
|
||||
@@ -85,9 +85,9 @@ algorithms = ["append", "assign", "make", "clear"
|
||||
, "convex_hull", "crosses", "difference", "disjoint", "distance"
|
||||
, "envelope", "equals", "expand", "for_each", "is_simple", "is_valid"
|
||||
, "intersection", "intersects", "length", "num_geometries"
|
||||
, "num_interior_rings", "num_points", "overlaps", "perimeter"
|
||||
, "reverse", "simplify", "sym_difference", "touches", "transform"
|
||||
, "union", "unique", "within"]
|
||||
, "num_interior_rings", "num_points", "num_segments", "overlaps"
|
||||
, "perimeter", "reverse", "simplify", "sym_difference", "touches"
|
||||
, "transform", "union", "unique", "within"]
|
||||
|
||||
access_functions = ["get", "set", "exterior_ring", "interior_rings"
|
||||
, "num_points", "num_interior_rings", "num_geometries"]
|
||||
|
||||
@@ -424,6 +424,7 @@
|
||||
<member><link linkend="geometry.reference.algorithms.num_interior_rings">num_interior_rings</link></member>
|
||||
<member><link linkend="geometry.reference.algorithms.num_geometries">num_geometries</link></member>
|
||||
<member><link linkend="geometry.reference.algorithms.num_points">num_points</link></member>
|
||||
<member><link linkend="geometry.reference.algorithms.num_segments">num_segments</link></member>
|
||||
</simplelist>
|
||||
|
||||
|
||||
|
||||
@@ -136,6 +136,7 @@
|
||||
[include generated/num_geometries.qbk]
|
||||
[include generated/num_interior_rings.qbk]
|
||||
[include generated/num_points.qbk]
|
||||
[include generated/num_segments.qbk]
|
||||
|
||||
|
||||
[include generated/overlaps.qbk]
|
||||
|
||||
35
doc/reference/algorithms/num_segments.qbk
Normal file
35
doc/reference/algorithms/num_segments.qbk
Normal file
@@ -0,0 +1,35 @@
|
||||
[/============================================================================
|
||||
Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
Licensed under the Boost Software License version 1.0.
|
||||
http://www.boost.org/users/license.html
|
||||
=============================================================================/]
|
||||
|
||||
[def __this_function__ num_segments]
|
||||
|
||||
[heading_conformance_no_ogc __this_function__]
|
||||
|
||||
[heading Behavior]
|
||||
[table
|
||||
[[Case] [Behavior] ]
|
||||
[[__point__][[qbk_ret 0]]]
|
||||
[[__segment__][[qbk_ret 1]]]
|
||||
[[__box__][[qbk_ret 4]]]
|
||||
[[__range__][[qbk_ret boost::size(geometry) - 1]]]
|
||||
[[__other__][[qbk_ret the sum of the number of segments of its elements]]]
|
||||
[[Open geometries][[qbk_ret the sum of the number of segments of its elements, it adds one for open (per ring) if specified]]]
|
||||
[[Closed geometries][[qbk_ret the sum of the number of segments of its elements]]]
|
||||
]
|
||||
|
||||
|
||||
[heading Complexity]
|
||||
Constant or Linear
|
||||
|
||||
[heading Examples]
|
||||
[num_segments]
|
||||
[num_segments_output]
|
||||
|
||||
@@ -39,14 +39,18 @@
|
||||
[*Solved tickets]
|
||||
|
||||
* [@https://svn.boost.org/trac/boost/ticket/8310 8310] Wrong results with overlapping polygons (fixed using point_on_surface for disjoint)
|
||||
* [@https://svn.boost.org/trac/boost/ticket/8375 8375] sym_difference of non-closed polygons returns closed polygon
|
||||
* [@https://svn.boost.org/trac/boost/ticket/8376 8376] difference of non-closed polygons returns closed polygon
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9081 9081] Booleans create self-intersecting polygons from non-self-intersecting polygons
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9245 9245] Check for process errors in make_qbk.py
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9563 9563] (Sym)difference not successful, fixed by rescaling to robust type
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9628 9628] Wrong result of within() due to the winding strategy not working correctly for nearly-horizontal segments
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9828 9828] boost::geometry::union_(...) creates redundant closing point
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9871 9871] Remove spike in polygon with only a spike
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9947 9947] Missing info about WKT in documentation
|
||||
* [@https://svn.boost.org/trac/boost/ticket/10019 10019] Difference of Linestring and Box returns their intersection
|
||||
* [@https://svn.boost.org/trac/boost/ticket/10077 10077] Wrong types in concept checks in boost/geometry/arithmetic/arithmetic.hpp
|
||||
* [@https://svn.boost.org/trac/boost/ticket/10234 10234] Wrong results of covered_by() for nearly-horizontal segments
|
||||
|
||||
[*Bugfixes]
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <boost/geometry/algorithms/num_geometries.hpp>
|
||||
#include <boost/geometry/algorithms/num_interior_rings.hpp>
|
||||
#include <boost/geometry/algorithms/num_points.hpp>
|
||||
#include <boost/geometry/algorithms/num_segments.hpp>
|
||||
#include <boost/geometry/algorithms/overlaps.hpp>
|
||||
#include <boost/geometry/algorithms/perimeter.hpp>
|
||||
#include <boost/geometry/algorithms/reverse.hpp>
|
||||
@@ -129,6 +130,7 @@ DECLARE_UNARY_ALGORITHM(length)
|
||||
DECLARE_UNARY_ALGORITHM(num_geometries)
|
||||
DECLARE_UNARY_ALGORITHM(num_interior_rings)
|
||||
DECLARE_UNARY_ALGORITHM(num_points)
|
||||
DECLARE_UNARY_ALGORITHM(num_segments)
|
||||
DECLARE_BINARY_ALGORITHM(overlaps)
|
||||
DECLARE_UNARY_ALGORITHM(perimeter)
|
||||
DECLARE_UNARY_ALGORITHM(reverse)
|
||||
|
||||
@@ -66,6 +66,7 @@ exe make_inverse : make_inverse.cpp ;
|
||||
exe num_geometries : num_geometries.cpp ;
|
||||
exe num_interior_rings : num_interior_rings.cpp ;
|
||||
exe num_points : num_points.cpp ;
|
||||
exe num_segments : num_segments.cpp ;
|
||||
|
||||
exe return_envelope : return_envelope.cpp ;
|
||||
|
||||
|
||||
46
doc/src/examples/algorithms/num_segments.cpp
Normal file
46
doc/src/examples/algorithms/num_segments.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// QuickBook Example
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
//[num_segments
|
||||
//` Get the number of segments in a geometry
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/geometry.hpp>
|
||||
#include <boost/geometry/geometries/point_xy.hpp>
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::geometry::model::multi_polygon
|
||||
<
|
||||
boost::geometry::model::polygon
|
||||
<
|
||||
boost::geometry::model::d2::point_xy<double>, true, false // cw, open polygon
|
||||
>
|
||||
> mp;
|
||||
boost::geometry::read_wkt("MULTIPOLYGON(((0 0,0 10,10 0),(1 1,8 1,1 8)),((10 10,10 20,20 10)))", mp);
|
||||
std::cout << "Number of segments: " << boost::geometry::num_segments(mp) << std::endl;
|
||||
std::cout << "Number of segments (add_to_open <- true): " << boost::geometry::num_segments(mp, true) << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//]
|
||||
|
||||
|
||||
//[num_segments_output
|
||||
/*`
|
||||
Output:
|
||||
[pre
|
||||
Number of segments: 6
|
||||
Number of segments (add_to_open <- true): 9
|
||||
]
|
||||
*/
|
||||
//]
|
||||
@@ -8,6 +8,7 @@
|
||||
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
@@ -20,6 +21,10 @@
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_APPEND_HPP
|
||||
|
||||
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/num_interior_rings.hpp>
|
||||
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
@@ -28,9 +33,7 @@
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/geometries/variant.hpp>
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@@ -98,7 +101,7 @@ struct point_to_polygon
|
||||
else if (ring_index < int(num_interior_rings(polygon)))
|
||||
{
|
||||
append_point<ring_type, Point>::apply(
|
||||
interior_rings(polygon)[ring_index], point);
|
||||
range::at(interior_rings(polygon), ring_index), point);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -120,7 +123,7 @@ struct range_to_polygon
|
||||
else if (ring_index < int(num_interior_rings(polygon)))
|
||||
{
|
||||
append_range<ring_type, Range>::apply(
|
||||
interior_rings(polygon)[ring_index], range);
|
||||
range::at(interior_rings(polygon), ring_index), range);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -202,6 +205,71 @@ struct append<Geometry, RangeOrPoint, point_tag>
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace append
|
||||
{
|
||||
|
||||
template <typename MultiGeometry, typename RangeOrPoint>
|
||||
struct append_to_multigeometry
|
||||
{
|
||||
static inline void apply(MultiGeometry& multigeometry,
|
||||
RangeOrPoint const& range_or_point,
|
||||
int ring_index, int multi_index)
|
||||
{
|
||||
|
||||
dispatch::append
|
||||
<
|
||||
typename boost::range_value<MultiGeometry>::type,
|
||||
RangeOrPoint
|
||||
>::apply(range::at(multigeometry, multi_index), range_or_point, ring_index);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::append
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
namespace splitted_dispatch
|
||||
{
|
||||
|
||||
template <typename Geometry, typename Point>
|
||||
struct append_point<multi_point_tag, Geometry, Point>
|
||||
: detail::append::append_point<Geometry, Point>
|
||||
{};
|
||||
|
||||
template <typename Geometry, typename Range>
|
||||
struct append_range<multi_point_tag, Geometry, Range>
|
||||
: detail::append::append_range<Geometry, Range>
|
||||
{};
|
||||
|
||||
template <typename MultiGeometry, typename RangeOrPoint>
|
||||
struct append_point<multi_linestring_tag, MultiGeometry, RangeOrPoint>
|
||||
: detail::append::append_to_multigeometry<MultiGeometry, RangeOrPoint>
|
||||
{};
|
||||
|
||||
template <typename MultiGeometry, typename RangeOrPoint>
|
||||
struct append_range<multi_linestring_tag, MultiGeometry, RangeOrPoint>
|
||||
: detail::append::append_to_multigeometry<MultiGeometry, RangeOrPoint>
|
||||
{};
|
||||
|
||||
template <typename MultiGeometry, typename RangeOrPoint>
|
||||
struct append_point<multi_polygon_tag, MultiGeometry, RangeOrPoint>
|
||||
: detail::append::append_to_multigeometry<MultiGeometry, RangeOrPoint>
|
||||
{};
|
||||
|
||||
template <typename MultiGeometry, typename RangeOrPoint>
|
||||
struct append_range<multi_polygon_tag, MultiGeometry, RangeOrPoint>
|
||||
: detail::append::append_to_multigeometry<MultiGeometry, RangeOrPoint>
|
||||
{};
|
||||
|
||||
} // namespace splitted_dispatch
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
namespace resolve_variant {
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
#include <boost/geometry/views/closeable_view.hpp>
|
||||
#include <boost/geometry/views/reversible_view.hpp>
|
||||
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/point_order.hpp>
|
||||
@@ -111,7 +113,7 @@ struct box_to_range
|
||||
assign_box_corners_oriented<Reverse>(box, range);
|
||||
if (Close)
|
||||
{
|
||||
range[4] = range[0];
|
||||
range::at(range, 4) = range::at(range, 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -160,13 +162,17 @@ struct range_to_range
|
||||
// point for open output.
|
||||
view_type view(rview);
|
||||
|
||||
int n = boost::size(view);
|
||||
typedef typename boost::range_size<Range1>::type size_type;
|
||||
size_type n = boost::size(view);
|
||||
if (geometry::closure<Range2>::value == geometry::open)
|
||||
{
|
||||
n--;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
// If size == 0 && geometry::open <=> n = numeric_limits<size_type>::max()
|
||||
// but ok, sice below it == end()
|
||||
|
||||
size_type i = 0;
|
||||
for (typename boost::range_iterator<view_type const>::type it
|
||||
= boost::begin(view);
|
||||
it != boost::end(view) && i < n;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/algorithms/detail/assign_values.hpp>
|
||||
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@@ -80,12 +80,16 @@ inline void assign_box_corners_oriented(Box const& box, Range& corners)
|
||||
if (Reverse)
|
||||
{
|
||||
// make counterclockwise ll,lr,ur,ul
|
||||
assign_box_corners(box, corners[0], corners[1], corners[3], corners[2]);
|
||||
assign_box_corners(box,
|
||||
range::at(corners, 0), range::at(corners, 1),
|
||||
range::at(corners, 3), range::at(corners, 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
// make clockwise ll,ul,ur,lr
|
||||
assign_box_corners(box, corners[0], corners[3], corners[1], corners[2]);
|
||||
assign_box_corners(box,
|
||||
range::at(corners, 0), range::at(corners, 3),
|
||||
range::at(corners, 1), range::at(corners, 2));
|
||||
}
|
||||
}
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <boost/geometry/arithmetic/dot_product.hpp>
|
||||
#include <boost/geometry/algorithms/equals.hpp>
|
||||
#include <boost/geometry/algorithms/expand.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/box_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/point_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
|
||||
#include <boost/geometry/strategies/buffer.hpp>
|
||||
@@ -42,7 +42,11 @@ struct turn_ovelaps_box
|
||||
template <typename Box, typename Turn>
|
||||
static inline bool apply(Box const& box, Turn const& turn)
|
||||
{
|
||||
return ! geometry::disjoint(box, turn.robust_point);
|
||||
return ! dispatch::disjoint
|
||||
<
|
||||
typename Turn::robust_point_type,
|
||||
Box
|
||||
>::apply(turn.robust_point, box);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -14,9 +14,10 @@
|
||||
#include <vector>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
@@ -103,7 +104,7 @@ public:
|
||||
<
|
||||
Strategy
|
||||
>::apply(strategy);
|
||||
boost::ignore_unused_variable_warning(cstrategy);
|
||||
boost::ignore_unused(cstrategy);
|
||||
|
||||
// get segment points
|
||||
segment_point p[2];
|
||||
@@ -181,7 +182,7 @@ public:
|
||||
<
|
||||
Strategy
|
||||
>::apply(strategy);
|
||||
boost::ignore_unused_variable_warning(cstrategy);
|
||||
boost::ignore_unused(cstrategy);
|
||||
|
||||
// get segment points
|
||||
segment_point p[2];
|
||||
@@ -199,7 +200,7 @@ public:
|
||||
}
|
||||
|
||||
point_box_comparable_strategy pb_cstrategy;
|
||||
boost::ignore_unused_variable_warning(pb_cstrategy);
|
||||
boost::ignore_unused(pb_cstrategy);
|
||||
cd[4] = pb_cstrategy.apply(p[0], box);
|
||||
cd[5] = pb_cstrategy.apply(p[1], box);
|
||||
|
||||
@@ -281,6 +282,8 @@ private:
|
||||
PPStrategy const& pp_strategy,
|
||||
PSStrategy const& ps_strategy)
|
||||
{
|
||||
boost::ignore_unused(pp_strategy, ps_strategy);
|
||||
|
||||
// the implementation below is written for non-negative slope
|
||||
// segments
|
||||
//
|
||||
@@ -325,6 +328,8 @@ private:
|
||||
BoxPoint const& top_left,
|
||||
PSStrategy const& ps_strategy)
|
||||
{
|
||||
boost::ignore_unused(ps_strategy);
|
||||
|
||||
// the segment lies above the box
|
||||
|
||||
typedef cast_to_result<ReturnType> cast;
|
||||
|
||||
@@ -280,7 +280,8 @@ struct extreme_points_on_ring
|
||||
template <typename Iterator>
|
||||
static inline bool right_turn(Ring const& ring, Iterator it)
|
||||
{
|
||||
int const index = std::distance(boost::begin(ring), it);
|
||||
typename std::iterator_traits<Iterator>::difference_type const index
|
||||
= std::distance(boost::begin(ring), it);
|
||||
geometry::ever_circling_range_iterator<Ring const> left(ring);
|
||||
geometry::ever_circling_range_iterator<Ring const> right(ring);
|
||||
left += index;
|
||||
@@ -328,7 +329,8 @@ struct extreme_points_on_ring
|
||||
return false;
|
||||
}
|
||||
|
||||
int const index = std::distance(boost::begin(ring), max_it);
|
||||
typename std::iterator_traits<range_iterator>::difference_type const
|
||||
index = std::distance(boost::begin(ring), max_it);
|
||||
//std::cout << "Extreme point lies at " << index << " having " << geometry::wkt(*max_it) << std::endl;
|
||||
|
||||
geometry::ever_circling_range_iterator<Ring const> left(ring);
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2014.
|
||||
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_BOX_BOX_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_BOX_BOX_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/algorithms/detail/intersection/interface.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/intersection_box_box.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1, typename Box2, bool Reverse
|
||||
>
|
||||
struct intersection
|
||||
<
|
||||
Box1, Box2,
|
||||
box_tag, box_tag,
|
||||
Reverse
|
||||
> : public detail::intersection::intersection_box_box
|
||||
<
|
||||
0, geometry::dimension<Box1>::value
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_BOX_BOX_HPP
|
||||
@@ -0,0 +1,22 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2014.
|
||||
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_IMPLEMENTATION_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_IMPLEMENTATION_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/algorithms/detail/intersection/box_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/intersection/multi.hpp>
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_IMPLEMENTATION_HPP
|
||||
@@ -0,0 +1,309 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2014.
|
||||
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_INTERFACE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_INTERFACE_HPP
|
||||
|
||||
|
||||
// TODO: those headers probably may be removed
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/algorithms/intersects.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/intersection_insert.hpp>
|
||||
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
// By default, all is forwarded to the intersection_insert-dispatcher
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Tag1 = typename geometry::tag<Geometry1>::type,
|
||||
typename Tag2 = typename geometry::tag<Geometry2>::type,
|
||||
bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
|
||||
>
|
||||
struct intersection
|
||||
{
|
||||
template <typename RobustPolicy, typename GeometryOut, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
RobustPolicy const& robust_policy,
|
||||
GeometryOut& geometry_out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename boost::range_value<GeometryOut>::type OneOut;
|
||||
|
||||
intersection_insert
|
||||
<
|
||||
Geometry1, Geometry2, OneOut,
|
||||
overlay_intersection
|
||||
>::apply(geometry1, geometry2, robust_policy, std::back_inserter(geometry_out), strategy);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// If reversal is needed, perform it
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Tag1, typename Tag2
|
||||
>
|
||||
struct intersection
|
||||
<
|
||||
Geometry1, Geometry2,
|
||||
Tag1, Tag2,
|
||||
true
|
||||
>
|
||||
: intersection<Geometry2, Geometry1, Tag2, Tag1, false>
|
||||
{
|
||||
template <typename RobustPolicy, typename GeometryOut, typename Strategy>
|
||||
static inline bool apply(
|
||||
Geometry1 const& g1,
|
||||
Geometry2 const& g2,
|
||||
RobustPolicy const& robust_policy,
|
||||
GeometryOut& out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return intersection<
|
||||
Geometry2, Geometry1,
|
||||
Tag2, Tag1,
|
||||
false
|
||||
>::apply(g2, g1, robust_policy, out, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
namespace resolve_variant
|
||||
{
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct intersection
|
||||
{
|
||||
template <typename GeometryOut>
|
||||
static inline bool
|
||||
apply(
|
||||
const Geometry1& geometry1,
|
||||
const Geometry2& geometry2,
|
||||
GeometryOut& geometry_out)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
typedef typename geometry::rescale_overlay_policy_type
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::type rescale_policy_type;
|
||||
|
||||
rescale_policy_type robust_policy
|
||||
= geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
|
||||
|
||||
typedef strategy_intersection
|
||||
<
|
||||
typename cs_tag<Geometry1>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
typename geometry::point_type<Geometry1>::type,
|
||||
rescale_policy_type
|
||||
> strategy;
|
||||
|
||||
return dispatch::intersection
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply(geometry1, geometry2, robust_policy, geometry_out, strategy());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
|
||||
struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
|
||||
{
|
||||
template <typename GeometryOut>
|
||||
struct visitor: static_visitor<bool>
|
||||
{
|
||||
Geometry2 const& m_geometry2;
|
||||
GeometryOut& m_geometry_out;
|
||||
|
||||
visitor(Geometry2 const& geometry2,
|
||||
GeometryOut& geometry_out)
|
||||
: m_geometry2(geometry2),
|
||||
m_geometry_out(geometry_out)
|
||||
{}
|
||||
|
||||
template <typename Geometry1>
|
||||
result_type operator()(Geometry1 const& geometry1) const
|
||||
{
|
||||
return intersection
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::template apply
|
||||
<
|
||||
GeometryOut
|
||||
>
|
||||
(geometry1, m_geometry2, m_geometry_out);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename GeometryOut>
|
||||
static inline bool
|
||||
apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
GeometryOut& geometry_out)
|
||||
{
|
||||
return apply_visitor(visitor<GeometryOut>(geometry2, geometry_out), geometry1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct intersection<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
{
|
||||
template <typename GeometryOut>
|
||||
struct visitor: static_visitor<bool>
|
||||
{
|
||||
Geometry1 const& m_geometry1;
|
||||
GeometryOut& m_geometry_out;
|
||||
|
||||
visitor(Geometry1 const& geometry1,
|
||||
GeometryOut& geometry_out)
|
||||
: m_geometry1(geometry1),
|
||||
m_geometry_out(geometry_out)
|
||||
{}
|
||||
|
||||
template <typename Geometry2>
|
||||
result_type operator()(Geometry2 const& geometry2) const
|
||||
{
|
||||
return intersection
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::template apply
|
||||
<
|
||||
GeometryOut
|
||||
>
|
||||
(m_geometry1, geometry2, m_geometry_out);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename GeometryOut>
|
||||
static inline bool
|
||||
apply(
|
||||
Geometry1 const& geometry1,
|
||||
const variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry2,
|
||||
GeometryOut& geometry_out)
|
||||
{
|
||||
return apply_visitor(visitor<GeometryOut>(geometry1, geometry_out), geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename A), BOOST_VARIANT_ENUM_PARAMS(typename B)>
|
||||
struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(A)>, variant<BOOST_VARIANT_ENUM_PARAMS(B)> >
|
||||
{
|
||||
template <typename GeometryOut>
|
||||
struct visitor: static_visitor<bool>
|
||||
{
|
||||
GeometryOut& m_geometry_out;
|
||||
|
||||
visitor(GeometryOut& geometry_out)
|
||||
: m_geometry_out(geometry_out)
|
||||
{}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
result_type operator()(
|
||||
Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2) const
|
||||
{
|
||||
return intersection
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::template apply
|
||||
<
|
||||
GeometryOut
|
||||
>
|
||||
(geometry1, geometry2, m_geometry_out);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename GeometryOut>
|
||||
static inline bool
|
||||
apply(
|
||||
const variant<BOOST_VARIANT_ENUM_PARAMS(A)>& geometry1,
|
||||
const variant<BOOST_VARIANT_ENUM_PARAMS(B)>& geometry2,
|
||||
GeometryOut& geometry_out)
|
||||
{
|
||||
return apply_visitor(visitor<GeometryOut>(geometry_out), geometry1, geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_variant
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc2{intersection}
|
||||
\ingroup intersection
|
||||
\details \details_calc2{intersection, spatial set theoretic intersection}.
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam GeometryOut Collection of geometries (e.g. std::vector, std::deque, boost::geometry::multi*) of which
|
||||
the value_type fulfills a \p_l_or_c concept, or it is the output geometry (e.g. for a box)
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param geometry_out The output geometry, either a multi_point, multi_polygon,
|
||||
multi_linestring, or a box (for intersection of two boxes)
|
||||
|
||||
\qbk{[include reference/algorithms/intersection.qbk]}
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename GeometryOut
|
||||
>
|
||||
inline bool intersection(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
GeometryOut& geometry_out)
|
||||
{
|
||||
return resolve_variant::intersection
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::template apply
|
||||
<
|
||||
GeometryOut
|
||||
>
|
||||
(geometry1, geometry2, geometry_out);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_INTERFACE_HPP
|
||||
423
include/boost/geometry/algorithms/detail/intersection/multi.hpp
Normal file
423
include/boost/geometry/algorithms/detail/intersection/multi.hpp
Normal file
@@ -0,0 +1,423 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2014.
|
||||
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_MULTI_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_MULTI_HPP
|
||||
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/geometry_id.hpp>
|
||||
#include <boost/geometry/core/is_areal.hpp>
|
||||
#include <boost/geometry/core/point_order.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
// TODO: those headers probably may be removed
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/select_rings.hpp>
|
||||
#include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>
|
||||
#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/intersection/interface.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/covered_by.hpp>
|
||||
#include <boost/geometry/algorithms/envelope.hpp>
|
||||
#include <boost/geometry/algorithms/num_points.hpp>
|
||||
|
||||
// TODO: remove this after moving num_point from multi directory
|
||||
#include <boost/geometry/multi/algorithms/num_points.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace intersection
|
||||
{
|
||||
|
||||
|
||||
template <typename PointOut>
|
||||
struct intersection_multi_linestring_multi_linestring_point
|
||||
{
|
||||
template
|
||||
<
|
||||
typename MultiLinestring1, typename MultiLinestring2,
|
||||
typename RobustPolicy,
|
||||
typename OutputIterator, typename Strategy
|
||||
>
|
||||
static inline OutputIterator apply(MultiLinestring1 const& ml1,
|
||||
MultiLinestring2 const& ml2,
|
||||
RobustPolicy const& robust_policy,
|
||||
OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
// Note, this loop is quadratic w.r.t. number of linestrings per input.
|
||||
// Future Enhancement: first do the sections of each, then intersect.
|
||||
for (typename boost::range_iterator
|
||||
<
|
||||
MultiLinestring1 const
|
||||
>::type it1 = boost::begin(ml1);
|
||||
it1 != boost::end(ml1);
|
||||
++it1)
|
||||
{
|
||||
for (typename boost::range_iterator
|
||||
<
|
||||
MultiLinestring2 const
|
||||
>::type it2 = boost::begin(ml2);
|
||||
it2 != boost::end(ml2);
|
||||
++it2)
|
||||
{
|
||||
out = intersection_linestring_linestring_point<PointOut>
|
||||
::apply(*it1, *it2, robust_policy, out, strategy);
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename PointOut>
|
||||
struct intersection_linestring_multi_linestring_point
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Linestring, typename MultiLinestring,
|
||||
typename RobustPolicy,
|
||||
typename OutputIterator, typename Strategy
|
||||
>
|
||||
static inline OutputIterator apply(Linestring const& linestring,
|
||||
MultiLinestring const& ml,
|
||||
RobustPolicy const& robust_policy,
|
||||
OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
for (typename boost::range_iterator
|
||||
<
|
||||
MultiLinestring const
|
||||
>::type it = boost::begin(ml);
|
||||
it != boost::end(ml);
|
||||
++it)
|
||||
{
|
||||
out = intersection_linestring_linestring_point<PointOut>
|
||||
::apply(linestring, *it, robust_policy, out, strategy);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// This loop is quite similar to the loop above, but beacuse the iterator
|
||||
// is second (above) or first (below) argument, it is not trivial to merge them.
|
||||
template
|
||||
<
|
||||
bool ReverseAreal,
|
||||
typename LineStringOut,
|
||||
overlay_type OverlayType
|
||||
>
|
||||
struct intersection_of_multi_linestring_with_areal
|
||||
{
|
||||
template
|
||||
<
|
||||
typename MultiLinestring, typename Areal,
|
||||
typename RobustPolicy,
|
||||
typename OutputIterator, typename Strategy
|
||||
>
|
||||
static inline OutputIterator apply(MultiLinestring const& ml, Areal const& areal,
|
||||
RobustPolicy const& robust_policy,
|
||||
OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
for (typename boost::range_iterator
|
||||
<
|
||||
MultiLinestring const
|
||||
>::type it = boost::begin(ml);
|
||||
it != boost::end(ml);
|
||||
++it)
|
||||
{
|
||||
out = intersection_of_linestring_with_areal
|
||||
<
|
||||
ReverseAreal, LineStringOut, OverlayType
|
||||
>::apply(*it, areal, robust_policy, out, strategy);
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
// This one calls the one above with reversed arguments
|
||||
template
|
||||
<
|
||||
bool ReverseAreal,
|
||||
typename LineStringOut,
|
||||
overlay_type OverlayType
|
||||
>
|
||||
struct intersection_of_areal_with_multi_linestring
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Areal, typename MultiLinestring,
|
||||
typename RobustPolicy,
|
||||
typename OutputIterator, typename Strategy
|
||||
>
|
||||
static inline OutputIterator apply(Areal const& areal, MultiLinestring const& ml,
|
||||
RobustPolicy const& robust_policy,
|
||||
OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return intersection_of_multi_linestring_with_areal
|
||||
<
|
||||
ReverseAreal, LineStringOut, OverlayType
|
||||
>::apply(ml, areal, robust_policy, out, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename LinestringOut>
|
||||
struct clip_multi_linestring
|
||||
{
|
||||
template
|
||||
<
|
||||
typename MultiLinestring, typename Box,
|
||||
typename RobustPolicy,
|
||||
typename OutputIterator, typename Strategy
|
||||
>
|
||||
static inline OutputIterator apply(MultiLinestring const& multi_linestring,
|
||||
Box const& box,
|
||||
RobustPolicy const& robust_policy,
|
||||
OutputIterator out, Strategy const& )
|
||||
{
|
||||
typedef typename point_type<LinestringOut>::type point_type;
|
||||
strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
|
||||
for (typename boost::range_iterator<MultiLinestring const>::type it
|
||||
= boost::begin(multi_linestring);
|
||||
it != boost::end(multi_linestring); ++it)
|
||||
{
|
||||
out = detail::intersection::clip_range_with_box
|
||||
<LinestringOut>(box, *it, robust_policy, out, lb_strategy);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::intersection
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
// Linear
|
||||
template
|
||||
<
|
||||
typename MultiLinestring1, typename MultiLinestring2,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
MultiLinestring1, MultiLinestring2,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
multi_linestring_tag, multi_linestring_tag, point_tag,
|
||||
false, false, false
|
||||
> : detail::intersection::intersection_multi_linestring_multi_linestring_point
|
||||
<
|
||||
GeometryOut
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Linestring, typename MultiLinestring,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
Linestring, MultiLinestring,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
linestring_tag, multi_linestring_tag, point_tag,
|
||||
false, false, false
|
||||
> : detail::intersection::intersection_linestring_multi_linestring_point
|
||||
<
|
||||
GeometryOut
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename MultiLinestring, typename Box,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
MultiLinestring, Box,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
multi_linestring_tag, box_tag, linestring_tag,
|
||||
false, true, false
|
||||
> : detail::intersection::clip_multi_linestring
|
||||
<
|
||||
GeometryOut
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Linestring, typename MultiPolygon,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
bool ReverseLinestring, bool ReverseMultiPolygon, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
Linestring, MultiPolygon,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
ReverseLinestring, ReverseMultiPolygon, ReverseOut,
|
||||
linestring_tag, multi_polygon_tag, linestring_tag,
|
||||
false, true, false
|
||||
> : detail::intersection::intersection_of_linestring_with_areal
|
||||
<
|
||||
ReverseMultiPolygon,
|
||||
GeometryOut,
|
||||
OverlayType
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
// Derives from areal/mls because runtime arguments are in that order.
|
||||
// areal/mls reverses it itself to mls/areal
|
||||
template
|
||||
<
|
||||
typename Polygon, typename MultiLinestring,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
bool ReversePolygon, bool ReverseMultiLinestring, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
Polygon, MultiLinestring,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
ReversePolygon, ReverseMultiLinestring, ReverseOut,
|
||||
polygon_tag, multi_linestring_tag, linestring_tag,
|
||||
true, false, false
|
||||
> : detail::intersection::intersection_of_areal_with_multi_linestring
|
||||
<
|
||||
ReversePolygon,
|
||||
GeometryOut,
|
||||
OverlayType
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename MultiLinestring, typename Ring,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
MultiLinestring, Ring,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
ReverseMultiLinestring, ReverseRing, ReverseOut,
|
||||
multi_linestring_tag, ring_tag, linestring_tag,
|
||||
false, true, false
|
||||
> : detail::intersection::intersection_of_multi_linestring_with_areal
|
||||
<
|
||||
ReverseRing,
|
||||
GeometryOut,
|
||||
OverlayType
|
||||
>
|
||||
{};
|
||||
|
||||
template
|
||||
<
|
||||
typename MultiLinestring, typename Polygon,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
MultiLinestring, Polygon,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
ReverseMultiLinestring, ReverseRing, ReverseOut,
|
||||
multi_linestring_tag, polygon_tag, linestring_tag,
|
||||
false, true, false
|
||||
> : detail::intersection::intersection_of_multi_linestring_with_areal
|
||||
<
|
||||
ReverseRing,
|
||||
GeometryOut,
|
||||
OverlayType
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename MultiLinestring, typename MultiPolygon,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
bool ReverseMultiLinestring, bool ReverseMultiPolygon, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
MultiLinestring, MultiPolygon,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
ReverseMultiLinestring, ReverseMultiPolygon, ReverseOut,
|
||||
multi_linestring_tag, multi_polygon_tag, linestring_tag,
|
||||
false, true, false
|
||||
> : detail::intersection::intersection_of_multi_linestring_with_areal
|
||||
<
|
||||
ReverseMultiPolygon,
|
||||
GeometryOut,
|
||||
OverlayType
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_MULTI_HPP
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/algorithms/convert.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
#include <boost/geometry/views/closeable_view.hpp>
|
||||
#include <boost/geometry/views/reversible_view.hpp>
|
||||
|
||||
@@ -95,8 +96,8 @@ struct copy_segment_point_polygon
|
||||
>::apply
|
||||
(
|
||||
seg_id.ring_index < 0
|
||||
? geometry::exterior_ring(polygon)
|
||||
: geometry::interior_rings(polygon)[seg_id.ring_index],
|
||||
? geometry::exterior_ring(polygon)
|
||||
: range::at(geometry::interior_rings(polygon), seg_id.ring_index),
|
||||
seg_id, second,
|
||||
point
|
||||
);
|
||||
@@ -146,7 +147,7 @@ struct copy_segment_point_multi
|
||||
);
|
||||
|
||||
// Call the single-version
|
||||
return Policy::apply(multi[seg_id.multi_index], seg_id, second, point);
|
||||
return Policy::apply(range::at(multi, seg_id.multi_index), seg_id, second, point);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
// Modifications copyright (c) 2014 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -39,6 +40,8 @@
|
||||
#include <boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp>
|
||||
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
@@ -155,18 +158,18 @@ public:
|
||||
// Sanity check
|
||||
if ( from_index > to_index
|
||||
|| from_index < 0
|
||||
|| to_index >= int(boost::size(ls)) )
|
||||
|| to_index >= static_cast<int>(boost::size(ls)) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
typedef typename boost::range_difference<LineString>::type size_type;
|
||||
size_type const count = to_index - from_index + 1;
|
||||
typedef typename boost::range_difference<LineString>::type diff_t;
|
||||
diff_t const count = to_index - from_index + 1;
|
||||
|
||||
typename boost::range_iterator<LineString const>::type
|
||||
it = boost::begin(ls) + from_index;
|
||||
|
||||
for (size_type i = 0; i < count; ++i, ++it)
|
||||
for (diff_t i = 0; i < count; ++i, ++it)
|
||||
{
|
||||
append_to_output(current_output, *it, robust_policy,
|
||||
boost::integral_constant<bool, RemoveSpikes>());
|
||||
@@ -193,8 +196,8 @@ struct copy_segments_polygon
|
||||
copy_segments_ring<Reverse>::apply
|
||||
(
|
||||
seg_id.ring_index < 0
|
||||
? geometry::exterior_ring(polygon)
|
||||
: geometry::interior_rings(polygon)[seg_id.ring_index],
|
||||
? geometry::exterior_ring(polygon)
|
||||
: range::at(geometry::interior_rings(polygon), seg_id.ring_index),
|
||||
seg_id, to_index,
|
||||
robust_policy,
|
||||
current_output
|
||||
@@ -265,10 +268,10 @@ struct copy_segments_multi
|
||||
);
|
||||
|
||||
// Call the single-version
|
||||
Policy::apply(multi_geometry[seg_id.multi_index],
|
||||
seg_id, to_index,
|
||||
robust_policy,
|
||||
current_output);
|
||||
Policy::apply(range::at(multi_geometry, seg_id.multi_index),
|
||||
seg_id, to_index,
|
||||
robust_policy,
|
||||
current_output);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -494,8 +494,10 @@ public :
|
||||
detail::copy_segments::copy_segments_linestring
|
||||
<
|
||||
false, RemoveSpikes
|
||||
>::apply(linestring, current_segment_id,
|
||||
boost::size(linestring) - 1, robust_policy,
|
||||
>::apply(linestring,
|
||||
current_segment_id,
|
||||
static_cast<int>(boost::size(linestring) - 1),
|
||||
robust_policy,
|
||||
current_piece);
|
||||
}
|
||||
|
||||
|
||||
@@ -263,8 +263,10 @@ protected:
|
||||
detail::copy_segments::copy_segments_linestring
|
||||
<
|
||||
false, false // do not reverse; do not remove spikes
|
||||
>::apply(linestring, current_segment_id,
|
||||
boost::size(linestring) - 1, robust_policy,
|
||||
>::apply(linestring,
|
||||
current_segment_id,
|
||||
static_cast<int>(boost::size(linestring) - 1),
|
||||
robust_policy,
|
||||
current_piece);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@@ -34,16 +35,16 @@ template<typename Tag>
|
||||
struct get_ring
|
||||
{};
|
||||
|
||||
// A container of rings (multi-ring but that does not exist)
|
||||
// A range of rings (multi-ring but that does not exist)
|
||||
// gets the "void" tag and is dispatched here.
|
||||
template<>
|
||||
struct get_ring<void>
|
||||
{
|
||||
template<typename Container>
|
||||
static inline typename boost::range_value<Container>::type const&
|
||||
apply(ring_identifier const& id, Container const& container)
|
||||
template<typename Range>
|
||||
static inline typename boost::range_value<Range>::type const&
|
||||
apply(ring_identifier const& id, Range const& container)
|
||||
{
|
||||
return container[id.multi_index];
|
||||
return range::at(container, id.multi_index);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -88,7 +89,7 @@ struct get_ring<polygon_tag>
|
||||
);
|
||||
return id.ring_index < 0
|
||||
? exterior_ring(polygon)
|
||||
: interior_rings(polygon)[id.ring_index];
|
||||
: range::at(interior_rings(polygon), id.ring_index);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -107,7 +108,7 @@ struct get_ring<multi_polygon_tag>
|
||||
&& id.multi_index < int(boost::size(multi_polygon))
|
||||
);
|
||||
return get_ring<polygon_tag>::apply(id,
|
||||
multi_polygon[id.multi_index]);
|
||||
range::at(multi_polygon, id.multi_index));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2013.
|
||||
// Modifications copyright (c) 2013, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013, 2014.
|
||||
// Modifications copyright (c) 2013, 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <boost/geometry/core/ring_type.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@@ -57,7 +58,7 @@ struct full_section_polygon
|
||||
{
|
||||
return section.ring_id.ring_index < 0
|
||||
? geometry::exterior_ring(polygon)
|
||||
: geometry::interior_rings(polygon)[section.ring_id.ring_index];
|
||||
: range::at(geometry::interior_rings(polygon), section.ring_id.ring_index);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -79,7 +80,7 @@ struct full_section_multi
|
||||
&& section.ring_id.multi_index < int(boost::size(multi))
|
||||
);
|
||||
|
||||
return Policy::apply(multi[section.ring_id.multi_index], section);
|
||||
return Policy::apply(range::at(multi, section.ring_id.multi_index), section);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2014.
|
||||
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -10,310 +15,8 @@
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_INTERSECTION_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/intersection_insert.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/intersection_box_box.hpp>
|
||||
#include <boost/geometry/algorithms/intersects.hpp>
|
||||
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
// By default, all is forwarded to the intersection_insert-dispatcher
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Tag1 = typename geometry::tag<Geometry1>::type,
|
||||
typename Tag2 = typename geometry::tag<Geometry2>::type,
|
||||
bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
|
||||
>
|
||||
struct intersection
|
||||
{
|
||||
template <typename RobustPolicy, typename GeometryOut, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
RobustPolicy const& robust_policy,
|
||||
GeometryOut& geometry_out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename boost::range_value<GeometryOut>::type OneOut;
|
||||
|
||||
intersection_insert
|
||||
<
|
||||
Geometry1, Geometry2, OneOut,
|
||||
overlay_intersection
|
||||
>::apply(geometry1, geometry2, robust_policy, std::back_inserter(geometry_out), strategy);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// If reversal is needed, perform it
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Tag1, typename Tag2
|
||||
>
|
||||
struct intersection
|
||||
<
|
||||
Geometry1, Geometry2,
|
||||
Tag1, Tag2,
|
||||
true
|
||||
>
|
||||
: intersection<Geometry2, Geometry1, Tag2, Tag1, false>
|
||||
{
|
||||
template <typename RobustPolicy, typename GeometryOut, typename Strategy>
|
||||
static inline bool apply(
|
||||
Geometry1 const& g1,
|
||||
Geometry2 const& g2,
|
||||
RobustPolicy const& robust_policy,
|
||||
GeometryOut& out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return intersection<
|
||||
Geometry2, Geometry1,
|
||||
Tag2, Tag1,
|
||||
false
|
||||
>::apply(g2, g1, robust_policy, out, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1, typename Box2, bool Reverse
|
||||
>
|
||||
struct intersection
|
||||
<
|
||||
Box1, Box2,
|
||||
box_tag, box_tag,
|
||||
Reverse
|
||||
> : public detail::intersection::intersection_box_box
|
||||
<
|
||||
0, geometry::dimension<Box1>::value
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
namespace resolve_variant
|
||||
{
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct intersection
|
||||
{
|
||||
template <typename GeometryOut>
|
||||
static inline bool
|
||||
apply(
|
||||
const Geometry1& geometry1,
|
||||
const Geometry2& geometry2,
|
||||
GeometryOut& geometry_out)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
typedef typename geometry::rescale_overlay_policy_type
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::type rescale_policy_type;
|
||||
|
||||
rescale_policy_type robust_policy
|
||||
= geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
|
||||
|
||||
typedef strategy_intersection
|
||||
<
|
||||
typename cs_tag<Geometry1>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
typename geometry::point_type<Geometry1>::type,
|
||||
rescale_policy_type
|
||||
> strategy;
|
||||
|
||||
return dispatch::intersection
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply(geometry1, geometry2, robust_policy, geometry_out, strategy());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
|
||||
struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
|
||||
{
|
||||
template <typename GeometryOut>
|
||||
struct visitor: static_visitor<bool>
|
||||
{
|
||||
Geometry2 const& m_geometry2;
|
||||
GeometryOut& m_geometry_out;
|
||||
|
||||
visitor(Geometry2 const& geometry2,
|
||||
GeometryOut& geometry_out)
|
||||
: m_geometry2(geometry2),
|
||||
m_geometry_out(geometry_out)
|
||||
{}
|
||||
|
||||
template <typename Geometry1>
|
||||
result_type operator()(Geometry1 const& geometry1) const
|
||||
{
|
||||
return intersection
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::template apply
|
||||
<
|
||||
GeometryOut
|
||||
>
|
||||
(geometry1, m_geometry2, m_geometry_out);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename GeometryOut>
|
||||
static inline bool
|
||||
apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
GeometryOut& geometry_out)
|
||||
{
|
||||
return apply_visitor(visitor<GeometryOut>(geometry2, geometry_out), geometry1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct intersection<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
{
|
||||
template <typename GeometryOut>
|
||||
struct visitor: static_visitor<bool>
|
||||
{
|
||||
Geometry1 const& m_geometry1;
|
||||
GeometryOut& m_geometry_out;
|
||||
|
||||
visitor(Geometry1 const& geometry1,
|
||||
GeometryOut& geometry_out)
|
||||
: m_geometry1(geometry1),
|
||||
m_geometry_out(geometry_out)
|
||||
{}
|
||||
|
||||
template <typename Geometry2>
|
||||
result_type operator()(Geometry2 const& geometry2) const
|
||||
{
|
||||
return intersection
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::template apply
|
||||
<
|
||||
GeometryOut
|
||||
>
|
||||
(m_geometry1, geometry2, m_geometry_out);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename GeometryOut>
|
||||
static inline bool
|
||||
apply(
|
||||
Geometry1 const& geometry1,
|
||||
const variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry2,
|
||||
GeometryOut& geometry_out)
|
||||
{
|
||||
return apply_visitor(visitor<GeometryOut>(geometry1, geometry_out), geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename A), BOOST_VARIANT_ENUM_PARAMS(typename B)>
|
||||
struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(A)>, variant<BOOST_VARIANT_ENUM_PARAMS(B)> >
|
||||
{
|
||||
template <typename GeometryOut>
|
||||
struct visitor: static_visitor<bool>
|
||||
{
|
||||
GeometryOut& m_geometry_out;
|
||||
|
||||
visitor(GeometryOut& geometry_out)
|
||||
: m_geometry_out(geometry_out)
|
||||
{}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
result_type operator()(
|
||||
Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2) const
|
||||
{
|
||||
return intersection
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::template apply
|
||||
<
|
||||
GeometryOut
|
||||
>
|
||||
(geometry1, geometry2, m_geometry_out);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename GeometryOut>
|
||||
static inline bool
|
||||
apply(
|
||||
const variant<BOOST_VARIANT_ENUM_PARAMS(A)>& geometry1,
|
||||
const variant<BOOST_VARIANT_ENUM_PARAMS(B)>& geometry2,
|
||||
GeometryOut& geometry_out)
|
||||
{
|
||||
return apply_visitor(visitor<GeometryOut>(geometry_out), geometry1, geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_variant
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc2{intersection}
|
||||
\ingroup intersection
|
||||
\details \details_calc2{intersection, spatial set theoretic intersection}.
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam GeometryOut Collection of geometries (e.g. std::vector, std::deque, boost::geometry::multi*) of which
|
||||
the value_type fulfills a \p_l_or_c concept, or it is the output geometry (e.g. for a box)
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param geometry_out The output geometry, either a multi_point, multi_polygon,
|
||||
multi_linestring, or a box (for intersection of two boxes)
|
||||
|
||||
\qbk{[include reference/algorithms/intersection.qbk]}
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename GeometryOut
|
||||
>
|
||||
inline bool intersection(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
GeometryOut& geometry_out)
|
||||
{
|
||||
return resolve_variant::intersection
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::template apply
|
||||
<
|
||||
GeometryOut
|
||||
>
|
||||
(geometry1, geometry2, geometry_out);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
#include <boost/geometry/algorithms/detail/intersection/interface.hpp>
|
||||
#include <boost/geometry/algorithms/detail/intersection/implementation.hpp>
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_INTERSECTION_HPP
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2014.
|
||||
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
@@ -54,6 +59,28 @@ struct num_interior_rings<Polygon, polygon_tag>
|
||||
};
|
||||
|
||||
|
||||
template <typename MultiPolygon>
|
||||
struct num_interior_rings<MultiPolygon, multi_polygon_tag>
|
||||
{
|
||||
static inline std::size_t apply(MultiPolygon const& multi_polygon)
|
||||
{
|
||||
std::size_t n = 0;
|
||||
for (typename boost::range_iterator<MultiPolygon const>::type
|
||||
it = boost::begin(multi_polygon);
|
||||
it != boost::end(multi_polygon);
|
||||
++it)
|
||||
{
|
||||
n += num_interior_rings
|
||||
<
|
||||
typename boost::range_value<MultiPolygon const>::type
|
||||
>::apply(*it);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif
|
||||
|
||||
|
||||
262
include/boost/geometry/algorithms/num_segments.hpp
Normal file
262
include/boost/geometry/algorithms/num_segments.hpp
Normal file
@@ -0,0 +1,262 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_NUM_SEGMENTS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_NUM_SEGMENTS_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/interior_type.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
|
||||
#include <boost/geometry/algorithms/disjoint.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
#include <boost/geometry/algorithms/num_points.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Tag = typename tag<Geometry>::type
|
||||
>
|
||||
struct num_segments
|
||||
: not_implemented<Tag>
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace num_segments
|
||||
{
|
||||
|
||||
|
||||
struct range_count
|
||||
{
|
||||
template <typename Range>
|
||||
static inline std::size_t apply(Range const& range, bool add_for_open)
|
||||
{
|
||||
std::size_t n = boost::size(range);
|
||||
if ( n <= 1 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (add_for_open
|
||||
&& geometry::closure<Range>::value == open
|
||||
&& geometry::disjoint(range::front(range), range::at(range, n - 1))
|
||||
)
|
||||
{
|
||||
return n;
|
||||
}
|
||||
return static_cast<std::size_t>(n - 1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct polygon_count
|
||||
: private range_count
|
||||
{
|
||||
template <typename Polygon>
|
||||
static inline std::size_t apply(Polygon const& poly, bool add_for_open)
|
||||
{
|
||||
std::size_t n = range_count::apply(exterior_ring(poly), add_for_open);
|
||||
|
||||
typename interior_return_type<Polygon const>::type
|
||||
rings = interior_rings(poly);
|
||||
for (typename detail::interior_iterator<Polygon const>::type
|
||||
it = boost::begin(rings); it != boost::end(rings); ++it)
|
||||
{
|
||||
n += range_count::apply(*it, add_for_open);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct multi_count
|
||||
{
|
||||
template <typename MultiGeometry>
|
||||
static inline
|
||||
std::size_t apply(MultiGeometry const& geometry, bool add_for_open)
|
||||
{
|
||||
typedef typename boost::range_value<MultiGeometry>::type geometry_type;
|
||||
typedef typename boost::range_iterator
|
||||
<
|
||||
MultiGeometry const
|
||||
>::type iterator_type;
|
||||
|
||||
std::size_t n = 0;
|
||||
for (iterator_type it = boost::begin(geometry);
|
||||
it != boost::end(geometry); ++it)
|
||||
{
|
||||
n += dispatch::num_segments
|
||||
<
|
||||
geometry_type
|
||||
>::apply(*it, add_for_open);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::num_segments
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_segments<Geometry, point_tag>
|
||||
: detail::num_points::other_count<0>
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_segments<Geometry, box_tag>
|
||||
: detail::num_points::other_count<4>
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_segments<Geometry, segment_tag>
|
||||
: detail::num_points::other_count<1>
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_segments<Geometry, linestring_tag>
|
||||
: detail::num_segments::range_count
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_segments<Geometry, ring_tag>
|
||||
: detail::num_segments::range_count
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_segments<Geometry, polygon_tag>
|
||||
: detail::num_segments::polygon_count
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_segments<Geometry, multi_point_tag>
|
||||
: detail::num_points::other_count<0>
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_segments<Geometry, multi_linestring_tag>
|
||||
: detail::num_segments::multi_count
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_segments<Geometry, multi_polygon_tag>
|
||||
: detail::num_segments::multi_count
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
|
||||
namespace resolve_variant
|
||||
{
|
||||
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_segments
|
||||
: dispatch::num_segments<Geometry>
|
||||
{};
|
||||
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct num_segments<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
{
|
||||
struct visitor: boost::static_visitor<std::size_t>
|
||||
{
|
||||
bool m_add_for_open;
|
||||
|
||||
visitor(bool add_for_open): m_add_for_open(add_for_open) {}
|
||||
|
||||
template <typename Geometry>
|
||||
typename std::size_t operator()(Geometry const& geometry) const
|
||||
{
|
||||
return num_segments<Geometry>::apply(geometry, m_add_for_open);
|
||||
}
|
||||
};
|
||||
|
||||
static inline std::size_t
|
||||
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
|
||||
bool add_for_open)
|
||||
{
|
||||
return boost::apply_visitor(visitor(add_for_open), geometry);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace resolve_variant
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc{number of segments}
|
||||
\ingroup num_segments
|
||||
\details \details_calc{num_segments, number of segments}.
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry
|
||||
\param add_for_open add one for open geometries (i.e. polygon types which are not closed)
|
||||
\return \return_calc{number of segments}
|
||||
|
||||
\qbk{[include reference/algorithms/num_segments.qbk]}
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline std::size_t num_segments(Geometry const& geometry,
|
||||
bool add_for_open = false)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
return resolve_variant::num_segments
|
||||
<
|
||||
Geometry
|
||||
>::apply(geometry, add_for_open);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_NUM_SEGMENTS_HPP
|
||||
@@ -70,6 +70,7 @@
|
||||
#include <boost/geometry/algorithms/num_geometries.hpp>
|
||||
#include <boost/geometry/algorithms/num_interior_rings.hpp>
|
||||
#include <boost/geometry/algorithms/num_points.hpp>
|
||||
#include <boost/geometry/algorithms/num_segments.hpp>
|
||||
#include <boost/geometry/algorithms/overlaps.hpp>
|
||||
#include <boost/geometry/algorithms/perimeter.hpp>
|
||||
#include <boost/geometry/algorithms/remove_spikes.hpp>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// R-tree R*-tree next node choosing algorithm implementation
|
||||
//
|
||||
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
|
||||
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
|
||||
//
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -54,12 +54,6 @@ public:
|
||||
// children are leafs
|
||||
if ( node_relative_level <= 1 )
|
||||
{
|
||||
/*if ( 0 < parameters.get_overlap_cost_threshold() &&
|
||||
parameters.get_overlap_cost_threshold() < children.size() )
|
||||
return choose_by_nearly_minimum_overlap_cost(children, indexable, parameters.get_overlap_cost_threshold());
|
||||
else
|
||||
return choose_by_minimum_overlap_cost(children, indexable);*/
|
||||
|
||||
return choose_by_minimum_overlap_cost(children, indexable, parameters.get_overlap_cost_threshold());
|
||||
}
|
||||
// children are internal nodes
|
||||
@@ -112,31 +106,36 @@ private:
|
||||
|
||||
if ( min_content_diff < -std::numeric_limits<double>::epsilon() || std::numeric_limits<double>::epsilon() < min_content_diff )
|
||||
{
|
||||
size_t first_n_children_count = children_count;
|
||||
if ( 0 < overlap_cost_threshold && overlap_cost_threshold < children.size() )
|
||||
{
|
||||
// calculate nearly minimum overlap cost
|
||||
|
||||
// sort by content_diff
|
||||
std::partial_sort(children_contents.begin(), children_contents.begin() + overlap_cost_threshold, children_contents.end(), content_diff_less);
|
||||
choosen_index = choose_by_minimum_overlap_cost_sorted_by_content(children, indexable, children_count, overlap_cost_threshold, children_contents);
|
||||
first_n_children_count = overlap_cost_threshold;
|
||||
// rearrange by content_diff
|
||||
// in order to calculate nearly minimum overlap cost
|
||||
std::nth_element(children_contents.begin(), children_contents.begin() + first_n_children_count, children_contents.end(), content_diff_less);
|
||||
}
|
||||
else
|
||||
{
|
||||
// calculate minimum overlap cost
|
||||
|
||||
choosen_index = choose_by_minimum_overlap_cost_unsorted_by_content(children, indexable, children_count, children_contents);
|
||||
}
|
||||
// calculate minimum or nearly minimum overlap cost
|
||||
choosen_index = choose_by_minimum_overlap_cost_first_n(children, indexable, first_n_children_count, children_count, children_contents);
|
||||
}
|
||||
|
||||
return choosen_index;
|
||||
}
|
||||
|
||||
template <typename Indexable, typename ChildrenContents>
|
||||
static inline size_t choose_by_minimum_overlap_cost_unsorted_by_content(children_type const& children,
|
||||
Indexable const& indexable,
|
||||
size_t children_count,
|
||||
ChildrenContents const& children_contents)
|
||||
static inline bool content_diff_less(boost::tuple<size_t, content_type, content_type> const& p1, boost::tuple<size_t, content_type, content_type> const& p2)
|
||||
{
|
||||
return boost::get<1>(p1) < boost::get<1>(p2) ||
|
||||
(boost::get<1>(p1) == boost::get<1>(p2) && boost::get<2>(p1) < boost::get<2>(p2));
|
||||
}
|
||||
|
||||
template <typename Indexable, typename ChildrenContents>
|
||||
static inline size_t choose_by_minimum_overlap_cost_first_n(children_type const& children,
|
||||
Indexable const& indexable,
|
||||
size_t const first_n_children_count,
|
||||
size_t const children_count,
|
||||
ChildrenContents const& children_contents)
|
||||
{
|
||||
BOOST_GEOMETRY_INDEX_ASSERT(first_n_children_count <= children_count, "unexpected value");
|
||||
BOOST_GEOMETRY_INDEX_ASSERT(children_contents.size() == children_count, "unexpected number of elements");
|
||||
|
||||
// choose index with smallest overlap change value, or content change or smallest content
|
||||
@@ -146,7 +145,7 @@ private:
|
||||
content_type smallest_content = (std::numeric_limits<content_type>::max)();
|
||||
|
||||
// for each child node
|
||||
for (size_t i = 0 ; i < children_count ; ++i )
|
||||
for (size_t i = 0 ; i < first_n_children_count ; ++i )
|
||||
{
|
||||
child_type const& ch_i = children[i];
|
||||
|
||||
@@ -189,198 +188,6 @@ private:
|
||||
|
||||
return choosen_index;
|
||||
}
|
||||
|
||||
template <typename Indexable, typename ChildrenContents>
|
||||
static inline size_t choose_by_minimum_overlap_cost_sorted_by_content(children_type const& children,
|
||||
Indexable const& indexable,
|
||||
size_t children_count,
|
||||
size_t overlap_cost_threshold,
|
||||
ChildrenContents const& children_contents)
|
||||
{
|
||||
BOOST_GEOMETRY_INDEX_ASSERT(overlap_cost_threshold < children_count, "unexpected value");
|
||||
BOOST_GEOMETRY_INDEX_ASSERT(children_count == children_contents.size(), "unexpected number of elements");
|
||||
|
||||
// for overlap_cost_threshold child nodes find the one with smallest overlap value
|
||||
size_t choosen_index = 0;
|
||||
content_type smallest_overlap_diff = (std::numeric_limits<content_type>::max)();
|
||||
|
||||
// for each node
|
||||
for (size_t i = 0 ; i < overlap_cost_threshold ; ++i )
|
||||
{
|
||||
size_t child_index = boost::get<0>(children_contents[i]);
|
||||
|
||||
typedef typename children_type::value_type child_type;
|
||||
child_type const& ch_i = children[child_index];
|
||||
|
||||
Box box_exp(ch_i.first);
|
||||
// calculate expanded box of child node ch_i
|
||||
geometry::expand(box_exp, indexable);
|
||||
|
||||
content_type overlap_diff = 0;
|
||||
|
||||
// calculate overlap
|
||||
for ( size_t j = 0 ; j < children_count ; ++j )
|
||||
{
|
||||
if ( child_index != j )
|
||||
{
|
||||
child_type const& ch_j = children[j];
|
||||
|
||||
content_type overlap_exp = index::detail::intersection_content(box_exp, ch_j.first);
|
||||
if ( overlap_exp < -std::numeric_limits<content_type>::epsilon() || std::numeric_limits<content_type>::epsilon() < overlap_exp )
|
||||
{
|
||||
overlap_diff += overlap_exp - index::detail::intersection_content(ch_i.first, ch_j.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update result
|
||||
if ( overlap_diff < smallest_overlap_diff )
|
||||
{
|
||||
smallest_overlap_diff = overlap_diff;
|
||||
choosen_index = child_index;
|
||||
}
|
||||
}
|
||||
|
||||
return choosen_index;
|
||||
}
|
||||
|
||||
//template <typename Indexable>
|
||||
//static inline size_t choose_by_minimum_overlap_cost(children_type const& children,
|
||||
// Indexable const& indexable)
|
||||
//{
|
||||
// size_t children_count = children.size();
|
||||
|
||||
// // choose index with smallest overlap change value, or content change or smallest content
|
||||
// size_t choosen_index = 0;
|
||||
// content_type smallest_overlap_diff = (std::numeric_limits<content_type>::max)();
|
||||
// content_type smallest_content_diff = (std::numeric_limits<content_type>::max)();
|
||||
// content_type smallest_content = (std::numeric_limits<content_type>::max)();
|
||||
|
||||
// // for each child node
|
||||
// for (size_t i = 0 ; i < children_count ; ++i )
|
||||
// {
|
||||
// child_type const& ch_i = children[i];
|
||||
|
||||
// Box box_exp(ch_i.first);
|
||||
// // calculate expanded box of child node ch_i
|
||||
// geometry::expand(box_exp, indexable);
|
||||
|
||||
// // calculate content and content diff
|
||||
// content_type content = index::detail::content(box_exp);
|
||||
// content_type content_diff = content - index::detail::content(ch_i.first);
|
||||
|
||||
// content_type overlap_diff = 0;
|
||||
//
|
||||
// // calculate overlap
|
||||
// for ( size_t j = 0 ; j < children_count ; ++j )
|
||||
// {
|
||||
// if ( i != j )
|
||||
// {
|
||||
// child_type const& ch_j = children[j];
|
||||
|
||||
// content_type overlap_exp = index::detail::intersection_content(box_exp, ch_j.first);
|
||||
// if ( overlap_exp < -std::numeric_limits<content_type>::epsilon() || std::numeric_limits<content_type>::epsilon() < overlap_exp )
|
||||
// {
|
||||
// overlap_diff += overlap_exp - index::detail::intersection_content(ch_i.first, ch_j.first);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// // update result
|
||||
// if ( overlap_diff < smallest_overlap_diff ||
|
||||
// ( overlap_diff == smallest_overlap_diff && ( content_diff < smallest_content_diff ||
|
||||
// ( content_diff == smallest_content_diff && content < smallest_content ) )
|
||||
// ) )
|
||||
// {
|
||||
// smallest_overlap_diff = overlap_diff;
|
||||
// smallest_content_diff = content_diff;
|
||||
// smallest_content = content;
|
||||
// choosen_index = i;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return choosen_index;
|
||||
//}
|
||||
|
||||
//template <typename Indexable>
|
||||
//static inline size_t choose_by_nearly_minimum_overlap_cost(children_type const& children,
|
||||
// Indexable const& indexable,
|
||||
// size_t overlap_cost_threshold)
|
||||
//{
|
||||
// const size_t children_count = children.size();
|
||||
|
||||
// // create container of children sorted by content enlargement needed to include the new value
|
||||
// std::vector< boost::tuple<size_t, content_type, content_type> > sorted_children(children_count);
|
||||
// for ( size_t i = 0 ; i < children_count ; ++i )
|
||||
// {
|
||||
// child_type const& ch_i = children[i];
|
||||
|
||||
// // expanded child node's box
|
||||
// Box box_exp(ch_i.first);
|
||||
// geometry::expand(box_exp, indexable);
|
||||
|
||||
// // areas difference
|
||||
// content_type content = index::detail::content(box_exp);
|
||||
// content_type content_diff = content - index::detail::content(ch_i.first);
|
||||
|
||||
// sorted_children[i] = boost::make_tuple(i, content_diff, content);
|
||||
// }
|
||||
|
||||
// BOOST_GEOMETRY_INDEX_ASSERT(overlap_cost_threshold <= children_count, "there is not enough children");
|
||||
|
||||
// // sort by content_diff
|
||||
// //std::sort(sorted_children.begin(), sorted_children.end(), content_diff_less);
|
||||
// std::partial_sort(sorted_children.begin(), sorted_children.begin() + overlap_cost_threshold, sorted_children.end(), content_diff_less);
|
||||
|
||||
// // for overlap_cost_threshold child nodes find the one with smallest overlap value
|
||||
// size_t choosen_index = 0;
|
||||
// content_type smallest_overlap_diff = (std::numeric_limits<content_type>::max)();
|
||||
|
||||
// // for each node
|
||||
// for (size_t i = 0 ; i < overlap_cost_threshold ; ++i )
|
||||
// {
|
||||
// size_t child_index = boost::get<0>(sorted_children[i]);
|
||||
|
||||
// typedef typename children_type::value_type child_type;
|
||||
// child_type const& ch_i = children[child_index];
|
||||
|
||||
// Box box_exp(ch_i.first);
|
||||
// // calculate expanded box of child node ch_i
|
||||
// geometry::expand(box_exp, indexable);
|
||||
|
||||
// content_type overlap_diff = 0;
|
||||
|
||||
// // calculate overlap
|
||||
// for ( size_t j = 0 ; j < children_count ; ++j )
|
||||
// {
|
||||
// if ( child_index != j )
|
||||
// {
|
||||
// child_type const& ch_j = children[j];
|
||||
|
||||
// content_type overlap_exp = index::detail::intersection_content(box_exp, ch_j.first);
|
||||
// if ( overlap_exp < -std::numeric_limits<content_type>::epsilon() || std::numeric_limits<content_type>::epsilon() < overlap_exp )
|
||||
// {
|
||||
// overlap_diff += overlap_exp - index::detail::intersection_content(ch_i.first, ch_j.first);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// // update result
|
||||
// if ( overlap_diff < smallest_overlap_diff )
|
||||
// {
|
||||
// smallest_overlap_diff = overlap_diff;
|
||||
// choosen_index = child_index;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return choosen_index;
|
||||
//}
|
||||
|
||||
static inline bool content_diff_less(boost::tuple<size_t, content_type, content_type> const& p1, boost::tuple<size_t, content_type, content_type> const& p2)
|
||||
{
|
||||
return boost::get<1>(p1) < boost::get<1>(p2) ||
|
||||
(boost::get<1>(p1) == boost::get<1>(p2) && boost::get<2>(p1) < boost::get<2>(p2));
|
||||
}
|
||||
|
||||
template <typename Indexable>
|
||||
static inline size_t choose_by_minimum_content_cost(children_type const& children, Indexable const& indexable)
|
||||
|
||||
@@ -113,19 +113,28 @@ struct choose_split_axis_and_index_for_corner
|
||||
// copy elements
|
||||
Elements elements_copy(elements); // MAY THROW, STRONG (alloc, copy)
|
||||
|
||||
size_t const index_first = parameters.get_min_elements();
|
||||
size_t const index_last = parameters.get_max_elements() - parameters.get_min_elements() + 2;
|
||||
|
||||
// sort elements
|
||||
element_axis_corner_less<element_type, Translator, indexable_tag, Corner, AxisIndex> elements_less(translator);
|
||||
std::sort(elements_copy.begin(), elements_copy.end(), elements_less); // MAY THROW, BASIC (copy)
|
||||
// {
|
||||
// typename Elements::iterator f = elements_copy.begin() + index_first;
|
||||
// typename Elements::iterator l = elements_copy.begin() + index_last;
|
||||
// std::nth_element(elements_copy.begin(), f, elements_copy.end(), elements_less); // MAY THROW, BASIC (copy)
|
||||
// std::nth_element(f, l, elements_copy.end(), elements_less); // MAY THROW, BASIC (copy)
|
||||
// std::sort(f, l, elements_less); // MAY THROW, BASIC (copy)
|
||||
// }
|
||||
|
||||
// init outputs
|
||||
choosen_index = parameters.get_min_elements();
|
||||
choosen_index = index_first;
|
||||
sum_of_margins = 0;
|
||||
smallest_overlap = (std::numeric_limits<content_type>::max)();
|
||||
smallest_content = (std::numeric_limits<content_type>::max)();
|
||||
|
||||
// calculate sum of margins for all distributions
|
||||
size_t index_last = parameters.get_max_elements() - parameters.get_min_elements() + 2;
|
||||
for ( size_t i = parameters.get_min_elements() ; i < index_last ; ++i )
|
||||
for ( size_t i = index_first ; i < index_last ; ++i )
|
||||
{
|
||||
// TODO - awulkiew: may be optimized - box of group 1 may be initialized with
|
||||
// box of min_elems number of elements and expanded for each iteration by another element
|
||||
@@ -320,50 +329,39 @@ struct choose_split_axis_and_index<Parameters, Box, 1>
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t Corner, size_t Dimension>
|
||||
struct partial_sort
|
||||
template <size_t Corner, size_t Dimension, size_t I = 0>
|
||||
struct nth_element
|
||||
{
|
||||
BOOST_STATIC_ASSERT(0 < Dimension);
|
||||
BOOST_STATIC_ASSERT(I < Dimension);
|
||||
|
||||
template <typename Elements, typename Translator>
|
||||
static inline void apply(Elements & elements, const size_t axis, const size_t index, Translator const& tr)
|
||||
{
|
||||
if ( axis < Dimension - 1 )
|
||||
//BOOST_GEOMETRY_INDEX_ASSERT(axis < Dimension, "unexpected axis value");
|
||||
|
||||
if ( axis != I )
|
||||
{
|
||||
partial_sort<Corner, Dimension - 1>::apply(elements, axis, index, tr); // MAY THROW, BASIC (copy)
|
||||
nth_element<Corner, Dimension, I + 1>::apply(elements, axis, index, tr); // MAY THROW, BASIC (copy)
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_GEOMETRY_INDEX_ASSERT(axis == Dimension - 1, "unexpected axis value");
|
||||
|
||||
typedef typename Elements::value_type element_type;
|
||||
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
|
||||
typedef typename tag<indexable_type>::type indexable_tag;
|
||||
|
||||
element_axis_corner_less<element_type, Translator, indexable_tag, Corner, Dimension - 1> less(tr);
|
||||
std::partial_sort(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy)
|
||||
element_axis_corner_less<element_type, Translator, indexable_tag, Corner, I> less(tr);
|
||||
std::nth_element(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t Corner>
|
||||
struct partial_sort<Corner, 1>
|
||||
template <size_t Corner, size_t Dimension>
|
||||
struct nth_element<Corner, Dimension, Dimension>
|
||||
{
|
||||
template <typename Elements, typename Translator>
|
||||
static inline void apply(Elements & elements,
|
||||
const size_t BOOST_GEOMETRY_INDEX_ASSERT_UNUSED_PARAM(axis),
|
||||
const size_t index,
|
||||
Translator const& tr)
|
||||
{
|
||||
BOOST_GEOMETRY_INDEX_ASSERT(axis == 0, "unexpected axis value");
|
||||
|
||||
typedef typename Elements::value_type element_type;
|
||||
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
|
||||
typedef typename tag<indexable_type>::type indexable_tag;
|
||||
|
||||
element_axis_corner_less<element_type, Translator, indexable_tag, Corner, 0> less(tr);
|
||||
std::partial_sort(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy)
|
||||
}
|
||||
static inline void apply(Elements & /*elements*/, const size_t /*axis*/, const size_t /*index*/, Translator const& /*tr*/)
|
||||
{}
|
||||
};
|
||||
|
||||
} // namespace rstar
|
||||
@@ -431,12 +429,12 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_
|
||||
// TODO: consider using nth_element
|
||||
if ( split_corner == static_cast<size_t>(min_corner) )
|
||||
{
|
||||
rstar::partial_sort<min_corner, dimension>
|
||||
rstar::nth_element<min_corner, dimension>
|
||||
::apply(elements_copy, split_axis, split_index, translator); // MAY THROW, BASIC (copy)
|
||||
}
|
||||
else
|
||||
{
|
||||
rstar::partial_sort<max_corner, dimension>
|
||||
rstar::nth_element<max_corner, dimension>
|
||||
::apply(elements_copy, split_axis, split_index, translator); // MAY THROW, BASIC (copy)
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
@@ -19,88 +20,8 @@
|
||||
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_APPEND_HPP
|
||||
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_APPEND_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/algorithms/append.hpp>
|
||||
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace append
|
||||
{
|
||||
|
||||
|
||||
template <typename MultiGeometry, typename RangeOrPoint>
|
||||
struct append_to_multigeometry
|
||||
{
|
||||
static inline void apply(MultiGeometry& multigeometry,
|
||||
RangeOrPoint const& range_or_point,
|
||||
int ring_index, int multi_index)
|
||||
{
|
||||
|
||||
dispatch::append
|
||||
<
|
||||
typename boost::range_value<MultiGeometry>::type,
|
||||
RangeOrPoint
|
||||
>::apply(multigeometry[multi_index], range_or_point, ring_index);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::append
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
namespace splitted_dispatch
|
||||
{
|
||||
|
||||
template <typename Geometry, typename Point>
|
||||
struct append_point<multi_point_tag, Geometry, Point>
|
||||
: detail::append::append_point<Geometry, Point>
|
||||
{};
|
||||
|
||||
template <typename Geometry, typename Range>
|
||||
struct append_range<multi_point_tag, Geometry, Range>
|
||||
: detail::append::append_range<Geometry, Range>
|
||||
{};
|
||||
|
||||
template <typename MultiGeometry, typename RangeOrPoint>
|
||||
struct append_point<multi_linestring_tag, MultiGeometry, RangeOrPoint>
|
||||
: detail::append::append_to_multigeometry<MultiGeometry, RangeOrPoint>
|
||||
{};
|
||||
|
||||
template <typename MultiGeometry, typename RangeOrPoint>
|
||||
struct append_range<multi_linestring_tag, MultiGeometry, RangeOrPoint>
|
||||
: detail::append::append_to_multigeometry<MultiGeometry, RangeOrPoint>
|
||||
{};
|
||||
|
||||
template <typename MultiGeometry, typename RangeOrPoint>
|
||||
struct append_point<multi_polygon_tag, MultiGeometry, RangeOrPoint>
|
||||
: detail::append::append_to_multigeometry<MultiGeometry, RangeOrPoint>
|
||||
{};
|
||||
|
||||
template <typename MultiGeometry, typename RangeOrPoint>
|
||||
struct append_range<multi_polygon_tag, MultiGeometry, RangeOrPoint>
|
||||
: detail::append::append_to_multigeometry<MultiGeometry, RangeOrPoint>
|
||||
{};
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_APPEND_HPP
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2014.
|
||||
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,407 +14,9 @@
|
||||
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_INTERSECTION_HPP
|
||||
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_INTERSECTION_HPP
|
||||
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/geometry_id.hpp>
|
||||
#include <boost/geometry/core/is_areal.hpp>
|
||||
#include <boost/geometry/core/point_order.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
// TODO: those headers probably may be removed
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/select_rings.hpp>
|
||||
#include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>
|
||||
#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/intersection.hpp>
|
||||
|
||||
#include <boost/geometry/multi/algorithms/covered_by.hpp>
|
||||
#include <boost/geometry/multi/algorithms/envelope.hpp>
|
||||
#include <boost/geometry/multi/algorithms/num_points.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace intersection
|
||||
{
|
||||
|
||||
|
||||
template <typename PointOut>
|
||||
struct intersection_multi_linestring_multi_linestring_point
|
||||
{
|
||||
template
|
||||
<
|
||||
typename MultiLinestring1, typename MultiLinestring2,
|
||||
typename RobustPolicy,
|
||||
typename OutputIterator, typename Strategy
|
||||
>
|
||||
static inline OutputIterator apply(MultiLinestring1 const& ml1,
|
||||
MultiLinestring2 const& ml2,
|
||||
RobustPolicy const& robust_policy,
|
||||
OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
// Note, this loop is quadratic w.r.t. number of linestrings per input.
|
||||
// Future Enhancement: first do the sections of each, then intersect.
|
||||
for (typename boost::range_iterator
|
||||
<
|
||||
MultiLinestring1 const
|
||||
>::type it1 = boost::begin(ml1);
|
||||
it1 != boost::end(ml1);
|
||||
++it1)
|
||||
{
|
||||
for (typename boost::range_iterator
|
||||
<
|
||||
MultiLinestring2 const
|
||||
>::type it2 = boost::begin(ml2);
|
||||
it2 != boost::end(ml2);
|
||||
++it2)
|
||||
{
|
||||
out = intersection_linestring_linestring_point<PointOut>
|
||||
::apply(*it1, *it2, robust_policy, out, strategy);
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename PointOut>
|
||||
struct intersection_linestring_multi_linestring_point
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Linestring, typename MultiLinestring,
|
||||
typename RobustPolicy,
|
||||
typename OutputIterator, typename Strategy
|
||||
>
|
||||
static inline OutputIterator apply(Linestring const& linestring,
|
||||
MultiLinestring const& ml,
|
||||
RobustPolicy const& robust_policy,
|
||||
OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
for (typename boost::range_iterator
|
||||
<
|
||||
MultiLinestring const
|
||||
>::type it = boost::begin(ml);
|
||||
it != boost::end(ml);
|
||||
++it)
|
||||
{
|
||||
out = intersection_linestring_linestring_point<PointOut>
|
||||
::apply(linestring, *it, robust_policy, out, strategy);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// This loop is quite similar to the loop above, but beacuse the iterator
|
||||
// is second (above) or first (below) argument, it is not trivial to merge them.
|
||||
template
|
||||
<
|
||||
bool ReverseAreal,
|
||||
typename LineStringOut,
|
||||
overlay_type OverlayType
|
||||
>
|
||||
struct intersection_of_multi_linestring_with_areal
|
||||
{
|
||||
template
|
||||
<
|
||||
typename MultiLinestring, typename Areal,
|
||||
typename RobustPolicy,
|
||||
typename OutputIterator, typename Strategy
|
||||
>
|
||||
static inline OutputIterator apply(MultiLinestring const& ml, Areal const& areal,
|
||||
RobustPolicy const& robust_policy,
|
||||
OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
for (typename boost::range_iterator
|
||||
<
|
||||
MultiLinestring const
|
||||
>::type it = boost::begin(ml);
|
||||
it != boost::end(ml);
|
||||
++it)
|
||||
{
|
||||
out = intersection_of_linestring_with_areal
|
||||
<
|
||||
ReverseAreal, LineStringOut, OverlayType
|
||||
>::apply(*it, areal, robust_policy, out, strategy);
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
// This one calls the one above with reversed arguments
|
||||
template
|
||||
<
|
||||
bool ReverseAreal,
|
||||
typename LineStringOut,
|
||||
overlay_type OverlayType
|
||||
>
|
||||
struct intersection_of_areal_with_multi_linestring
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Areal, typename MultiLinestring,
|
||||
typename RobustPolicy,
|
||||
typename OutputIterator, typename Strategy
|
||||
>
|
||||
static inline OutputIterator apply(Areal const& areal, MultiLinestring const& ml,
|
||||
RobustPolicy const& robust_policy,
|
||||
OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return intersection_of_multi_linestring_with_areal
|
||||
<
|
||||
ReverseAreal, LineStringOut, OverlayType
|
||||
>::apply(ml, areal, robust_policy, out, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename LinestringOut>
|
||||
struct clip_multi_linestring
|
||||
{
|
||||
template
|
||||
<
|
||||
typename MultiLinestring, typename Box,
|
||||
typename RobustPolicy,
|
||||
typename OutputIterator, typename Strategy
|
||||
>
|
||||
static inline OutputIterator apply(MultiLinestring const& multi_linestring,
|
||||
Box const& box,
|
||||
RobustPolicy const& robust_policy,
|
||||
OutputIterator out, Strategy const& )
|
||||
{
|
||||
typedef typename point_type<LinestringOut>::type point_type;
|
||||
strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
|
||||
for (typename boost::range_iterator<MultiLinestring const>::type it
|
||||
= boost::begin(multi_linestring);
|
||||
it != boost::end(multi_linestring); ++it)
|
||||
{
|
||||
out = detail::intersection::clip_range_with_box
|
||||
<LinestringOut>(box, *it, robust_policy, out, lb_strategy);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::intersection
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
// Linear
|
||||
template
|
||||
<
|
||||
typename MultiLinestring1, typename MultiLinestring2,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
MultiLinestring1, MultiLinestring2,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
multi_linestring_tag, multi_linestring_tag, point_tag,
|
||||
false, false, false
|
||||
> : detail::intersection::intersection_multi_linestring_multi_linestring_point
|
||||
<
|
||||
GeometryOut
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Linestring, typename MultiLinestring,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
Linestring, MultiLinestring,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
linestring_tag, multi_linestring_tag, point_tag,
|
||||
false, false, false
|
||||
> : detail::intersection::intersection_linestring_multi_linestring_point
|
||||
<
|
||||
GeometryOut
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename MultiLinestring, typename Box,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
MultiLinestring, Box,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
multi_linestring_tag, box_tag, linestring_tag,
|
||||
false, true, false
|
||||
> : detail::intersection::clip_multi_linestring
|
||||
<
|
||||
GeometryOut
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Linestring, typename MultiPolygon,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
bool ReverseLinestring, bool ReverseMultiPolygon, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
Linestring, MultiPolygon,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
ReverseLinestring, ReverseMultiPolygon, ReverseOut,
|
||||
linestring_tag, multi_polygon_tag, linestring_tag,
|
||||
false, true, false
|
||||
> : detail::intersection::intersection_of_linestring_with_areal
|
||||
<
|
||||
ReverseMultiPolygon,
|
||||
GeometryOut,
|
||||
OverlayType
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
// Derives from areal/mls because runtime arguments are in that order.
|
||||
// areal/mls reverses it itself to mls/areal
|
||||
template
|
||||
<
|
||||
typename Polygon, typename MultiLinestring,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
bool ReversePolygon, bool ReverseMultiLinestring, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
Polygon, MultiLinestring,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
ReversePolygon, ReverseMultiLinestring, ReverseOut,
|
||||
polygon_tag, multi_linestring_tag, linestring_tag,
|
||||
true, false, false
|
||||
> : detail::intersection::intersection_of_areal_with_multi_linestring
|
||||
<
|
||||
ReversePolygon,
|
||||
GeometryOut,
|
||||
OverlayType
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename MultiLinestring, typename Ring,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
MultiLinestring, Ring,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
ReverseMultiLinestring, ReverseRing, ReverseOut,
|
||||
multi_linestring_tag, ring_tag, linestring_tag,
|
||||
false, true, false
|
||||
> : detail::intersection::intersection_of_multi_linestring_with_areal
|
||||
<
|
||||
ReverseRing,
|
||||
GeometryOut,
|
||||
OverlayType
|
||||
>
|
||||
{};
|
||||
|
||||
template
|
||||
<
|
||||
typename MultiLinestring, typename Polygon,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
MultiLinestring, Polygon,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
ReverseMultiLinestring, ReverseRing, ReverseOut,
|
||||
multi_linestring_tag, polygon_tag, linestring_tag,
|
||||
false, true, false
|
||||
> : detail::intersection::intersection_of_multi_linestring_with_areal
|
||||
<
|
||||
ReverseRing,
|
||||
GeometryOut,
|
||||
OverlayType
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename MultiLinestring, typename MultiPolygon,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
bool ReverseMultiLinestring, bool ReverseMultiPolygon, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
MultiLinestring, MultiPolygon,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
ReverseMultiLinestring, ReverseMultiPolygon, ReverseOut,
|
||||
multi_linestring_tag, multi_polygon_tag, linestring_tag,
|
||||
false, true, false
|
||||
> : detail::intersection::intersection_of_multi_linestring_with_areal
|
||||
<
|
||||
ReverseMultiPolygon,
|
||||
GeometryOut,
|
||||
OverlayType
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_INTERSECTION_HPP
|
||||
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2014.
|
||||
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
@@ -14,48 +19,8 @@
|
||||
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_INTERIOR_RINGS_HPP
|
||||
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_INTERIOR_RINGS_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/num_interior_rings.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename MultiPolygon>
|
||||
struct num_interior_rings<MultiPolygon, multi_polygon_tag>
|
||||
{
|
||||
static inline std::size_t apply(MultiPolygon const& multi_polygon)
|
||||
{
|
||||
std::size_t n = 0;
|
||||
for (typename boost::range_iterator<MultiPolygon const>::type
|
||||
it = boost::begin(multi_polygon);
|
||||
it != boost::end(multi_polygon);
|
||||
++it)
|
||||
{
|
||||
n += geometry::num_interior_rings(*it);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_INTERIOR_RINGS_HPP
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/core/topological_dimension.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/append.hpp>
|
||||
#include <boost/geometry/algorithms/area.hpp>
|
||||
#include <boost/geometry/algorithms/centroid.hpp>
|
||||
#include <boost/geometry/algorithms/clear.hpp>
|
||||
@@ -39,8 +40,10 @@
|
||||
#include <boost/geometry/algorithms/envelope.hpp>
|
||||
#include <boost/geometry/algorithms/equals.hpp>
|
||||
#include <boost/geometry/algorithms/for_each.hpp>
|
||||
#include <boost/geometry/algorithms/intersection.hpp>
|
||||
#include <boost/geometry/algorithms/length.hpp>
|
||||
#include <boost/geometry/algorithms/num_geometries.hpp>
|
||||
#include <boost/geometry/algorithms/num_interior_rings.hpp>
|
||||
#include <boost/geometry/algorithms/perimeter.hpp>
|
||||
#include <boost/geometry/algorithms/remove_spikes.hpp>
|
||||
#include <boost/geometry/algorithms/reverse.hpp>
|
||||
@@ -49,9 +52,6 @@
|
||||
#include <boost/geometry/algorithms/unique.hpp>
|
||||
#include <boost/geometry/algorithms/within.hpp>
|
||||
|
||||
#include <boost/geometry/multi/algorithms/append.hpp>
|
||||
#include <boost/geometry/multi/algorithms/intersection.hpp>
|
||||
#include <boost/geometry/multi/algorithms/num_interior_rings.hpp>
|
||||
#include <boost/geometry/multi/algorithms/num_points.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/point_on_border.hpp>
|
||||
|
||||
@@ -68,7 +68,11 @@ private :
|
||||
|
||||
inline void apply(point_type* points) const
|
||||
{
|
||||
detail::assign_box_corners_oriented<!Clockwise>(m_box, points);
|
||||
// assign_box_corners_oriented requires a range
|
||||
// an alternative for this workaround would be to pass a range here,
|
||||
// e.g. use boost::array in points_view instead of c-array
|
||||
std::pair<point_type*, point_type*> rng = std::make_pair(points, points + 5);
|
||||
detail::assign_box_corners_oriented<!Clockwise>(m_box, rng);
|
||||
points[4] = points[0];
|
||||
}
|
||||
private :
|
||||
|
||||
@@ -36,6 +36,7 @@ class points_view
|
||||
// to have it lightweight). Probably there is already an
|
||||
// equivalent of this within Boost. If so, TODO: use that one.
|
||||
// This used to be "box_iterator" and "segment_iterator".
|
||||
// ALTERNATIVE: use boost:array and its iterators
|
||||
struct points_iterator
|
||||
: public boost::iterator_facade
|
||||
<
|
||||
@@ -105,7 +106,7 @@ class points_view
|
||||
}
|
||||
|
||||
Point const* m_points;
|
||||
int m_index;
|
||||
difference_type m_index;
|
||||
};
|
||||
|
||||
public :
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
test-suite boost-geometry-algorithms
|
||||
:
|
||||
[ run append.cpp : : : <toolset>msvc:<cxxflags>/bigobj ]
|
||||
[ run area.cpp ]
|
||||
[ run area.cpp : : : <toolset>msvc:<cxxflags>/bigobj ]
|
||||
[ run assign.cpp ]
|
||||
[ run buffer.cpp ]
|
||||
[ run centroid.cpp : : : <toolset>msvc:<cxxflags>/bigobj ]
|
||||
[ run comparable_distance.cpp ]
|
||||
[ run comparable_distance.cpp : : : <toolset>msvc:<cxxflags>/bigobj ]
|
||||
[ run convex_hull.cpp : : : <toolset>msvc:<cxxflags>/bigobj ]
|
||||
[ run correct.cpp ]
|
||||
[ run correct.cpp : : : <toolset>msvc:<cxxflags>/bigobj ]
|
||||
[ run convert.cpp : : : <toolset>msvc:<cxxflags>/bigobj ]
|
||||
[ run covered_by.cpp ]
|
||||
[ run crosses.cpp : : : <toolset>msvc:<cxxflags>/bigobj ]
|
||||
@@ -30,10 +30,10 @@ test-suite boost-geometry-algorithms
|
||||
[ run difference_linear_linear.cpp ]
|
||||
[ run difference_pl_pl.cpp ]
|
||||
[ run disjoint.cpp : : : <toolset>msvc:<cxxflags>/bigobj ]
|
||||
[ run disjoint_coverage.cpp ]
|
||||
[ run disjoint_coverage.cpp : : : <toolset>msvc:<cxxflags>/bigobj ]
|
||||
[ run distance.cpp : : : <toolset>msvc:<cxxflags>/bigobj ]
|
||||
[ run distance_areal_areal.cpp ]
|
||||
[ run distance_linear_areal.cpp ]
|
||||
[ run distance_areal_areal.cpp : : : <toolset>msvc:<cxxflags>/bigobj ]
|
||||
[ run distance_linear_areal.cpp : : : <toolset>msvc:<cxxflags>/bigobj ]
|
||||
[ run distance_linear_linear.cpp ]
|
||||
[ run distance_pointlike_areal.cpp ]
|
||||
[ run distance_pointlike_linear.cpp ]
|
||||
@@ -46,11 +46,12 @@ test-suite boost-geometry-algorithms
|
||||
[ run intersection_linear_linear.cpp ]
|
||||
[ run intersection_pl_pl.cpp ]
|
||||
[ run intersects.cpp : : : <toolset>msvc:<cxxflags>/bigobj ]
|
||||
[ run is_simple.cpp ]
|
||||
[ run is_valid.cpp ]
|
||||
[ run is_simple.cpp : : : <toolset>msvc:<cxxflags>/bigobj ]
|
||||
[ run is_valid.cpp : : : <toolset>msvc:<cxxflags>/bigobj ]
|
||||
[ run length.cpp ]
|
||||
[ run make.cpp ]
|
||||
[ run num_points.cpp ]
|
||||
[ run num_segments.cpp ]
|
||||
[ run overlaps.cpp : : : <toolset>msvc:<cxxflags>/bigobj ]
|
||||
[ run perimeter.cpp ]
|
||||
[ run point_on_surface.cpp ]
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#ifndef BOOST_GEOMETRY_TEST_FROM_WKT_HPP
|
||||
#define BOOST_GEOMETRY_TEST_FROM_WKT_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/geometry/io/wkt/read.hpp>
|
||||
#include <boost/geometry/multi/io/wkt/read.hpp>
|
||||
|
||||
|
||||
277
test/algorithms/num_segments.cpp
Normal file
277
test/algorithms/num_segments.cpp
Normal file
@@ -0,0 +1,277 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_TEST_MODULE
|
||||
#define BOOST_TEST_MODULE test_num_segments
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/test/included/unit_test.hpp>
|
||||
|
||||
#include <boost/variant/variant.hpp>
|
||||
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/geometries/geometries.hpp>
|
||||
#include <boost/geometry/io/wkt/wkt.hpp>
|
||||
#include <boost/geometry/algorithms/num_segments.hpp>
|
||||
|
||||
namespace bg = boost::geometry;
|
||||
|
||||
|
||||
typedef bg::model::point<double,2,bg::cs::cartesian> point;
|
||||
typedef bg::model::linestring<point> linestring;
|
||||
typedef bg::model::segment<point> segment;
|
||||
typedef bg::model::box<point> box;
|
||||
typedef bg::model::ring<point, true, true> ring_cw_closed;
|
||||
typedef bg::model::ring<point, true, false> ring_cw_open;
|
||||
typedef bg::model::ring<point, false, true> ring_ccw_closed;
|
||||
typedef bg::model::ring<point, false, false> ring_ccw_open;
|
||||
typedef bg::model::polygon<point, true, true> polygon_cw_closed;
|
||||
typedef bg::model::polygon<point, true, false> polygon_cw_open;
|
||||
typedef bg::model::polygon<point, false, true> polygon_ccw_closed;
|
||||
typedef bg::model::polygon<point, false, false> polygon_ccw_open;
|
||||
typedef bg::model::multi_point<point> multi_point;
|
||||
typedef bg::model::multi_linestring<linestring> multi_linestring;
|
||||
typedef bg::model::multi_polygon<polygon_cw_closed> multi_polygon_cw_closed;
|
||||
typedef bg::model::multi_polygon<polygon_cw_open> multi_polygon_cw_open;
|
||||
typedef bg::model::multi_polygon<polygon_ccw_closed> multi_polygon_ccw_closed;
|
||||
typedef bg::model::multi_polygon<polygon_ccw_open> multi_polygon_ccw_open;
|
||||
|
||||
|
||||
template <typename Geometry>
|
||||
struct test_num_segments
|
||||
{
|
||||
static inline void apply(Geometry const& geometry,
|
||||
std::size_t expected_closed,
|
||||
std::size_t expected_open)
|
||||
{
|
||||
std::size_t detected = bg::num_segments(geometry);
|
||||
BOOST_CHECK_MESSAGE( detected == expected_closed,
|
||||
"Expected: " << expected_closed
|
||||
<< " detected: " << detected
|
||||
<< " wkt: " << bg::wkt(geometry) );
|
||||
|
||||
detected = bg::num_segments(geometry, true);
|
||||
BOOST_CHECK_MESSAGE( detected == expected_open,
|
||||
"Expected (add for open): " << expected_open
|
||||
<< " detected (add for open): " << detected
|
||||
<< " wkt: " << bg::wkt(geometry) );
|
||||
|
||||
}
|
||||
|
||||
static inline void apply(Geometry const& geometry,
|
||||
std::size_t expected_closed)
|
||||
{
|
||||
apply(geometry, expected_closed, expected_closed);
|
||||
}
|
||||
|
||||
static inline void apply(std::string const& wkt,
|
||||
std::size_t expected_closed,
|
||||
std::size_t expected_open)
|
||||
{
|
||||
Geometry geometry;
|
||||
bg::read_wkt(wkt, geometry);
|
||||
apply(geometry, expected_closed, expected_open);
|
||||
}
|
||||
|
||||
static inline void apply(std::string const& wkt,
|
||||
std::size_t expected_closed)
|
||||
{
|
||||
apply(wkt, expected_closed, expected_closed);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_point )
|
||||
{
|
||||
test_num_segments<point>::apply("POINT(0 0)", 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_segment )
|
||||
{
|
||||
test_num_segments<segment>::apply("SEGMENT(0 0,1 1)", 1);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_box )
|
||||
{
|
||||
test_num_segments<box>::apply("BOX(0 0,1 1)", 4);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_linestring )
|
||||
{
|
||||
typedef test_num_segments<linestring> tester;
|
||||
|
||||
tester::apply("LINESTRING()", 0);
|
||||
tester::apply("LINESTRING(0 0)", 0);
|
||||
tester::apply("LINESTRING(0 0,0 0)", 1);
|
||||
tester::apply("LINESTRING(0 0,0 0,1 1)", 2);
|
||||
tester::apply("LINESTRING(0 0,0 0,0 0,1 1)", 3);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_multipoint )
|
||||
{
|
||||
typedef test_num_segments<multi_point> tester;
|
||||
|
||||
tester::apply("MULTIPOINT()", 0);
|
||||
tester::apply("MULTIPOINT(0 0)", 0);
|
||||
tester::apply("MULTIPOINT(0 0,0 0)", 0);
|
||||
tester::apply("MULTIPOINT(0 0,0 0,1 1)", 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_multilinestring )
|
||||
{
|
||||
typedef test_num_segments<multi_linestring> tester;
|
||||
|
||||
tester::apply("MULTILINESTRING()", 0);
|
||||
tester::apply("MULTILINESTRING((),(0 0))", 0);
|
||||
tester::apply("MULTILINESTRING((0 0))", 0);
|
||||
tester::apply("MULTILINESTRING((0 0,1 0))", 1);
|
||||
tester::apply("MULTILINESTRING((),(),(0 0,1 0))", 1);
|
||||
tester::apply("MULTILINESTRING((0 0,1 0,0 1),(0 0,1 0,0 1,0 0))", 5);
|
||||
}
|
||||
|
||||
template <typename OpenRing>
|
||||
void test_open_ring()
|
||||
{
|
||||
typedef test_num_segments<OpenRing> tester;
|
||||
|
||||
tester::apply("POLYGON(())", 0);
|
||||
tester::apply("POLYGON((0 0))", 0);
|
||||
tester::apply("POLYGON((0 0,1 0))", 1, 2);
|
||||
tester::apply("POLYGON((0 0,1 0,0 1))", 2, 3);
|
||||
tester::apply("POLYGON((0 0,0 0,1 0,0 1))", 3, 4);
|
||||
}
|
||||
|
||||
template <typename ClosedRing>
|
||||
void test_closed_ring()
|
||||
{
|
||||
typedef test_num_segments<ClosedRing> tester;
|
||||
|
||||
tester::apply("POLYGON(())", 0);
|
||||
tester::apply("POLYGON((0 0))", 0);
|
||||
tester::apply("POLYGON((0 0,0 0))", 1);
|
||||
tester::apply("POLYGON((0 0,1 0,0 0))", 2);
|
||||
tester::apply("POLYGON((0 0,1 0,0 1,0 0))", 3);
|
||||
tester::apply("POLYGON((0 0,1 0,1 0,0 1,0 0))", 4);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_ring )
|
||||
{
|
||||
test_open_ring<ring_ccw_open>();
|
||||
test_open_ring<ring_cw_open>();
|
||||
test_closed_ring<ring_ccw_closed>();
|
||||
test_closed_ring<ring_cw_closed>();
|
||||
}
|
||||
|
||||
template <typename OpenPolygon>
|
||||
void test_open_polygon()
|
||||
{
|
||||
typedef test_num_segments<OpenPolygon> tester;
|
||||
|
||||
tester::apply("POLYGON(())", 0);
|
||||
tester::apply("POLYGON((0 0))", 0);
|
||||
tester::apply("POLYGON((0 0,10 0),(0 0))", 1, 2);
|
||||
tester::apply("POLYGON((0 0,10 0),(1 1,2 1))", 2, 4);
|
||||
tester::apply("POLYGON((0 0,10 0,0 10))", 2, 3);
|
||||
tester::apply("POLYGON((0 0,10 0,0 10),())", 2, 3);
|
||||
tester::apply("POLYGON((0 0,10 0,0 10),(1 1))", 2, 3);
|
||||
tester::apply("POLYGON((0 0,10 0,0 10),(1 1,2 1))", 3, 5);
|
||||
tester::apply("POLYGON((0 0,10 0,0 10),(1 1,2 1,1 2))", 4, 6);
|
||||
tester::apply("POLYGON((0 0,10 0,10 10,0 10),(1 1,2 1,1 2))", 5, 7);
|
||||
tester::apply("POLYGON((0 0,10 0,10 10,0 10),(1 1,2 1,2 2,1 2))", 6, 8);
|
||||
tester::apply("POLYGON((0 0,10 0,10 10,0 10),(1 1,2 1,2 2,1 2),(5 5,6 5,6 6,5 6))", 9, 12);
|
||||
}
|
||||
|
||||
template <typename ClosedPolygon>
|
||||
void test_closed_polygon()
|
||||
{
|
||||
typedef test_num_segments<ClosedPolygon> tester;
|
||||
|
||||
tester::apply("POLYGON(())", 0);
|
||||
tester::apply("POLYGON((0 0))", 0);
|
||||
tester::apply("POLYGON((0 0,10 0,0 0),(0 0))", 2);
|
||||
tester::apply("POLYGON((0 0,10 0,0 0),(1 1,2 1,1 1))", 4);
|
||||
tester::apply("POLYGON((0 0,10 0,0 10,0 0))", 3);
|
||||
tester::apply("POLYGON((0 0,10 0,0 10,0 0),())", 3);
|
||||
tester::apply("POLYGON((0 0,10 0,0 10,0 0),(1 1))", 3);
|
||||
tester::apply("POLYGON((0 0,10 0,0 10,0 0),(1 1,2 1,1 1))", 5);
|
||||
tester::apply("POLYGON((0 0,10 0,0 10,0 0),(1 1,2 1,1 2,1 1))", 6);
|
||||
tester::apply("POLYGON((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,1 2,1 1))", 7);
|
||||
tester::apply("POLYGON((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,2 2,1 2,1 1))", 8);
|
||||
tester::apply("POLYGON((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,2 2,1 2,1 1),(5 5,6 5,6 6,5 6,5 5))", 12);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_polygon )
|
||||
{
|
||||
test_open_polygon<polygon_ccw_open>();
|
||||
test_open_polygon<polygon_cw_open>();
|
||||
test_closed_polygon<polygon_ccw_closed>();
|
||||
test_closed_polygon<polygon_cw_closed>();
|
||||
}
|
||||
|
||||
template <typename OpenMultiPolygon>
|
||||
void test_open_multipolygon()
|
||||
{
|
||||
typedef test_num_segments<OpenMultiPolygon> tester;
|
||||
|
||||
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10),(1 1,2 1,1 2)))", 5, 7);
|
||||
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10),(1 1,2 1,2 2,1 2),(5 5,6 5,6 6,5 6)))", 9, 12);
|
||||
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10),(1 1,2 1,1 2)),((100 100,110 100,110 110),(101 101,102 101,102 102)))", 9, 13);
|
||||
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10),(1 1,2 1,2 2,1 2),(5 5,6 5,6 6,5 6)),((100 100,110 100,110 110),(101 101,102 101,102 102),(105 105,106 105,106 106,105 106)))", 16, 22);
|
||||
}
|
||||
|
||||
template <typename ClosedMultiPolygon>
|
||||
void test_closed_multipolygon()
|
||||
{
|
||||
typedef test_num_segments<ClosedMultiPolygon> tester;
|
||||
|
||||
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,1 2,1 1)))", 7);
|
||||
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,2 2,1 2,1 1),(5 5,6 5,6 6,5 6,5 5)))", 12);
|
||||
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,1 2,1 1)),((100 100,110 100,110 110,100 100),(101 101,102 101,102 102,101 101)))", 13);
|
||||
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,2 2,1 2,1 1),(5 5,6 5,6 6,5 6,5 5)),((100 100,110 100,110 110,100 100),(101 101,102 101,102 102,101 101),(105 105,106 105,106 106,105 106,105 105)))", 22);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_multipolygon )
|
||||
{
|
||||
test_open_multipolygon<multi_polygon_ccw_open>();
|
||||
test_open_multipolygon<multi_polygon_cw_open>();
|
||||
test_closed_multipolygon<multi_polygon_ccw_closed>();
|
||||
test_closed_multipolygon<multi_polygon_cw_closed>();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_variant )
|
||||
{
|
||||
typedef boost::variant
|
||||
<
|
||||
linestring, polygon_cw_open, polygon_cw_closed
|
||||
> variant_geometry_type;
|
||||
|
||||
typedef test_num_segments<variant_geometry_type> tester;
|
||||
|
||||
linestring ls;
|
||||
bg::read_wkt("LINESTRING(0 0,1 1,2 2)", ls);
|
||||
|
||||
polygon_cw_open p_open;
|
||||
bg::read_wkt("POLYGON((0 0,0 1,1 0))", p_open);
|
||||
|
||||
polygon_cw_closed p_closed;
|
||||
bg::read_wkt("POLYGON((0 0,0 1,1 1,1 0,0 0))", p_closed);
|
||||
|
||||
variant_geometry_type variant_geometry;
|
||||
|
||||
variant_geometry = ls;
|
||||
tester::apply(variant_geometry, 2);
|
||||
|
||||
variant_geometry = p_open;
|
||||
tester::apply(variant_geometry, 2, 3);
|
||||
|
||||
variant_geometry = p_closed;
|
||||
tester::apply(variant_geometry, 4);
|
||||
}
|
||||
@@ -107,7 +107,7 @@ void test_difference(std::string const& caseid, G1 const& g1, G2 const& g2,
|
||||
}
|
||||
|
||||
typename bg::default_area_result<G1>::type area = 0;
|
||||
int n = 0;
|
||||
std::size_t n = 0;
|
||||
for (typename std::vector<OutputType>::iterator it = clip.begin();
|
||||
it != clip.end();
|
||||
++it)
|
||||
@@ -157,7 +157,7 @@ void test_difference(std::string const& caseid, G1 const& g1, G2 const& g2,
|
||||
#if ! defined(BOOST_GEOMETRY_NO_BOOST_TEST)
|
||||
if (expected_point_count >= 0)
|
||||
{
|
||||
BOOST_CHECK_MESSAGE(bg::math::abs(n - expected_point_count) < 3,
|
||||
BOOST_CHECK_MESSAGE(bg::math::abs(int(n) - expected_point_count) < 3,
|
||||
"difference: " << caseid
|
||||
<< " #points expected: " << expected_point_count
|
||||
<< " detected: " << n
|
||||
|
||||
@@ -219,6 +219,18 @@ void test_tickets()
|
||||
bool within = boost::geometry::within(p, r);
|
||||
BOOST_CHECK_EQUAL(within, false);
|
||||
}
|
||||
|
||||
// https://svn.boost.org/trac/boost/ticket/10234
|
||||
{
|
||||
pt p;
|
||||
ring r;
|
||||
bg::read_wkt("POINT(0.1377 5.00)", p);
|
||||
bg::read_wkt("POLYGON((0.1277 4.97, 0.1277 5.00, 0.1278 4.9999999999999982, 0.1278 4.97, 0.1277 4.97))", r);
|
||||
bool within = boost::geometry::within(p, r);
|
||||
BOOST_CHECK_EQUAL(within, false);
|
||||
bool covered_by = boost::geometry::covered_by(p, r);
|
||||
BOOST_CHECK_EQUAL(covered_by, false);
|
||||
}
|
||||
}
|
||||
|
||||
int test_main( int , char* [] )
|
||||
|
||||
@@ -28,15 +28,9 @@
|
||||
#include <boost/geometry/geometries/point_xy.hpp>
|
||||
#include <boost/geometry/multi/geometries/multi_geometries.hpp>
|
||||
|
||||
#include <boost/geometry/io/svg/svg_mapper.hpp>
|
||||
#include <boost/geometry/extensions/algorithms/midpoints.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp>
|
||||
|
||||
#include <boost/geometry/multi/multi.hpp> // TODO: more specific
|
||||
|
||||
#include <boost/geometry/strategies/buffer.hpp>
|
||||
#include <boost/geometry/strategies/agnostic/buffer_distance_asymmetric.hpp>
|
||||
|
||||
#include <common/common_settings.hpp>
|
||||
#include <common/make_square_polygon.hpp>
|
||||
@@ -197,28 +191,31 @@ bool test_buffer(MultiPolygon& result, int& index,
|
||||
typedef bg::strategy::buffer::distance_asymmetric<coordinate_type> distance_strategy_type;
|
||||
distance_strategy_type distance_strategy(settings.distance, settings.distance);
|
||||
|
||||
typedef bg::strategy::buffer::join_round<point_type, point_type> join_strategy_type;
|
||||
join_strategy_type join_strategy;
|
||||
|
||||
typedef typename boost::range_value<MultiPolygon>::type polygon_type;
|
||||
MultiPolygon buffered;
|
||||
|
||||
std::ostringstream out;
|
||||
out << "recursive_polygons_buffer_" << index++ << "_" << level;
|
||||
|
||||
bg::strategy::buffer::end_round end_strategy;
|
||||
bg::strategy::buffer::point_circle point_strategy;
|
||||
bg::strategy::buffer::side_straight side_strategy;
|
||||
|
||||
try
|
||||
{
|
||||
switch(settings.join_code)
|
||||
{
|
||||
case 1 :
|
||||
bg::buffer_inserter<polygon_type>(mp, std::back_inserter(buffered),
|
||||
distance_strategy,
|
||||
bg::strategy::buffer::join_round<point_type, point_type>());
|
||||
bg::buffer(mp, buffered,
|
||||
distance_strategy, side_strategy,
|
||||
bg::strategy::buffer::join_round(),
|
||||
end_strategy, point_strategy);
|
||||
break;
|
||||
case 2 :
|
||||
bg::buffer_inserter<polygon_type>(mp, std::back_inserter(buffered),
|
||||
distance_strategy,
|
||||
bg::strategy::buffer::join_miter<point_type, point_type>());
|
||||
bg::buffer(mp, buffered,
|
||||
distance_strategy, side_strategy,
|
||||
bg::strategy::buffer::join_miter(),
|
||||
end_strategy, point_strategy);
|
||||
break;
|
||||
default :
|
||||
return false;
|
||||
|
||||
@@ -30,7 +30,7 @@ struct wrapped_boost_array
|
||||
inline wrapped_boost_array() : size(0) {}
|
||||
|
||||
boost::array<Point, Count> array;
|
||||
int size;
|
||||
std::size_t size;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user