Merge branch 'develop' of https://github.com/boostorg/geometry into feature/disjoint-1.57

This commit is contained in:
Menelaos Karavelas
2014-08-09 01:03:41 +03:00
46 changed files with 1734 additions and 1148 deletions

View File

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

View File

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

View File

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

View File

@@ -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"]

View File

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

View File

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

View 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]

View File

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

View File

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

View File

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

View 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
]
*/
//]

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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);
}

View File

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

View File

@@ -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* [] )

View File

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

View File

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