Added boost header
This commit is contained in:
230
test/external/boost/geometry/algorithms/append.hpp
vendored
Normal file
230
test/external/boost/geometry/algorithms/append.hpp
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_APPEND_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_APPEND_HPP
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/mutable_range.hpp>
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/num_interior_rings.hpp>
|
||||
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace append
|
||||
{
|
||||
|
||||
template <typename Geometry, typename Point>
|
||||
struct append_no_action
|
||||
{
|
||||
static inline void apply(Geometry& geometry, Point const& point,
|
||||
int = 0, int = 0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry, typename Point>
|
||||
struct append_point
|
||||
{
|
||||
static inline void apply(Geometry& geometry, Point const& point,
|
||||
int = 0, int = 0)
|
||||
{
|
||||
typename geometry::point_type<Geometry>::type copy;
|
||||
geometry::detail::conversion::convert_point_to_point(point, copy);
|
||||
traits::push_back<Geometry>::apply(geometry, copy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Geometry, typename Range>
|
||||
struct append_range
|
||||
{
|
||||
typedef typename boost::range_value<Range>::type point_type;
|
||||
|
||||
static inline void apply(Geometry& geometry, Range const& range,
|
||||
int = 0, int = 0)
|
||||
{
|
||||
for (typename boost::range_iterator<Range const>::type
|
||||
it = boost::begin(range);
|
||||
it != boost::end(range);
|
||||
++it)
|
||||
{
|
||||
append_point<Geometry, point_type>::apply(geometry, *it);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Polygon, typename Point>
|
||||
struct point_to_polygon
|
||||
{
|
||||
typedef typename ring_type<Polygon>::type ring_type;
|
||||
|
||||
static inline void apply(Polygon& polygon, Point const& point,
|
||||
int ring_index, int = 0)
|
||||
{
|
||||
if (ring_index == -1)
|
||||
{
|
||||
append_point<ring_type, Point>::apply(
|
||||
exterior_ring(polygon), point);
|
||||
}
|
||||
else if (ring_index < int(num_interior_rings(polygon)))
|
||||
{
|
||||
append_point<ring_type, Point>::apply(
|
||||
interior_rings(polygon)[ring_index], point);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Polygon, typename Range>
|
||||
struct range_to_polygon
|
||||
{
|
||||
typedef typename ring_type<Polygon>::type ring_type;
|
||||
|
||||
static inline void apply(Polygon& polygon, Range const& range,
|
||||
int ring_index, int )
|
||||
{
|
||||
if (ring_index == -1)
|
||||
{
|
||||
append_range<ring_type, Range>::apply(
|
||||
exterior_ring(polygon), range);
|
||||
}
|
||||
else if (ring_index < int(num_interior_rings(polygon)))
|
||||
{
|
||||
append_range<ring_type, Range>::apply(
|
||||
interior_rings(polygon)[ring_index], range);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::append
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
namespace splitted_dispatch
|
||||
{
|
||||
|
||||
template <typename Tag, typename Geometry, typename Point>
|
||||
struct append_point
|
||||
: detail::append::append_no_action<Geometry, Point>
|
||||
{};
|
||||
|
||||
template <typename Geometry, typename Point>
|
||||
struct append_point<linestring_tag, Geometry, Point>
|
||||
: detail::append::append_point<Geometry, Point>
|
||||
{};
|
||||
|
||||
template <typename Geometry, typename Point>
|
||||
struct append_point<ring_tag, Geometry, Point>
|
||||
: detail::append::append_point<Geometry, Point>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename Point>
|
||||
struct append_point<polygon_tag, Polygon, Point>
|
||||
: detail::append::point_to_polygon<Polygon, Point>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Tag, typename Geometry, typename Range>
|
||||
struct append_range
|
||||
: detail::append::append_no_action<Geometry, Range>
|
||||
{};
|
||||
|
||||
template <typename Geometry, typename Range>
|
||||
struct append_range<linestring_tag, Geometry, Range>
|
||||
: detail::append::append_range<Geometry, Range>
|
||||
{};
|
||||
|
||||
template <typename Geometry, typename Range>
|
||||
struct append_range<ring_tag, Geometry, Range>
|
||||
: detail::append::append_range<Geometry, Range>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename Range>
|
||||
struct append_range<polygon_tag, Polygon, Range>
|
||||
: detail::append::range_to_polygon<Polygon, Range>
|
||||
{};
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Default: append a range (or linestring or ring or whatever) to any geometry
|
||||
template <typename TagRangeOrPoint, typename Geometry, typename RangeOrPoint>
|
||||
struct append
|
||||
: splitted_dispatch::append_range<typename tag<Geometry>::type, Geometry, RangeOrPoint>
|
||||
{};
|
||||
|
||||
// Specialization for point to append a point to any geometry
|
||||
template <typename Geometry, typename RangeOrPoint>
|
||||
struct append<point_tag, Geometry, RangeOrPoint>
|
||||
: splitted_dispatch::append_point<typename tag<Geometry>::type, Geometry, RangeOrPoint>
|
||||
{};
|
||||
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief Appends one or more points to a linestring, ring, polygon, multi-geometry
|
||||
\ingroup append
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam RangeOrPoint Either a range or a point, fullfilling Boost.Range concept or Boost.Geometry Point Concept
|
||||
\param geometry \param_geometry
|
||||
\param range_or_point The point or range to add
|
||||
\param ring_index The index of the ring in case of a polygon:
|
||||
exterior ring (-1, the default) or interior ring index
|
||||
\param multi_index Reserved for multi polygons or multi linestrings
|
||||
|
||||
\qbk{[include reference/algorithms/append.qbk]}
|
||||
}
|
||||
*/
|
||||
template <typename Geometry, typename RangeOrPoint>
|
||||
inline void append(Geometry& geometry, RangeOrPoint const& range_or_point,
|
||||
int ring_index = -1, int multi_index = 0)
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
dispatch::append
|
||||
<
|
||||
typename tag<RangeOrPoint>::type,
|
||||
Geometry,
|
||||
RangeOrPoint
|
||||
>::apply(geometry, range_or_point, ring_index, multi_index);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_APPEND_HPP
|
||||
287
test/external/boost/geometry/algorithms/area.hpp
vendored
Normal file
287
test/external/boost/geometry/algorithms/area.hpp
vendored
Normal file
@@ -0,0 +1,287 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_AREA_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_AREA_HPP
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/range/functions.hpp>
|
||||
#include <boost/range/metafunctions.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/point_order.hpp>
|
||||
#include <boost/geometry/core/ring_type.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/calculate_null.hpp>
|
||||
#include <boost/geometry/algorithms/detail/calculate_sum.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/area.hpp>
|
||||
#include <boost/geometry/strategies/default_area_result.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/concepts/area_concept.hpp>
|
||||
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
#include <boost/geometry/util/order_as_direction.hpp>
|
||||
#include <boost/geometry/views/closeable_view.hpp>
|
||||
#include <boost/geometry/views/reversible_view.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace area
|
||||
{
|
||||
|
||||
template<typename Box, typename Strategy>
|
||||
struct box_area
|
||||
{
|
||||
typedef typename coordinate_type<Box>::type return_type;
|
||||
|
||||
static inline return_type apply(Box const& box, Strategy const&)
|
||||
{
|
||||
// Currently only works for 2D Cartesian boxes
|
||||
assert_dimension<Box, 2>();
|
||||
|
||||
return_type const dx = get<max_corner, 0>(box)
|
||||
- get<min_corner, 0>(box);
|
||||
return_type const dy = get<max_corner, 1>(box)
|
||||
- get<min_corner, 1>(box);
|
||||
|
||||
return dx * dy;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Ring,
|
||||
iterate_direction Direction,
|
||||
closure_selector Closure,
|
||||
typename Strategy
|
||||
>
|
||||
struct ring_area
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT( (geometry::concept::AreaStrategy<Strategy>) );
|
||||
|
||||
typedef typename Strategy::return_type type;
|
||||
|
||||
static inline type apply(Ring const& ring, Strategy const& strategy)
|
||||
{
|
||||
assert_dimension<Ring, 2>();
|
||||
|
||||
// Ignore warning (because using static method sometimes) on strategy
|
||||
boost::ignore_unused_variable_warning(strategy);
|
||||
|
||||
// An open ring has at least three points,
|
||||
// A closed ring has at least four points,
|
||||
// if not, there is no (zero) area
|
||||
if (boost::size(ring)
|
||||
< core_detail::closure::minimum_ring_size<Closure>::value)
|
||||
{
|
||||
return type();
|
||||
}
|
||||
|
||||
typedef typename reversible_view<Ring const, Direction>::type rview_type;
|
||||
typedef typename closeable_view
|
||||
<
|
||||
rview_type const, Closure
|
||||
>::type view_type;
|
||||
typedef typename boost::range_iterator<view_type const>::type iterator_type;
|
||||
|
||||
rview_type rview(ring);
|
||||
view_type view(rview);
|
||||
typename Strategy::state_type state;
|
||||
iterator_type it = boost::begin(view);
|
||||
iterator_type end = boost::end(view);
|
||||
|
||||
for (iterator_type previous = it++;
|
||||
it != end;
|
||||
++previous, ++it)
|
||||
{
|
||||
strategy.apply(*previous, *it, state);
|
||||
}
|
||||
|
||||
return strategy.result(state);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::area
|
||||
|
||||
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag,
|
||||
typename Geometry,
|
||||
typename Strategy
|
||||
>
|
||||
struct area
|
||||
: detail::calculate_null
|
||||
<
|
||||
typename Strategy::return_type,
|
||||
Geometry,
|
||||
Strategy
|
||||
> {};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Strategy
|
||||
>
|
||||
struct area<box_tag, Geometry, Strategy>
|
||||
: detail::area::box_area<Geometry, Strategy>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Ring,
|
||||
typename Strategy
|
||||
>
|
||||
struct area<ring_tag, Ring, Strategy>
|
||||
: detail::area::ring_area
|
||||
<
|
||||
Ring,
|
||||
order_as_direction<geometry::point_order<Ring>::value>::value,
|
||||
geometry::closure<Ring>::value,
|
||||
Strategy
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Polygon,
|
||||
typename Strategy
|
||||
>
|
||||
struct area<polygon_tag, Polygon, Strategy>
|
||||
: detail::calculate_polygon_sum
|
||||
<
|
||||
typename Strategy::return_type,
|
||||
Polygon,
|
||||
Strategy,
|
||||
detail::area::ring_area
|
||||
<
|
||||
typename ring_type<Polygon const>::type,
|
||||
order_as_direction<geometry::point_order<Polygon>::value>::value,
|
||||
geometry::closure<Polygon>::value,
|
||||
Strategy
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc{area}
|
||||
\ingroup area
|
||||
\details \details_calc{area}. \details_default_strategy
|
||||
|
||||
The area algorithm calculates the surface area of all geometries having a surface, namely
|
||||
box, polygon, ring, multipolygon. The units are the square of the units used for the points
|
||||
defining the surface. If subject geometry is defined in meters, then area is calculated
|
||||
in square meters.
|
||||
|
||||
The area calculation can be done in all three common coordinate systems, Cartesian, Spherical
|
||||
and Geographic as well.
|
||||
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry
|
||||
\return \return_calc{area}
|
||||
|
||||
\qbk{[include reference/algorithms/area.qbk]}
|
||||
\qbk{[heading Examples]}
|
||||
\qbk{[area] [area_output]}
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline typename default_area_result<Geometry>::type area(Geometry const& geometry)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
typedef typename point_type<Geometry>::type point_type;
|
||||
typedef typename strategy::area::services::default_strategy
|
||||
<
|
||||
typename cs_tag<point_type>::type,
|
||||
point_type
|
||||
>::type strategy_type;
|
||||
|
||||
return dispatch::area
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
strategy_type
|
||||
>::apply(geometry, strategy_type());
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief \brief_calc{area} \brief_strategy
|
||||
\ingroup area
|
||||
\details \details_calc{area} \brief_strategy. \details_strategy_reasons
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Strategy \tparam_strategy{Area}
|
||||
\param geometry \param_geometry
|
||||
\param strategy \param_strategy{area}
|
||||
\return \return_calc{area}
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
|
||||
\qbk{
|
||||
[include reference/algorithms/area.qbk]
|
||||
|
||||
[heading Example]
|
||||
[area_with_strategy]
|
||||
[area_with_strategy_output]
|
||||
|
||||
[heading Available Strategies]
|
||||
\* [link geometry.reference.strategies.strategy_area_surveyor Surveyor (cartesian)]
|
||||
\* [link geometry.reference.strategies.strategy_area_huiller Huiller (spherical)]
|
||||
}
|
||||
*/
|
||||
template <typename Geometry, typename Strategy>
|
||||
inline typename Strategy::return_type area(
|
||||
Geometry const& geometry, Strategy const& strategy)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
return dispatch::area
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
Strategy
|
||||
>::apply(geometry, strategy);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_AREA_HPP
|
||||
182
test/external/boost/geometry/algorithms/assign.hpp
vendored
Normal file
182
test/external/boost/geometry/algorithms/assign.hpp
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_ASSIGN_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_ASSIGN_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/concept/requires.hpp>
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/numeric/conversion/bounds.hpp>
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
|
||||
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/assign_values.hpp>
|
||||
#include <boost/geometry/algorithms/convert.hpp>
|
||||
|
||||
#include <boost/geometry/arithmetic/arithmetic.hpp>
|
||||
#include <boost/geometry/algorithms/append.hpp>
|
||||
#include <boost/geometry/algorithms/clear.hpp>
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
|
||||
#include <boost/geometry/util/for_each_coordinate.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
/*!
|
||||
\brief Assign a range of points to a linestring, ring or polygon
|
||||
\note The point-type of the range might be different from the point-type of the geometry
|
||||
\ingroup assign
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Range \tparam_range_point
|
||||
\param geometry \param_geometry
|
||||
\param range \param_range_point
|
||||
|
||||
\qbk{
|
||||
[heading Notes]
|
||||
[note Assign automatically clears the geometry before assigning (use append if you don't want that)]
|
||||
[heading Example]
|
||||
[assign_points] [assign_points_output]
|
||||
|
||||
[heading See also]
|
||||
\* [link geometry.reference.algorithms.append append]
|
||||
}
|
||||
*/
|
||||
template <typename Geometry, typename Range>
|
||||
inline void assign_points(Geometry& geometry, Range const& range)
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
clear(geometry);
|
||||
geometry::append(geometry, range, -1, 0);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief assign to a box inverse infinite
|
||||
\details The assign_inverse function initialize a 2D or 3D box with large coordinates, the
|
||||
min corner is very large, the max corner is very small. This is a convenient starting point to
|
||||
collect the minimum bounding box of a geometry.
|
||||
\ingroup assign
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry
|
||||
|
||||
\qbk{
|
||||
[heading Example]
|
||||
[assign_inverse] [assign_inverse_output]
|
||||
|
||||
[heading See also]
|
||||
\* [link geometry.reference.algorithms.make.make_inverse make_inverse]
|
||||
}
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline void assign_inverse(Geometry& geometry)
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
dispatch::assign_inverse
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry
|
||||
>::apply(geometry);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief assign zero values to a box, point
|
||||
\ingroup assign
|
||||
\details The assign_zero function initializes a 2D or 3D point or box with coordinates of zero
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry
|
||||
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline void assign_zero(Geometry& geometry)
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
dispatch::assign_zero
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry
|
||||
>::apply(geometry);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Assigns one geometry to another geometry
|
||||
\details The assign algorithm assigns one geometry, e.g. a BOX, to another geometry, e.g. a RING. This only
|
||||
if it is possible and applicable.
|
||||
\ingroup assign
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry (target)
|
||||
\param geometry2 \param_geometry (source)
|
||||
|
||||
\qbk{
|
||||
[heading Example]
|
||||
[assign] [assign_output]
|
||||
|
||||
[heading See also]
|
||||
\* [link geometry.reference.algorithms.convert convert]
|
||||
}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline void assign(Geometry1& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
concept::check_concepts_and_equal_dimensions<Geometry1, Geometry2 const>();
|
||||
|
||||
bool const same_point_order =
|
||||
point_order<Geometry1>::value == point_order<Geometry2>::value;
|
||||
bool const same_closure =
|
||||
closure<Geometry1>::value == closure<Geometry2>::value;
|
||||
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
same_point_order, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_POINT_ORDER
|
||||
, (types<Geometry1, Geometry2>)
|
||||
);
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
same_closure, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_CLOSURE
|
||||
, (types<Geometry1, Geometry2>)
|
||||
);
|
||||
|
||||
dispatch::convert
|
||||
<
|
||||
false,
|
||||
typename tag<Geometry2>::type,
|
||||
typename tag<Geometry1>::type,
|
||||
dimension<Geometry1>::type::value,
|
||||
Geometry2,
|
||||
Geometry1
|
||||
>::apply(geometry2, geometry1);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_ASSIGN_HPP
|
||||
167
test/external/boost/geometry/algorithms/buffer.hpp
vendored
Normal file
167
test/external/boost/geometry/algorithms/buffer.hpp
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_BUFFER_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_BUFFER_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
|
||||
|
||||
#include <boost/geometry/algorithms/clear.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint.hpp>
|
||||
#include <boost/geometry/arithmetic/arithmetic.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/geometries/segment.hpp>
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace buffer
|
||||
{
|
||||
|
||||
template <typename BoxIn, typename BoxOut, typename T, std::size_t C, std::size_t D, std::size_t N>
|
||||
struct box_loop
|
||||
{
|
||||
typedef typename coordinate_type<BoxOut>::type coordinate_type;
|
||||
|
||||
static inline void apply(BoxIn const& box_in, T const& distance, BoxOut& box_out)
|
||||
{
|
||||
coordinate_type d = distance;
|
||||
set<C, D>(box_out, get<C, D>(box_in) + d);
|
||||
box_loop<BoxIn, BoxOut, T, C, D + 1, N>::apply(box_in, distance, box_out);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename BoxIn, typename BoxOut, typename T, std::size_t C, std::size_t N>
|
||||
struct box_loop<BoxIn, BoxOut, T, C, N, N>
|
||||
{
|
||||
static inline void apply(BoxIn const&, T const&, BoxOut&) {}
|
||||
};
|
||||
|
||||
// Extends a box with the same amount in all directions
|
||||
template<typename BoxIn, typename BoxOut, typename T>
|
||||
inline void buffer_box(BoxIn const& box_in, T const& distance, BoxOut& box_out)
|
||||
{
|
||||
assert_dimension_equal<BoxIn, BoxOut>();
|
||||
|
||||
static const std::size_t N = dimension<BoxIn>::value;
|
||||
|
||||
box_loop<BoxIn, BoxOut, T, min_corner, 0, N>::apply(box_in, -distance, box_out);
|
||||
box_loop<BoxIn, BoxOut, T, max_corner, 0, N>::apply(box_in, distance, box_out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}} // namespace detail::buffer
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template <typename TagIn, typename TagOut, typename Input, typename T, typename Output>
|
||||
struct buffer {};
|
||||
|
||||
|
||||
template <typename BoxIn, typename T, typename BoxOut>
|
||||
struct buffer<box_tag, box_tag, BoxIn, T, BoxOut>
|
||||
{
|
||||
static inline void apply(BoxIn const& box_in, T const& distance,
|
||||
T const& chord_length, BoxIn& box_out)
|
||||
{
|
||||
detail::buffer::buffer_box(box_in, distance, box_out);
|
||||
}
|
||||
};
|
||||
|
||||
// Many things to do. Point is easy, other geometries require self intersections
|
||||
// For point, note that it should output as a polygon (like the rest). Buffers
|
||||
// of a set of geometries are often lateron combined using a "dissolve" operation.
|
||||
// Two points close to each other get a combined kidney shaped buffer then.
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc{buffer}
|
||||
\ingroup buffer
|
||||
\details \details_calc{buffer, \det_buffer}.
|
||||
\tparam Input \tparam_geometry
|
||||
\tparam Output \tparam_geometry
|
||||
\tparam Distance \tparam_numeric
|
||||
\param geometry_in \param_geometry
|
||||
\param geometry_out \param_geometry
|
||||
\param distance The distance to be used for the buffer
|
||||
\param chord_length (optional) The length of the chord's in the generated arcs around points or bends
|
||||
\note Currently only implemented for box, the trivial case, but still useful
|
||||
|
||||
\qbk{[include reference/algorithms/buffer.qbk]}
|
||||
*/
|
||||
template <typename Input, typename Output, typename Distance>
|
||||
inline void buffer(Input const& geometry_in, Output& geometry_out,
|
||||
Distance const& distance, Distance const& chord_length = -1)
|
||||
{
|
||||
concept::check<Input const>();
|
||||
concept::check<Output>();
|
||||
|
||||
dispatch::buffer
|
||||
<
|
||||
typename tag<Input>::type,
|
||||
typename tag<Output>::type,
|
||||
Input,
|
||||
Distance,
|
||||
Output
|
||||
>::apply(geometry_in, distance, chord_length, geometry_out);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief \brief_calc{buffer}
|
||||
\ingroup buffer
|
||||
\details \details_calc{return_buffer, \det_buffer}. \details_return{buffer}.
|
||||
\tparam Input \tparam_geometry
|
||||
\tparam Output \tparam_geometry
|
||||
\tparam Distance \tparam_numeric
|
||||
\param geometry \param_geometry
|
||||
\param distance The distance to be used for the buffer
|
||||
\param chord_length (optional) The length of the chord's in the generated arcs around points or bends
|
||||
\return \return_calc{buffer}
|
||||
*/
|
||||
template <typename Output, typename Input, typename T>
|
||||
Output return_buffer(Input const& geometry, T const& distance, T const& chord_length = -1)
|
||||
{
|
||||
concept::check<Input const>();
|
||||
concept::check<Output>();
|
||||
|
||||
Output geometry_out;
|
||||
|
||||
dispatch::buffer
|
||||
<
|
||||
typename tag<Input>::type,
|
||||
typename tag<Output>::type,
|
||||
Input,
|
||||
T,
|
||||
Output
|
||||
>::apply(geometry, distance, chord_length, geometry_out);
|
||||
|
||||
return geometry_out;
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_BUFFER_HPP
|
||||
470
test/external/boost/geometry/algorithms/centroid.hpp
vendored
Normal file
470
test/external/boost/geometry/algorithms/centroid.hpp
vendored
Normal file
@@ -0,0 +1,470 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_CENTROID_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_CENTROID_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/exception.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/tag_cast.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/convert.hpp>
|
||||
#include <boost/geometry/algorithms/distance.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/strategies/centroid.hpp>
|
||||
#include <boost/geometry/strategies/concepts/centroid_concept.hpp>
|
||||
#include <boost/geometry/views/closeable_view.hpp>
|
||||
|
||||
#include <boost/geometry/util/for_each_coordinate.hpp>
|
||||
#include <boost/geometry/util/select_coordinate_type.hpp>
|
||||
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#if ! defined(BOOST_GEOMETRY_CENTROID_NO_THROW)
|
||||
|
||||
/*!
|
||||
\brief Centroid Exception
|
||||
\ingroup centroid
|
||||
\details The centroid_exception is thrown if the free centroid function is called with
|
||||
geometries for which the centroid cannot be calculated. For example: a linestring
|
||||
without points, a polygon without points, an empty multi-geometry.
|
||||
\qbk{
|
||||
[heading See also]
|
||||
\* [link geometry.reference.algorithms.centroid the centroid function]
|
||||
}
|
||||
|
||||
*/
|
||||
class centroid_exception : public geometry::exception
|
||||
{
|
||||
public:
|
||||
|
||||
inline centroid_exception() {}
|
||||
|
||||
virtual char const* what() const throw()
|
||||
{
|
||||
return "Boost.Geometry Centroid calculation exception";
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace centroid
|
||||
{
|
||||
|
||||
template<typename Point, typename PointCentroid, typename Strategy>
|
||||
struct centroid_point
|
||||
{
|
||||
static inline void apply(Point const& point, PointCentroid& centroid,
|
||||
Strategy const&)
|
||||
{
|
||||
geometry::convert(point, centroid);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Box,
|
||||
typename Point,
|
||||
std::size_t Dimension,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct centroid_box_calculator
|
||||
{
|
||||
typedef typename select_coordinate_type
|
||||
<
|
||||
Box, Point
|
||||
>::type coordinate_type;
|
||||
static inline void apply(Box const& box, Point& centroid)
|
||||
{
|
||||
coordinate_type const c1 = get<min_corner, Dimension>(box);
|
||||
coordinate_type const c2 = get<max_corner, Dimension>(box);
|
||||
coordinate_type m = c1 + c2;
|
||||
m /= 2.0;
|
||||
|
||||
set<Dimension>(centroid, m);
|
||||
|
||||
centroid_box_calculator
|
||||
<
|
||||
Box, Point,
|
||||
Dimension + 1, DimensionCount
|
||||
>::apply(box, centroid);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename Box, typename Point, std::size_t DimensionCount>
|
||||
struct centroid_box_calculator<Box, Point, DimensionCount, DimensionCount>
|
||||
{
|
||||
static inline void apply(Box const& , Point& )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename Box, typename Point, typename Strategy>
|
||||
struct centroid_box
|
||||
{
|
||||
static inline void apply(Box const& box, Point& centroid,
|
||||
Strategy const&)
|
||||
{
|
||||
centroid_box_calculator
|
||||
<
|
||||
Box, Point,
|
||||
0, dimension<Box>::type::value
|
||||
>::apply(box, centroid);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// There is one thing where centroid is different from e.g. within.
|
||||
// If the ring has only one point, it might make sense that
|
||||
// that point is the centroid.
|
||||
template<typename Point, typename Range>
|
||||
inline bool range_ok(Range const& range, Point& centroid)
|
||||
{
|
||||
std::size_t const n = boost::size(range);
|
||||
if (n > 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (n <= 0)
|
||||
{
|
||||
#if ! defined(BOOST_GEOMETRY_CENTROID_NO_THROW)
|
||||
throw centroid_exception();
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
else // if (n == 1)
|
||||
{
|
||||
// Take over the first point in a "coordinate neutral way"
|
||||
geometry::convert(*boost::begin(range), centroid);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Calculate the centroid of a ring.
|
||||
*/
|
||||
template<typename Ring, closure_selector Closure, typename Strategy>
|
||||
struct centroid_range_state
|
||||
{
|
||||
static inline void apply(Ring const& ring,
|
||||
Strategy const& strategy, typename Strategy::state_type& state)
|
||||
{
|
||||
typedef typename closeable_view<Ring const, Closure>::type view_type;
|
||||
|
||||
typedef typename boost::range_iterator<view_type const>::type iterator_type;
|
||||
|
||||
view_type view(ring);
|
||||
iterator_type it = boost::begin(view);
|
||||
iterator_type end = boost::end(view);
|
||||
|
||||
for (iterator_type previous = it++;
|
||||
it != end;
|
||||
++previous, ++it)
|
||||
{
|
||||
Strategy::apply(*previous, *it, state);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Range, typename Point, closure_selector Closure, typename Strategy>
|
||||
struct centroid_range
|
||||
{
|
||||
static inline void apply(Range const& range, Point& centroid,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
if (range_ok(range, centroid))
|
||||
{
|
||||
typename Strategy::state_type state;
|
||||
centroid_range_state
|
||||
<
|
||||
Range,
|
||||
Closure,
|
||||
Strategy
|
||||
>::apply(range, strategy, state);
|
||||
Strategy::result(state, centroid);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
\brief Centroid of a polygon.
|
||||
\note Because outer ring is clockwise, inners are counter clockwise,
|
||||
triangle approach is OK and works for polygons with rings.
|
||||
*/
|
||||
template<typename Polygon, typename Strategy>
|
||||
struct centroid_polygon_state
|
||||
{
|
||||
typedef typename ring_type<Polygon>::type ring_type;
|
||||
|
||||
static inline void apply(Polygon const& poly,
|
||||
Strategy const& strategy, typename Strategy::state_type& state)
|
||||
{
|
||||
typedef centroid_range_state
|
||||
<
|
||||
ring_type,
|
||||
geometry::closure<ring_type>::value,
|
||||
Strategy
|
||||
> per_ring;
|
||||
|
||||
per_ring::apply(exterior_ring(poly), strategy, state);
|
||||
|
||||
typename interior_return_type<Polygon const>::type rings
|
||||
= interior_rings(poly);
|
||||
for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
|
||||
{
|
||||
per_ring::apply(*it, strategy, state);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Polygon, typename Point, typename Strategy>
|
||||
struct centroid_polygon
|
||||
{
|
||||
static inline void apply(Polygon const& poly, Point& centroid,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
if (range_ok(exterior_ring(poly), centroid))
|
||||
{
|
||||
typename Strategy::state_type state;
|
||||
centroid_polygon_state
|
||||
<
|
||||
Polygon,
|
||||
Strategy
|
||||
>::apply(poly, strategy, state);
|
||||
Strategy::result(state, centroid);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::centroid
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag,
|
||||
typename Geometry,
|
||||
typename Point,
|
||||
typename Strategy
|
||||
>
|
||||
struct centroid {};
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Point,
|
||||
typename Strategy
|
||||
>
|
||||
struct centroid<point_tag, Geometry, Point, Strategy>
|
||||
: detail::centroid::centroid_point<Geometry, Point, Strategy>
|
||||
{};
|
||||
|
||||
template
|
||||
<
|
||||
typename Box,
|
||||
typename Point,
|
||||
typename Strategy
|
||||
>
|
||||
struct centroid<box_tag, Box, Point, Strategy>
|
||||
: detail::centroid::centroid_box<Box, Point, Strategy>
|
||||
{};
|
||||
|
||||
template <typename Ring, typename Point, typename Strategy>
|
||||
struct centroid<ring_tag, Ring, Point, Strategy>
|
||||
: detail::centroid::centroid_range
|
||||
<
|
||||
Ring,
|
||||
Point,
|
||||
geometry::closure<Ring>::value,
|
||||
Strategy
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename Linestring, typename Point, typename Strategy>
|
||||
struct centroid<linestring_tag, Linestring, Point, Strategy>
|
||||
: detail::centroid::centroid_range
|
||||
<
|
||||
Linestring,
|
||||
Point,
|
||||
closed,
|
||||
Strategy
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename Polygon, typename Point, typename Strategy>
|
||||
struct centroid<polygon_tag, Polygon, Point, Strategy>
|
||||
: detail::centroid::centroid_polygon<Polygon, Point, Strategy>
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc{centroid} \brief_strategy
|
||||
\ingroup centroid
|
||||
\details \details_calc{centroid,geometric center (or: center of mass)}. \details_strategy_reasons
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Point \tparam_point
|
||||
\tparam Strategy \tparam_strategy{Centroid}
|
||||
\param geometry \param_geometry
|
||||
\param c \param_point \param_set{centroid}
|
||||
\param strategy \param_strategy{centroid}
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{[include reference/algorithms/centroid.qbk]}
|
||||
\qbk{[include reference/algorithms/centroid_strategies.qbk]}
|
||||
}
|
||||
|
||||
*/
|
||||
template<typename Geometry, typename Point, typename Strategy>
|
||||
inline void centroid(Geometry const& geometry, Point& c,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
//BOOST_CONCEPT_ASSERT( (geometry::concept::CentroidStrategy<Strategy>) );
|
||||
|
||||
concept::check_concepts_and_equal_dimensions<Point, Geometry const>();
|
||||
|
||||
typedef typename point_type<Geometry>::type point_type;
|
||||
|
||||
// Call dispatch apply method. That one returns true if centroid
|
||||
// should be taken from state.
|
||||
dispatch::centroid
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
Point,
|
||||
Strategy
|
||||
>::apply(geometry, c, strategy);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc{centroid}
|
||||
\ingroup centroid
|
||||
\details \details_calc{centroid,geometric center (or: center of mass)}. \details_default_strategy
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Point \tparam_point
|
||||
\param geometry \param_geometry
|
||||
\param c The calculated centroid will be assigned to this point reference
|
||||
|
||||
\qbk{[include reference/algorithms/centroid.qbk]}
|
||||
\qbk{
|
||||
[heading Example]
|
||||
[centroid]
|
||||
[centroid_output]
|
||||
}
|
||||
*/
|
||||
template<typename Geometry, typename Point>
|
||||
inline void centroid(Geometry const& geometry, Point& c)
|
||||
{
|
||||
concept::check_concepts_and_equal_dimensions<Point, Geometry const>();
|
||||
|
||||
typedef typename strategy::centroid::services::default_strategy
|
||||
<
|
||||
typename cs_tag<Geometry>::type,
|
||||
typename tag_cast
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
pointlike_tag,
|
||||
linear_tag,
|
||||
areal_tag
|
||||
>::type,
|
||||
dimension<Geometry>::type::value,
|
||||
Point,
|
||||
Geometry
|
||||
>::type strategy_type;
|
||||
|
||||
centroid(geometry, c, strategy_type());
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc{centroid}
|
||||
\ingroup centroid
|
||||
\details \details_calc{centroid,geometric center (or: center of mass)}. \details_return{centroid}.
|
||||
\tparam Point \tparam_point
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry
|
||||
\return \return_calc{centroid}
|
||||
|
||||
\qbk{[include reference/algorithms/centroid.qbk]}
|
||||
*/
|
||||
template<typename Point, typename Geometry>
|
||||
inline Point return_centroid(Geometry const& geometry)
|
||||
{
|
||||
concept::check_concepts_and_equal_dimensions<Point, Geometry const>();
|
||||
|
||||
Point c;
|
||||
centroid(geometry, c);
|
||||
return c;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief \brief_calc{centroid} \brief_strategy
|
||||
\ingroup centroid
|
||||
\details \details_calc{centroid,geometric center (or: center of mass)}. \details_return{centroid}. \details_strategy_reasons
|
||||
\tparam Point \tparam_point
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Strategy \tparam_strategy{centroid}
|
||||
\param geometry \param_geometry
|
||||
\param strategy \param_strategy{centroid}
|
||||
\return \return_calc{centroid}
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{[include reference/algorithms/centroid.qbk]}
|
||||
\qbk{[include reference/algorithms/centroid_strategies.qbk]}
|
||||
*/
|
||||
template<typename Point, typename Geometry, typename Strategy>
|
||||
inline Point return_centroid(Geometry const& geometry, Strategy const& strategy)
|
||||
{
|
||||
//BOOST_CONCEPT_ASSERT( (geometry::concept::CentroidStrategy<Strategy>) );
|
||||
|
||||
concept::check_concepts_and_equal_dimensions<Point, Geometry const>();
|
||||
|
||||
Point c;
|
||||
centroid(geometry, c, strategy);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_CENTROID_HPP
|
||||
159
test/external/boost/geometry/algorithms/clear.hpp
vendored
Normal file
159
test/external/boost/geometry/algorithms/clear.hpp
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_CLEAR_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_CLEAR_HPP
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/mutable_range.hpp>
|
||||
#include <boost/geometry/core/tag_cast.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace clear
|
||||
{
|
||||
|
||||
template <typename Geometry>
|
||||
struct collection_clear
|
||||
{
|
||||
static inline void apply(Geometry& geometry)
|
||||
{
|
||||
traits::clear<Geometry>::apply(geometry);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Polygon>
|
||||
struct polygon_clear
|
||||
{
|
||||
static inline void apply(Polygon& polygon)
|
||||
{
|
||||
traits::clear
|
||||
<
|
||||
typename boost::remove_reference
|
||||
<
|
||||
typename traits::interior_mutable_type<Polygon>::type
|
||||
>::type
|
||||
>::apply(interior_rings(polygon));
|
||||
traits::clear
|
||||
<
|
||||
typename boost::remove_reference
|
||||
<
|
||||
typename traits::ring_mutable_type<Polygon>::type
|
||||
>::type
|
||||
>::apply(exterior_ring(polygon));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct no_action
|
||||
{
|
||||
static inline void apply(Geometry& )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::clear
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template <typename Tag, typename Geometry>
|
||||
struct clear
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
|
||||
, (types<Geometry>)
|
||||
);
|
||||
};
|
||||
|
||||
// Point/box/segment do not have clear. So specialize to do nothing.
|
||||
template <typename Geometry>
|
||||
struct clear<point_tag, Geometry>
|
||||
: detail::clear::no_action<Geometry>
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct clear<box_tag, Geometry>
|
||||
: detail::clear::no_action<Geometry>
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct clear<segment_tag, Geometry>
|
||||
: detail::clear::no_action<Geometry>
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct clear<linestring_tag, Geometry>
|
||||
: detail::clear::collection_clear<Geometry>
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct clear<ring_tag, Geometry>
|
||||
: detail::clear::collection_clear<Geometry>
|
||||
{};
|
||||
|
||||
|
||||
// Polygon can (indirectly) use std for clear
|
||||
template <typename Polygon>
|
||||
struct clear<polygon_tag, Polygon>
|
||||
: detail::clear::polygon_clear<Polygon>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief Clears a linestring, ring or polygon (exterior+interiors) or multi*
|
||||
\details Generic function to clear a geometry. All points will be removed from the collection or collections
|
||||
making up the geometry. In most cases this is equivalent to the .clear() method of a std::vector<...>. In
|
||||
the case of a polygon, this clear functionality is automatically called for the exterior ring, and for the
|
||||
interior ring collection. In the case of a point, boxes and segments, nothing will happen.
|
||||
\ingroup clear
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry which will be cleared
|
||||
\note points and boxes cannot be cleared, instead they can be set to zero by "assign_zero"
|
||||
|
||||
\qbk{[include reference/algorithms/clear.qbk]}
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline void clear(Geometry& geometry)
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
dispatch::clear
|
||||
<
|
||||
typename tag_cast<typename tag<Geometry>::type, multi_tag>::type,
|
||||
Geometry
|
||||
>::apply(geometry);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_CLEAR_HPP
|
||||
74
test/external/boost/geometry/algorithms/comparable_distance.hpp
vendored
Normal file
74
test/external/boost/geometry/algorithms/comparable_distance.hpp
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_COMPARABLE_DISTANCE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_COMPARABLE_DISTANCE_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/algorithms/distance.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc2{comparable distance measurement}
|
||||
\ingroup distance
|
||||
\details The free function comparable_distance does not necessarily calculate the distance,
|
||||
but it calculates a distance measure such that two distances are comparable to each other.
|
||||
For example: for the Cartesian coordinate system, Pythagoras is used but the square root
|
||||
is not taken, which makes it faster and the results of two point pairs can still be
|
||||
compared to each other.
|
||||
\tparam Geometry1 first geometry type
|
||||
\tparam Geometry2 second geometry type
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\return \return_calc{comparable distance}
|
||||
|
||||
\qbk{[include reference/algorithms/comparable_distance.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline typename default_distance_result<Geometry1, Geometry2>::type comparable_distance(
|
||||
Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
typedef typename point_type<Geometry1>::type point1_type;
|
||||
typedef typename point_type<Geometry2>::type point2_type;
|
||||
|
||||
// Define a point-point-distance-strategy
|
||||
// for either the normal case, either the reversed case
|
||||
|
||||
typedef typename strategy::distance::services::comparable_type
|
||||
<
|
||||
typename boost::mpl::if_c
|
||||
<
|
||||
geometry::reverse_dispatch
|
||||
<Geometry1, Geometry2>::type::value,
|
||||
typename strategy::distance::services::default_strategy
|
||||
<point_tag, point2_type, point1_type>::type,
|
||||
typename strategy::distance::services::default_strategy
|
||||
<point_tag, point1_type, point2_type>::type
|
||||
>::type
|
||||
>::type strategy_type;
|
||||
|
||||
return distance(geometry1, geometry2, strategy_type());
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_COMPARABLE_DISTANCE_HPP
|
||||
400
test/external/boost/geometry/algorithms/convert.hpp
vendored
Normal file
400
test/external/boost/geometry/algorithms/convert.hpp
vendored
Normal file
@@ -0,0 +1,400 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_CONVERT_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_CONVERT_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/type_traits/is_array.hpp>
|
||||
|
||||
#include <boost/geometry/arithmetic/arithmetic.hpp>
|
||||
#include <boost/geometry/algorithms/append.hpp>
|
||||
#include <boost/geometry/algorithms/clear.hpp>
|
||||
#include <boost/geometry/algorithms/for_each.hpp>
|
||||
#include <boost/geometry/algorithms/detail/assign_values.hpp>
|
||||
#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
|
||||
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
|
||||
|
||||
#include <boost/geometry/views/closeable_view.hpp>
|
||||
#include <boost/geometry/views/reversible_view.hpp>
|
||||
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/point_order.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace conversion
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename Box,
|
||||
std::size_t Index,
|
||||
std::size_t Dimension,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct point_to_box
|
||||
{
|
||||
static inline void apply(Point const& point, Box& box)
|
||||
{
|
||||
typedef typename coordinate_type<Box>::type coordinate_type;
|
||||
|
||||
set<Index, Dimension>(box,
|
||||
boost::numeric_cast<coordinate_type>(get<Dimension>(point)));
|
||||
point_to_box
|
||||
<
|
||||
Point, Box,
|
||||
Index, Dimension + 1, DimensionCount
|
||||
>::apply(point, box);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename Box,
|
||||
std::size_t Index,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct point_to_box<Point, Box, Index, DimensionCount, DimensionCount>
|
||||
{
|
||||
static inline void apply(Point const& , Box& )
|
||||
{}
|
||||
};
|
||||
|
||||
template <typename Box, typename Range, bool Close, bool Reverse>
|
||||
struct box_to_range
|
||||
{
|
||||
static inline void apply(Box const& box, Range& range)
|
||||
{
|
||||
traits::resize<Range>::apply(range, Close ? 5 : 4);
|
||||
assign_box_corners_oriented<Reverse>(box, range);
|
||||
if (Close)
|
||||
{
|
||||
range[4] = range[0];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Segment, typename Range>
|
||||
struct segment_to_range
|
||||
{
|
||||
static inline void apply(Segment const& segment, Range& range)
|
||||
{
|
||||
traits::resize<Range>::apply(range, 2);
|
||||
|
||||
typename boost::range_iterator<Range>::type it = boost::begin(range);
|
||||
|
||||
assign_point_from_index<0>(segment, *it);
|
||||
++it;
|
||||
assign_point_from_index<1>(segment, *it);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Range1,
|
||||
typename Range2,
|
||||
bool Reverse = false
|
||||
>
|
||||
struct range_to_range
|
||||
{
|
||||
typedef typename reversible_view
|
||||
<
|
||||
Range1 const,
|
||||
Reverse ? iterate_reverse : iterate_forward
|
||||
>::type rview_type;
|
||||
typedef typename closeable_view
|
||||
<
|
||||
rview_type const,
|
||||
geometry::closure<Range1>::value
|
||||
>::type view_type;
|
||||
|
||||
static inline void apply(Range1 const& source, Range2& destination)
|
||||
{
|
||||
geometry::clear(destination);
|
||||
|
||||
rview_type rview(source);
|
||||
|
||||
// We consider input always as closed, and skip last
|
||||
// point for open output.
|
||||
view_type view(rview);
|
||||
|
||||
int n = boost::size(view);
|
||||
if (geometry::closure<Range2>::value == geometry::open)
|
||||
{
|
||||
n--;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (typename boost::range_iterator<view_type const>::type it
|
||||
= boost::begin(view);
|
||||
it != boost::end(view) && i < n;
|
||||
++it, ++i)
|
||||
{
|
||||
geometry::append(destination, *it);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Polygon1, typename Polygon2>
|
||||
struct polygon_to_polygon
|
||||
{
|
||||
typedef range_to_range
|
||||
<
|
||||
typename geometry::ring_type<Polygon1>::type,
|
||||
typename geometry::ring_type<Polygon2>::type,
|
||||
geometry::point_order<Polygon1>::value
|
||||
!= geometry::point_order<Polygon2>::value
|
||||
> per_ring;
|
||||
|
||||
static inline void apply(Polygon1 const& source, Polygon2& destination)
|
||||
{
|
||||
// Clearing managed per ring, and in the resizing of interior rings
|
||||
|
||||
per_ring::apply(geometry::exterior_ring(source),
|
||||
geometry::exterior_ring(destination));
|
||||
|
||||
// Container should be resizeable
|
||||
traits::resize
|
||||
<
|
||||
typename boost::remove_reference
|
||||
<
|
||||
typename traits::interior_mutable_type<Polygon2>::type
|
||||
>::type
|
||||
>::apply(interior_rings(destination), num_interior_rings(source));
|
||||
|
||||
typename interior_return_type<Polygon1 const>::type rings_source
|
||||
= interior_rings(source);
|
||||
typename interior_return_type<Polygon2>::type rings_dest
|
||||
= interior_rings(destination);
|
||||
|
||||
BOOST_AUTO_TPL(it_source, boost::begin(rings_source));
|
||||
BOOST_AUTO_TPL(it_dest, boost::begin(rings_dest));
|
||||
|
||||
for ( ; it_source != boost::end(rings_source); ++it_source, ++it_dest)
|
||||
{
|
||||
per_ring::apply(*it_source, *it_dest);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::conversion
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
bool UseAssignment,
|
||||
typename Tag1, typename Tag2,
|
||||
std::size_t DimensionCount,
|
||||
typename Geometry1, typename Geometry2
|
||||
>
|
||||
struct convert
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPES
|
||||
, (types<Geometry1, Geometry2>)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag,
|
||||
std::size_t DimensionCount,
|
||||
typename Geometry1, typename Geometry2
|
||||
>
|
||||
struct convert<true, Tag, Tag, DimensionCount, Geometry1, Geometry2>
|
||||
{
|
||||
// Same geometry type -> copy whole geometry
|
||||
static inline void apply(Geometry1 const& source, Geometry2& destination)
|
||||
{
|
||||
destination = source;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
std::size_t DimensionCount,
|
||||
typename Geometry1, typename Geometry2
|
||||
>
|
||||
struct convert<false, point_tag, point_tag, DimensionCount, Geometry1, Geometry2>
|
||||
: detail::conversion::point_to_point<Geometry1, Geometry2, 0, DimensionCount>
|
||||
{};
|
||||
|
||||
template <std::size_t DimensionCount, typename Segment, typename LineString>
|
||||
struct convert<false, segment_tag, linestring_tag, DimensionCount, Segment, LineString>
|
||||
: detail::conversion::segment_to_range<Segment, LineString>
|
||||
{};
|
||||
|
||||
|
||||
template <std::size_t DimensionCount, typename Ring1, typename Ring2>
|
||||
struct convert<false, ring_tag, ring_tag, DimensionCount, Ring1, Ring2>
|
||||
: detail::conversion::range_to_range
|
||||
<
|
||||
Ring1,
|
||||
Ring2,
|
||||
geometry::point_order<Ring1>::value
|
||||
!= geometry::point_order<Ring2>::value
|
||||
>
|
||||
{};
|
||||
|
||||
template <std::size_t DimensionCount, typename LineString1, typename LineString2>
|
||||
struct convert<false, linestring_tag, linestring_tag, DimensionCount, LineString1, LineString2>
|
||||
: detail::conversion::range_to_range<LineString1, LineString2>
|
||||
{};
|
||||
|
||||
template <std::size_t DimensionCount, typename Polygon1, typename Polygon2>
|
||||
struct convert<false, polygon_tag, polygon_tag, DimensionCount, Polygon1, Polygon2>
|
||||
: detail::conversion::polygon_to_polygon<Polygon1, Polygon2>
|
||||
{};
|
||||
|
||||
template <typename Box, typename Ring>
|
||||
struct convert<false, box_tag, ring_tag, 2, Box, Ring>
|
||||
: detail::conversion::box_to_range
|
||||
<
|
||||
Box,
|
||||
Ring,
|
||||
geometry::closure<Ring>::value == closed,
|
||||
geometry::point_order<Ring>::value == counterclockwise
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Box, typename Polygon>
|
||||
struct convert<false, box_tag, polygon_tag, 2, Box, Polygon>
|
||||
{
|
||||
static inline void apply(Box const& box, Polygon& polygon)
|
||||
{
|
||||
typedef typename ring_type<Polygon>::type ring_type;
|
||||
|
||||
convert
|
||||
<
|
||||
false, box_tag, ring_tag,
|
||||
2, Box, ring_type
|
||||
>::apply(box, exterior_ring(polygon));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Point, std::size_t DimensionCount, typename Box>
|
||||
struct convert<false, point_tag, box_tag, DimensionCount, Point, Box>
|
||||
{
|
||||
static inline void apply(Point const& point, Box& box)
|
||||
{
|
||||
detail::conversion::point_to_box
|
||||
<
|
||||
Point, Box, min_corner, 0, DimensionCount
|
||||
>::apply(point, box);
|
||||
detail::conversion::point_to_box
|
||||
<
|
||||
Point, Box, max_corner, 0, DimensionCount
|
||||
>::apply(point, box);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Ring, std::size_t DimensionCount, typename Polygon>
|
||||
struct convert<false, ring_tag, polygon_tag, DimensionCount, Ring, Polygon>
|
||||
{
|
||||
static inline void apply(Ring const& ring, Polygon& polygon)
|
||||
{
|
||||
typedef typename ring_type<Polygon>::type ring_type;
|
||||
convert
|
||||
<
|
||||
false, ring_tag, ring_tag, DimensionCount,
|
||||
Ring, ring_type
|
||||
>::apply(ring, exterior_ring(polygon));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Polygon, std::size_t DimensionCount, typename Ring>
|
||||
struct convert<false, polygon_tag, ring_tag, DimensionCount, Polygon, Ring>
|
||||
{
|
||||
static inline void apply(Polygon const& polygon, Ring& ring)
|
||||
{
|
||||
typedef typename ring_type<Polygon>::type ring_type;
|
||||
|
||||
convert
|
||||
<
|
||||
false,
|
||||
ring_tag, ring_tag, DimensionCount,
|
||||
ring_type, Ring
|
||||
>::apply(exterior_ring(polygon), ring);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief Converts one geometry to another geometry
|
||||
\details The convert algorithm converts one geometry, e.g. a BOX, to another
|
||||
geometry, e.g. a RING. This only if it is possible and applicable.
|
||||
If the point-order is different, or the closure is different between two
|
||||
geometry types, it will be converted correctly by explicitly reversing the
|
||||
points or closing or opening the polygon rings.
|
||||
\ingroup convert
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry (source)
|
||||
\param geometry2 \param_geometry (target)
|
||||
|
||||
\qbk{[include reference/algorithms/convert.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline void convert(Geometry1 const& geometry1, Geometry2& geometry2)
|
||||
{
|
||||
concept::check_concepts_and_equal_dimensions<Geometry1 const, Geometry2>();
|
||||
|
||||
dispatch::convert
|
||||
<
|
||||
boost::is_same<Geometry1, Geometry2>::value
|
||||
// && boost::has_assign<Geometry2>::value, -- type traits extensions
|
||||
&& ! boost::is_array<Geometry1>::value,
|
||||
typename tag_cast<typename tag<Geometry1>::type, multi_tag>::type,
|
||||
typename tag_cast<typename tag<Geometry2>::type, multi_tag>::type,
|
||||
dimension<Geometry1>::type::value,
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply(geometry1, geometry2);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_CONVERT_HPP
|
||||
247
test/external/boost/geometry/algorithms/convex_hull.hpp
vendored
Normal file
247
test/external/boost/geometry/algorithms/convex_hull.hpp
vendored
Normal file
@@ -0,0 +1,247 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_CONVEX_HULL_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_CONVEX_HULL_HPP
|
||||
|
||||
|
||||
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/point_order.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/convex_hull.hpp>
|
||||
#include <boost/geometry/strategies/concepts/convex_hull_concept.hpp>
|
||||
|
||||
#include <boost/geometry/views/detail/range_type.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/as_range.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace convex_hull
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
order_selector Order,
|
||||
typename Strategy
|
||||
>
|
||||
struct hull_insert
|
||||
{
|
||||
|
||||
// Member template function (to avoid inconvenient declaration
|
||||
// of output-iterator-type, from hull_to_geometry)
|
||||
template <typename OutputIterator>
|
||||
static inline OutputIterator apply(Geometry const& geometry,
|
||||
OutputIterator out, Strategy const& strategy)
|
||||
{
|
||||
typename Strategy::state_type state;
|
||||
|
||||
strategy.apply(geometry, state);
|
||||
strategy.result(state, out, Order == clockwise);
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename OutputGeometry,
|
||||
typename Strategy
|
||||
>
|
||||
struct hull_to_geometry
|
||||
{
|
||||
static inline void apply(Geometry const& geometry, OutputGeometry& out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
hull_insert
|
||||
<
|
||||
Geometry,
|
||||
geometry::point_order<OutputGeometry>::value,
|
||||
Strategy
|
||||
>::apply(geometry,
|
||||
std::back_inserter(
|
||||
// Handle linestring, ring and polygon the same:
|
||||
detail::as_range
|
||||
<
|
||||
typename range_type<OutputGeometry>::type
|
||||
>(out)), strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::convex_hull
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag1,
|
||||
typename Geometry,
|
||||
typename Output,
|
||||
typename Strategy
|
||||
>
|
||||
struct convex_hull
|
||||
: detail::convex_hull::hull_to_geometry<Geometry, Output, Strategy>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryTag,
|
||||
order_selector Order,
|
||||
typename GeometryIn, typename Strategy
|
||||
>
|
||||
struct convex_hull_insert
|
||||
: detail::convex_hull::hull_insert<GeometryIn, Order, Strategy>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
template<typename Geometry1, typename Geometry2, typename Strategy>
|
||||
inline void convex_hull(Geometry1 const& geometry,
|
||||
Geometry2& out, Strategy const& strategy)
|
||||
{
|
||||
concept::check_concepts_and_equal_dimensions
|
||||
<
|
||||
const Geometry1,
|
||||
Geometry2
|
||||
>();
|
||||
|
||||
BOOST_CONCEPT_ASSERT( (geometry::concept::ConvexHullStrategy<Strategy>) );
|
||||
|
||||
|
||||
dispatch::convex_hull
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
Strategy
|
||||
>::apply(geometry, out, strategy);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc{convex hull}
|
||||
\ingroup convex_hull
|
||||
\details \details_calc{convex_hull,convex hull}.
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry \param_geometry, input geometry
|
||||
\param hull \param_geometry \param_set{convex hull}
|
||||
|
||||
\qbk{[include reference/algorithms/convex_hull.qbk]}
|
||||
*/
|
||||
template<typename Geometry1, typename Geometry2>
|
||||
inline void convex_hull(Geometry1 const& geometry,
|
||||
Geometry2& hull)
|
||||
{
|
||||
concept::check_concepts_and_equal_dimensions
|
||||
<
|
||||
const Geometry1,
|
||||
Geometry2
|
||||
>();
|
||||
|
||||
typedef typename point_type<Geometry2>::type point_type;
|
||||
|
||||
typedef typename strategy_convex_hull
|
||||
<
|
||||
typename cs_tag<point_type>::type,
|
||||
Geometry1,
|
||||
point_type
|
||||
>::type strategy_type;
|
||||
|
||||
convex_hull(geometry, hull, strategy_type());
|
||||
}
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace convex_hull
|
||||
{
|
||||
|
||||
|
||||
template<typename Geometry, typename OutputIterator, typename Strategy>
|
||||
inline OutputIterator convex_hull_insert(Geometry const& geometry,
|
||||
OutputIterator out, Strategy const& strategy)
|
||||
{
|
||||
// Concept: output point type = point type of input geometry
|
||||
concept::check<Geometry const>();
|
||||
concept::check<typename point_type<Geometry>::type>();
|
||||
|
||||
BOOST_CONCEPT_ASSERT( (geometry::concept::ConvexHullStrategy<Strategy>) );
|
||||
|
||||
return dispatch::convex_hull_insert
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
geometry::point_order<Geometry>::value,
|
||||
Geometry, Strategy
|
||||
>::apply(geometry, out, strategy);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Calculate the convex hull of a geometry, output-iterator version
|
||||
\ingroup convex_hull
|
||||
\tparam Geometry the input geometry type
|
||||
\tparam OutputIterator: an output-iterator
|
||||
\param geometry the geometry to calculate convex hull from
|
||||
\param out an output iterator outputing points of the convex hull
|
||||
\note This overloaded version outputs to an output iterator.
|
||||
In this case, nothing is known about its point-type or
|
||||
about its clockwise order. Therefore, the input point-type
|
||||
and order are copied
|
||||
|
||||
*/
|
||||
template<typename Geometry, typename OutputIterator>
|
||||
inline OutputIterator convex_hull_insert(Geometry const& geometry,
|
||||
OutputIterator out)
|
||||
{
|
||||
// Concept: output point type = point type of input geometry
|
||||
concept::check<Geometry const>();
|
||||
concept::check<typename point_type<Geometry>::type>();
|
||||
|
||||
typedef typename point_type<Geometry>::type point_type;
|
||||
|
||||
typedef typename strategy_convex_hull
|
||||
<
|
||||
typename cs_tag<point_type>::type,
|
||||
Geometry,
|
||||
point_type
|
||||
>::type strategy_type;
|
||||
|
||||
return convex_hull_insert(geometry, out, strategy_type());
|
||||
}
|
||||
|
||||
|
||||
}} // namespace detail::convex_hull
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_CONVEX_HULL_HPP
|
||||
270
test/external/boost/geometry/algorithms/correct.hpp
vendored
Normal file
270
test/external/boost/geometry/algorithms/correct.hpp
vendored
Normal file
@@ -0,0 +1,270 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_CORRECT_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_CORRECT_HPP
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/mutable_range.hpp>
|
||||
#include <boost/geometry/core/ring_type.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/area.hpp>
|
||||
#include <boost/geometry/algorithms/disjoint.hpp>
|
||||
#include <boost/geometry/util/order_as_direction.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace correct
|
||||
{
|
||||
|
||||
template <typename Geometry>
|
||||
struct correct_nop
|
||||
{
|
||||
static inline void apply(Geometry& )
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
template <typename Box, std::size_t Dimension, std::size_t DimensionCount>
|
||||
struct correct_box_loop
|
||||
{
|
||||
typedef typename coordinate_type<Box>::type coordinate_type;
|
||||
|
||||
static inline void apply(Box& box)
|
||||
{
|
||||
if (get<min_corner, Dimension>(box) > get<max_corner, Dimension>(box))
|
||||
{
|
||||
// Swap the coordinates
|
||||
coordinate_type max_value = get<min_corner, Dimension>(box);
|
||||
coordinate_type min_value = get<max_corner, Dimension>(box);
|
||||
set<min_corner, Dimension>(box, min_value);
|
||||
set<max_corner, Dimension>(box, max_value);
|
||||
}
|
||||
|
||||
correct_box_loop
|
||||
<
|
||||
Box, Dimension + 1, DimensionCount
|
||||
>::apply(box);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename Box, std::size_t DimensionCount>
|
||||
struct correct_box_loop<Box, DimensionCount, DimensionCount>
|
||||
{
|
||||
static inline void apply(Box& box)
|
||||
{}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Correct a box: make min/max correct
|
||||
template <typename Box>
|
||||
struct correct_box
|
||||
{
|
||||
|
||||
static inline void apply(Box& box)
|
||||
{
|
||||
// Currently only for Cartesian coordinates
|
||||
// (or spherical without crossing dateline)
|
||||
// Future version: adapt using strategies
|
||||
correct_box_loop
|
||||
<
|
||||
Box, 0, dimension<Box>::type::value
|
||||
>::apply(box);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Close a ring, if not closed
|
||||
template <typename Ring, typename Predicate>
|
||||
struct correct_ring
|
||||
{
|
||||
typedef typename point_type<Ring>::type point_type;
|
||||
typedef typename coordinate_type<Ring>::type coordinate_type;
|
||||
|
||||
typedef typename strategy::area::services::default_strategy
|
||||
<
|
||||
typename cs_tag<point_type>::type,
|
||||
point_type
|
||||
>::type strategy_type;
|
||||
|
||||
typedef detail::area::ring_area
|
||||
<
|
||||
Ring,
|
||||
order_as_direction<geometry::point_order<Ring>::value>::value,
|
||||
geometry::closure<Ring>::value,
|
||||
strategy_type
|
||||
> ring_area_type;
|
||||
|
||||
|
||||
static inline void apply(Ring& r)
|
||||
{
|
||||
// Check close-ness
|
||||
if (boost::size(r) > 2)
|
||||
{
|
||||
// check if closed, if not, close it
|
||||
bool const disjoint = geometry::disjoint(*boost::begin(r), *(boost::end(r) - 1));
|
||||
closure_selector const s = geometry::closure<Ring>::value;
|
||||
|
||||
if (disjoint && (s == closed))
|
||||
{
|
||||
geometry::append(r, *boost::begin(r));
|
||||
}
|
||||
if (! disjoint && geometry::closure<Ring>::value != closed)
|
||||
{
|
||||
// Open it by removing last point
|
||||
geometry::traits::resize<Ring>::apply(r, boost::size(r) - 1);
|
||||
}
|
||||
}
|
||||
// Check area
|
||||
Predicate predicate;
|
||||
coordinate_type const zero = 0;
|
||||
if (predicate(ring_area_type::apply(r, strategy_type()), zero))
|
||||
{
|
||||
std::reverse(boost::begin(r), boost::end(r));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Correct a polygon: normalizes all rings, sets outer ring clockwise, sets all
|
||||
// inner rings counter clockwise (or vice versa depending on orientation)
|
||||
template <typename Polygon>
|
||||
struct correct_polygon
|
||||
{
|
||||
typedef typename ring_type<Polygon>::type ring_type;
|
||||
typedef typename coordinate_type<Polygon>::type coordinate_type;
|
||||
|
||||
static inline void apply(Polygon& poly)
|
||||
{
|
||||
correct_ring
|
||||
<
|
||||
ring_type,
|
||||
std::less<coordinate_type>
|
||||
>::apply(exterior_ring(poly));
|
||||
|
||||
typename interior_return_type<Polygon>::type rings
|
||||
= interior_rings(poly);
|
||||
for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
|
||||
{
|
||||
correct_ring
|
||||
<
|
||||
ring_type,
|
||||
std::greater<coordinate_type>
|
||||
>::apply(*it);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::correct
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template <typename Tag, typename Geometry>
|
||||
struct correct
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
|
||||
, (types<Geometry>)
|
||||
);
|
||||
};
|
||||
|
||||
template <typename Point>
|
||||
struct correct<point_tag, Point>
|
||||
: detail::correct::correct_nop<Point>
|
||||
{};
|
||||
|
||||
template <typename LineString>
|
||||
struct correct<linestring_tag, LineString>
|
||||
: detail::correct::correct_nop<LineString>
|
||||
{};
|
||||
|
||||
template <typename Segment>
|
||||
struct correct<segment_tag, Segment>
|
||||
: detail::correct::correct_nop<Segment>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Box>
|
||||
struct correct<box_tag, Box>
|
||||
: detail::correct::correct_box<Box>
|
||||
{};
|
||||
|
||||
template <typename Ring>
|
||||
struct correct<ring_tag, Ring>
|
||||
: detail::correct::correct_ring
|
||||
<
|
||||
Ring,
|
||||
std::less<typename coordinate_type<Ring>::type>
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename Polygon>
|
||||
struct correct<polygon_tag, Polygon>
|
||||
: detail::correct::correct_polygon<Polygon>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief Corrects a geometry
|
||||
\details Corrects a geometry: all rings which are wrongly oriented with respect
|
||||
to their expected orientation are reversed. To all rings which do not have a
|
||||
closing point and are typed as they should have one, the first point is
|
||||
appended. Also boxes can be corrected.
|
||||
\ingroup correct
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry which will be corrected if necessary
|
||||
|
||||
\qbk{[include reference/algorithms/correct.qbk]}
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline void correct(Geometry& geometry)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
dispatch::correct<typename tag<Geometry>::type, Geometry>::apply(geometry);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_CORRECT_HPP
|
||||
206
test/external/boost/geometry/algorithms/covered_by.hpp
vendored
Normal file
206
test/external/boost/geometry/algorithms/covered_by.hpp
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
#include <boost/geometry/algorithms/within.hpp>
|
||||
|
||||
|
||||
#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
|
||||
#include <boost/geometry/strategies/cartesian/box_in_box.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag1,
|
||||
typename Tag2,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Strategy
|
||||
>
|
||||
struct covered_by
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
|
||||
, (types<Geometry1, Geometry2>)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
template <typename Point, typename Box, typename Strategy>
|
||||
struct covered_by<point_tag, box_tag, Point, Box, Strategy>
|
||||
{
|
||||
static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
|
||||
{
|
||||
return strategy.apply(point, box);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box1, typename Box2, typename Strategy>
|
||||
struct covered_by<box_tag, box_tag, Box1, Box2, Strategy>
|
||||
{
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
|
||||
{
|
||||
assert_dimension_equal<Box1, Box2>();
|
||||
return strategy.apply(box1, box2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename Point, typename Ring, typename Strategy>
|
||||
struct covered_by<point_tag, ring_tag, Point, Ring, Strategy>
|
||||
{
|
||||
static inline bool apply(Point const& point, Ring const& ring, Strategy const& strategy)
|
||||
{
|
||||
return detail::within::point_in_ring
|
||||
<
|
||||
Point,
|
||||
Ring,
|
||||
order_as_direction<geometry::point_order<Ring>::value>::value,
|
||||
geometry::closure<Ring>::value,
|
||||
Strategy
|
||||
>::apply(point, ring) >= 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Point, typename Polygon, typename Strategy>
|
||||
struct covered_by<point_tag, polygon_tag, Point, Polygon, Strategy>
|
||||
{
|
||||
static inline bool apply(Point const& point, Polygon const& polygon, Strategy const& strategy)
|
||||
{
|
||||
return detail::within::point_in_polygon
|
||||
<
|
||||
Point,
|
||||
Polygon,
|
||||
order_as_direction<geometry::point_order<Polygon>::value>::value,
|
||||
geometry::closure<Polygon>::value,
|
||||
Strategy
|
||||
>::apply(point, polygon, strategy) >= 0;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check12{is inside or on border}
|
||||
\ingroup covered_by
|
||||
\details \details_check12{covered_by, is inside or on border}.
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param geometry1 geometry which might be covered_by the second geometry
|
||||
\param geometry2 geometry which might contain the first geometry
|
||||
\return true if geometry1 is completely contained covered_by geometry2,
|
||||
else false
|
||||
\note The default strategy is used for covered_by detection
|
||||
|
||||
*/
|
||||
template<typename Geometry1, typename Geometry2>
|
||||
inline bool covered_by(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
assert_dimension_equal<Geometry1, Geometry2>();
|
||||
|
||||
typedef typename point_type<Geometry1>::type point_type1;
|
||||
typedef typename point_type<Geometry2>::type point_type2;
|
||||
|
||||
typedef typename strategy::covered_by::services::default_strategy
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
|
||||
typename tag_cast
|
||||
<
|
||||
typename cs_tag<point_type1>::type, spherical_tag
|
||||
>::type,
|
||||
typename tag_cast
|
||||
<
|
||||
typename cs_tag<point_type2>::type, spherical_tag
|
||||
>::type,
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
return dispatch::covered_by
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
strategy_type
|
||||
>::apply(geometry1, geometry2, strategy_type());
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief \brief_check12{is inside or on border} \brief_strategy
|
||||
\ingroup covered_by
|
||||
\details \details_check12{covered_by, is inside or on border}, \brief_strategy. \details_strategy_reasons
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param geometry1 \param_geometry geometry which might be covered_by the second geometry
|
||||
\param geometry2 \param_geometry which might contain the first geometry
|
||||
\param strategy strategy to be used
|
||||
\return true if geometry1 is completely contained covered_by geometry2,
|
||||
else false
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
|
||||
*/
|
||||
template<typename Geometry1, typename Geometry2, typename Strategy>
|
||||
inline bool covered_by(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concept::within::check
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
|
||||
Strategy
|
||||
>();
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
assert_dimension_equal<Geometry1, Geometry2>();
|
||||
|
||||
return dispatch::covered_by
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
Strategy
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP
|
||||
107
test/external/boost/geometry/algorithms/detail/as_range.hpp
vendored
Normal file
107
test/external/boost/geometry/algorithms/detail/as_range.hpp
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_AS_RANGE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_AS_RANGE_HPP
|
||||
|
||||
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/util/add_const_if_c.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename GeometryTag, typename Geometry, typename Range, bool IsConst>
|
||||
struct as_range
|
||||
{
|
||||
static inline typename add_const_if_c<IsConst, Range>::type& get(
|
||||
typename add_const_if_c<IsConst, Geometry>::type& input)
|
||||
{
|
||||
return input;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Geometry, typename Range, bool IsConst>
|
||||
struct as_range<polygon_tag, Geometry, Range, IsConst>
|
||||
{
|
||||
static inline typename add_const_if_c<IsConst, Range>::type& get(
|
||||
typename add_const_if_c<IsConst, Geometry>::type& input)
|
||||
{
|
||||
return exterior_ring(input);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
// Will probably be replaced by the more generic "view_as", therefore in detail
|
||||
namespace detail
|
||||
{
|
||||
|
||||
/*!
|
||||
\brief Function getting either the range (ring, linestring) itself
|
||||
or the outer ring (polygon)
|
||||
\details Utility to handle polygon's outer ring as a range
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Range, typename Geometry>
|
||||
inline Range& as_range(Geometry& input)
|
||||
{
|
||||
return dispatch::as_range
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
Range,
|
||||
false
|
||||
>::get(input);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Function getting either the range (ring, linestring) itself
|
||||
or the outer ring (polygon), const version
|
||||
\details Utility to handle polygon's outer ring as a range
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Range, typename Geometry>
|
||||
inline Range const& as_range(Geometry const& input)
|
||||
{
|
||||
return dispatch::as_range
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
Range,
|
||||
true
|
||||
>::get(input);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_AS_RANGE_HPP
|
||||
93
test/external/boost/geometry/algorithms/detail/assign_box_corners.hpp
vendored
Normal file
93
test/external/boost/geometry/algorithms/detail/assign_box_corners.hpp
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ASSIGN_BOX_CORNERS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ASSIGN_BOX_CORNERS_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/algorithms/detail/assign_values.hpp>
|
||||
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail
|
||||
{
|
||||
// Note: this is moved to namespace detail because the names and parameter orders
|
||||
// are not yet 100% clear.
|
||||
|
||||
/*!
|
||||
\brief Assign the four points of a 2D box
|
||||
\ingroup assign
|
||||
\note The order is crucial. Most logical is LOWER, UPPER and sub-order LEFT, RIGHT
|
||||
so this is how it is implemented.
|
||||
\tparam Box \tparam_box
|
||||
\tparam Point \tparam_point
|
||||
\param box \param_box
|
||||
\param lower_left point being assigned to lower left coordinates of the box
|
||||
\param lower_right point being assigned to lower right coordinates of the box
|
||||
\param upper_left point being assigned to upper left coordinates of the box
|
||||
\param upper_right point being assigned to upper right coordinates of the box
|
||||
|
||||
\qbk{
|
||||
[heading Example]
|
||||
[assign_box_corners] [assign_box_corners_output]
|
||||
}
|
||||
*/
|
||||
template <typename Box, typename Point>
|
||||
inline void assign_box_corners(Box const& box,
|
||||
Point& lower_left, Point& lower_right,
|
||||
Point& upper_left, Point& upper_right)
|
||||
{
|
||||
concept::check<Box const>();
|
||||
concept::check<Point>();
|
||||
|
||||
detail::assign::assign_box_2d_corner
|
||||
<min_corner, min_corner>(box, lower_left);
|
||||
detail::assign::assign_box_2d_corner
|
||||
<max_corner, min_corner>(box, lower_right);
|
||||
detail::assign::assign_box_2d_corner
|
||||
<min_corner, max_corner>(box, upper_left);
|
||||
detail::assign::assign_box_2d_corner
|
||||
<max_corner, max_corner>(box, upper_right);
|
||||
}
|
||||
|
||||
template <bool Reverse, typename Box, typename Range>
|
||||
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]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// make clockwise ll,ul,ur,lr
|
||||
assign_box_corners(box, corners[0], corners[3], corners[1], corners[2]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ASSIGN_BOX_CORNERS_HPP
|
||||
94
test/external/boost/geometry/algorithms/detail/assign_indexed_point.hpp
vendored
Normal file
94
test/external/boost/geometry/algorithms/detail/assign_indexed_point.hpp
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ASSIGN_INDEXED_POINT_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ASSIGN_INDEXED_POINT_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/algorithms/detail/assign_values.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail
|
||||
{
|
||||
|
||||
/*!
|
||||
\brief Assign a box or segment with the value of a point
|
||||
\ingroup assign
|
||||
\tparam Index indicates which box-corner, min_corner (0) or max_corner (1)
|
||||
or which point of segment (0/1)
|
||||
\tparam Point \tparam_point
|
||||
\tparam Geometry \tparam_box_or_segment
|
||||
\param point \param_point
|
||||
\param geometry \param_box_or_segment
|
||||
|
||||
\qbk{
|
||||
[heading Example]
|
||||
[assign_point_to_index] [assign_point_to_index_output]
|
||||
}
|
||||
*/
|
||||
template <std::size_t Index, typename Geometry, typename Point>
|
||||
inline void assign_point_to_index(Point const& point, Geometry& geometry)
|
||||
{
|
||||
concept::check<Point const>();
|
||||
concept::check<Geometry>();
|
||||
|
||||
detail::assign::assign_point_to_index
|
||||
<
|
||||
Geometry, Point, Index, 0, dimension<Geometry>::type::value
|
||||
>::apply(point, geometry);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Assign a point with a point of a box or segment
|
||||
\ingroup assign
|
||||
\tparam Index indicates which box-corner, min_corner (0) or max_corner (1)
|
||||
or which point of segment (0/1)
|
||||
\tparam Geometry \tparam_box_or_segment
|
||||
\tparam Point \tparam_point
|
||||
\param geometry \param_box_or_segment
|
||||
\param point \param_point
|
||||
|
||||
\qbk{
|
||||
[heading Example]
|
||||
[assign_point_from_index] [assign_point_from_index_output]
|
||||
}
|
||||
*/
|
||||
template <std::size_t Index, typename Point, typename Geometry>
|
||||
inline void assign_point_from_index(Geometry const& geometry, Point& point)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
concept::check<Point>();
|
||||
|
||||
detail::assign::assign_point_from_index
|
||||
<
|
||||
Geometry, Point, Index, 0, dimension<Geometry>::type::value
|
||||
>::apply(geometry, point);
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ASSIGN_INDEXED_POINT_HPP
|
||||
443
test/external/boost/geometry/algorithms/detail/assign_values.hpp
vendored
Normal file
443
test/external/boost/geometry/algorithms/detail/assign_values.hpp
vendored
Normal file
@@ -0,0 +1,443 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_ASSIGN_VALUES_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_ASSIGN_VALUES_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/concept/requires.hpp>
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/numeric/conversion/bounds.hpp>
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
#include <boost/geometry/arithmetic/arithmetic.hpp>
|
||||
#include <boost/geometry/algorithms/append.hpp>
|
||||
#include <boost/geometry/algorithms/clear.hpp>
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
|
||||
#include <boost/geometry/util/for_each_coordinate.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace assign
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Box, std::size_t Index,
|
||||
std::size_t Dimension, std::size_t DimensionCount
|
||||
>
|
||||
struct initialize
|
||||
{
|
||||
typedef typename coordinate_type<Box>::type coordinate_type;
|
||||
|
||||
static inline void apply(Box& box, coordinate_type const& value)
|
||||
{
|
||||
geometry::set<Index, Dimension>(box, value);
|
||||
initialize<Box, Index, Dimension + 1, DimensionCount>::apply(box, value);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Box, std::size_t Index, std::size_t DimensionCount>
|
||||
struct initialize<Box, Index, DimensionCount, DimensionCount>
|
||||
{
|
||||
typedef typename coordinate_type<Box>::type coordinate_type;
|
||||
|
||||
static inline void apply(Box&, coordinate_type const& )
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
template <typename Point>
|
||||
struct assign_zero_point
|
||||
{
|
||||
static inline void apply(Point& point)
|
||||
{
|
||||
geometry::assign_value(point, 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename BoxOrSegment>
|
||||
struct assign_inverse_box_or_segment
|
||||
{
|
||||
typedef typename point_type<BoxOrSegment>::type point_type;
|
||||
|
||||
static inline void apply(BoxOrSegment& geometry)
|
||||
{
|
||||
typedef typename coordinate_type<point_type>::type bound_type;
|
||||
|
||||
initialize
|
||||
<
|
||||
BoxOrSegment, 0, 0, dimension<BoxOrSegment>::type::value
|
||||
>::apply(
|
||||
geometry, boost::numeric::bounds<bound_type>::highest());
|
||||
initialize
|
||||
<
|
||||
BoxOrSegment, 1, 0, dimension<BoxOrSegment>::type::value
|
||||
>::apply(
|
||||
geometry, boost::numeric::bounds<bound_type>::lowest());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename BoxOrSegment>
|
||||
struct assign_zero_box_or_segment
|
||||
{
|
||||
static inline void apply(BoxOrSegment& geometry)
|
||||
{
|
||||
typedef typename coordinate_type<BoxOrSegment>::type coordinate_type;
|
||||
|
||||
initialize
|
||||
<
|
||||
BoxOrSegment, 0, 0, dimension<BoxOrSegment>::type::value
|
||||
>::apply(geometry, coordinate_type());
|
||||
initialize
|
||||
<
|
||||
BoxOrSegment, 1, 0, dimension<BoxOrSegment>::type::value
|
||||
>::apply(geometry, coordinate_type());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
std::size_t Corner1, std::size_t Corner2,
|
||||
typename Box, typename Point
|
||||
>
|
||||
inline void assign_box_2d_corner(Box const& box, Point& point)
|
||||
{
|
||||
// Be sure both are 2-Dimensional
|
||||
assert_dimension<Box, 2>();
|
||||
assert_dimension<Point, 2>();
|
||||
|
||||
// Copy coordinates
|
||||
typedef typename coordinate_type<Point>::type coordinate_type;
|
||||
|
||||
geometry::set<0>(point, boost::numeric_cast<coordinate_type>(get<Corner1, 0>(box)));
|
||||
geometry::set<1>(point, boost::numeric_cast<coordinate_type>(get<Corner2, 1>(box)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry, typename Point,
|
||||
std::size_t Index,
|
||||
std::size_t Dimension, std::size_t DimensionCount
|
||||
>
|
||||
struct assign_point_to_index
|
||||
{
|
||||
|
||||
static inline void apply(Point const& point, Geometry& geometry)
|
||||
{
|
||||
geometry::set<Index, Dimension>(geometry, boost::numeric_cast
|
||||
<
|
||||
typename coordinate_type<Geometry>::type
|
||||
>(geometry::get<Dimension>(point)));
|
||||
|
||||
assign_point_to_index
|
||||
<
|
||||
Geometry, Point, Index, Dimension + 1, DimensionCount
|
||||
>::apply(point, geometry);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry, typename Point,
|
||||
std::size_t Index,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct assign_point_to_index
|
||||
<
|
||||
Geometry, Point,
|
||||
Index,
|
||||
DimensionCount, DimensionCount
|
||||
>
|
||||
{
|
||||
static inline void apply(Point const& , Geometry& )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry, typename Point,
|
||||
std::size_t Index,
|
||||
std::size_t Dimension, std::size_t DimensionCount
|
||||
>
|
||||
struct assign_point_from_index
|
||||
{
|
||||
|
||||
static inline void apply(Geometry const& geometry, Point& point)
|
||||
{
|
||||
geometry::set<Dimension>( point, boost::numeric_cast
|
||||
<
|
||||
typename coordinate_type<Point>::type
|
||||
>(geometry::get<Index, Dimension>(geometry)));
|
||||
|
||||
assign_point_from_index
|
||||
<
|
||||
Geometry, Point, Index, Dimension + 1, DimensionCount
|
||||
>::apply(geometry, point);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry, typename Point,
|
||||
std::size_t Index,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct assign_point_from_index
|
||||
<
|
||||
Geometry, Point,
|
||||
Index,
|
||||
DimensionCount, DimensionCount
|
||||
>
|
||||
{
|
||||
static inline void apply(Geometry const&, Point&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Geometry>
|
||||
struct assign_2d_box_or_segment
|
||||
{
|
||||
typedef typename coordinate_type<Geometry>::type coordinate_type;
|
||||
|
||||
// Here we assign 4 coordinates to a box of segment
|
||||
// -> Most logical is: x1,y1,x2,y2
|
||||
// In case the user reverses x1/x2 or y1/y2, for a box, we could reverse them (THAT IS NOT IMPLEMENTED)
|
||||
|
||||
template <typename Type>
|
||||
static inline void apply(Geometry& geometry,
|
||||
Type const& x1, Type const& y1, Type const& x2, Type const& y2)
|
||||
{
|
||||
geometry::set<0, 0>(geometry, boost::numeric_cast<coordinate_type>(x1));
|
||||
geometry::set<0, 1>(geometry, boost::numeric_cast<coordinate_type>(y1));
|
||||
geometry::set<1, 0>(geometry, boost::numeric_cast<coordinate_type>(x2));
|
||||
geometry::set<1, 1>(geometry, boost::numeric_cast<coordinate_type>(y2));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::assign
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template <typename GeometryTag, typename Geometry, std::size_t DimensionCount>
|
||||
struct assign
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
|
||||
, (types<Geometry>)
|
||||
);
|
||||
};
|
||||
|
||||
template <typename Point>
|
||||
struct assign<point_tag, Point, 2>
|
||||
{
|
||||
typedef typename coordinate_type<Point>::type coordinate_type;
|
||||
|
||||
template <typename T>
|
||||
static inline void apply(Point& point, T const& c1, T const& c2)
|
||||
{
|
||||
set<0>(point, boost::numeric_cast<coordinate_type>(c1));
|
||||
set<1>(point, boost::numeric_cast<coordinate_type>(c2));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Point>
|
||||
struct assign<point_tag, Point, 3>
|
||||
{
|
||||
typedef typename coordinate_type<Point>::type coordinate_type;
|
||||
|
||||
template <typename T>
|
||||
static inline void apply(Point& point, T const& c1, T const& c2, T const& c3)
|
||||
{
|
||||
set<0>(point, boost::numeric_cast<coordinate_type>(c1));
|
||||
set<1>(point, boost::numeric_cast<coordinate_type>(c2));
|
||||
set<2>(point, boost::numeric_cast<coordinate_type>(c3));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box>
|
||||
struct assign<box_tag, Box, 2>
|
||||
: detail::assign::assign_2d_box_or_segment<Box>
|
||||
{};
|
||||
|
||||
template <typename Segment>
|
||||
struct assign<segment_tag, Segment, 2>
|
||||
: detail::assign::assign_2d_box_or_segment<Segment>
|
||||
{};
|
||||
|
||||
|
||||
|
||||
template <typename GeometryTag, typename Geometry>
|
||||
struct assign_zero {};
|
||||
|
||||
|
||||
template <typename Point>
|
||||
struct assign_zero<point_tag, Point>
|
||||
: detail::assign::assign_zero_point<Point>
|
||||
{};
|
||||
|
||||
template <typename Box>
|
||||
struct assign_zero<box_tag, Box>
|
||||
: detail::assign::assign_zero_box_or_segment<Box>
|
||||
{};
|
||||
|
||||
template <typename Segment>
|
||||
struct assign_zero<segment_tag, Segment>
|
||||
: detail::assign::assign_zero_box_or_segment<Segment>
|
||||
{};
|
||||
|
||||
|
||||
template <typename GeometryTag, typename Geometry>
|
||||
struct assign_inverse {};
|
||||
|
||||
template <typename Box>
|
||||
struct assign_inverse<box_tag, Box>
|
||||
: detail::assign::assign_inverse_box_or_segment<Box>
|
||||
{};
|
||||
|
||||
template <typename Segment>
|
||||
struct assign_inverse<segment_tag, Segment>
|
||||
: detail::assign::assign_inverse_box_or_segment<Segment>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief Assign two coordinates to a geometry (usually a 2D point)
|
||||
\ingroup assign
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Type \tparam_numeric to specify the coordinates
|
||||
\param geometry \param_geometry
|
||||
\param c1 \param_x
|
||||
\param c2 \param_y
|
||||
|
||||
\qbk{distinguish, 2 coordinate values}
|
||||
\qbk{
|
||||
[heading Example]
|
||||
[assign_2d_point] [assign_2d_point_output]
|
||||
|
||||
[heading See also]
|
||||
\* [link geometry.reference.algorithms.make.make_2_2_coordinate_values make]
|
||||
}
|
||||
*/
|
||||
template <typename Geometry, typename Type>
|
||||
inline void assign_values(Geometry& geometry, Type const& c1, Type const& c2)
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
dispatch::assign
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
geometry::dimension<Geometry>::type::value
|
||||
>::apply(geometry, c1, c2);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Assign three values to a geometry (usually a 3D point)
|
||||
\ingroup assign
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Type \tparam_numeric to specify the coordinates
|
||||
\param geometry \param_geometry
|
||||
\param c1 \param_x
|
||||
\param c2 \param_y
|
||||
\param c3 \param_z
|
||||
|
||||
\qbk{distinguish, 3 coordinate values}
|
||||
\qbk{
|
||||
[heading Example]
|
||||
[assign_3d_point] [assign_3d_point_output]
|
||||
|
||||
[heading See also]
|
||||
\* [link geometry.reference.algorithms.make.make_3_3_coordinate_values make]
|
||||
}
|
||||
*/
|
||||
template <typename Geometry, typename Type>
|
||||
inline void assign_values(Geometry& geometry,
|
||||
Type const& c1, Type const& c2, Type const& c3)
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
dispatch::assign
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
geometry::dimension<Geometry>::type::value
|
||||
>::apply(geometry, c1, c2, c3);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Assign four values to a geometry (usually a box or segment)
|
||||
\ingroup assign
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Type \tparam_numeric to specify the coordinates
|
||||
\param geometry \param_geometry
|
||||
\param c1 First coordinate (usually x1)
|
||||
\param c2 Second coordinate (usually y1)
|
||||
\param c3 Third coordinate (usually x2)
|
||||
\param c4 Fourth coordinate (usually y2)
|
||||
|
||||
\qbk{distinguish, 4 coordinate values}
|
||||
*/
|
||||
template <typename Geometry, typename Type>
|
||||
inline void assign_values(Geometry& geometry,
|
||||
Type const& c1, Type const& c2, Type const& c3, Type const& c4)
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
dispatch::assign
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
geometry::dimension<Geometry>::type::value
|
||||
>::apply(geometry, c1, c2, c3, c4);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_ASSIGN_VALUES_HPP
|
||||
38
test/external/boost/geometry/algorithms/detail/calculate_null.hpp
vendored
Normal file
38
test/external/boost/geometry/algorithms/detail/calculate_null.hpp
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_CALCULATE_NULL_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CALCULATE_NULL_HPP
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<typename ReturnType, typename Geometry, typename Strategy>
|
||||
struct calculate_null
|
||||
{
|
||||
static inline ReturnType apply(Geometry const& , Strategy const&)
|
||||
{
|
||||
return ReturnType();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CALCULATE_NULL_HPP
|
||||
64
test/external/boost/geometry/algorithms/detail/calculate_sum.hpp
vendored
Normal file
64
test/external/boost/geometry/algorithms/detail/calculate_sum.hpp
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_CALCULATE_SUM_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CALCULATE_SUM_HPP
|
||||
|
||||
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename ReturnType,
|
||||
typename Polygon,
|
||||
typename Strategy,
|
||||
typename Policy
|
||||
>
|
||||
class calculate_polygon_sum
|
||||
{
|
||||
template <typename Rings>
|
||||
static inline ReturnType sum_interior_rings(Rings const& rings, Strategy const& strategy)
|
||||
{
|
||||
ReturnType sum = ReturnType();
|
||||
for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
|
||||
{
|
||||
sum += Policy::apply(*it, strategy);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
public :
|
||||
static inline ReturnType apply(Polygon const& poly, Strategy const& strategy)
|
||||
{
|
||||
return Policy::apply(exterior_ring(poly), strategy)
|
||||
+ sum_interior_rings(interior_rings(poly), strategy)
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CALCULATE_SUM_HPP
|
||||
68
test/external/boost/geometry/algorithms/detail/convert_point_to_point.hpp
vendored
Normal file
68
test/external/boost/geometry/algorithms/detail/convert_point_to_point.hpp
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_CONVERT_POINT_TO_POINT_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CONVERT_POINT_TO_POINT_HPP
|
||||
|
||||
// Note: extracted from "convert.hpp" to avoid circular references convert/append
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace conversion
|
||||
{
|
||||
|
||||
|
||||
template <typename Source, typename Destination, std::size_t Dimension, std::size_t DimensionCount>
|
||||
struct point_to_point
|
||||
{
|
||||
static inline void apply(Source const& source, Destination& destination)
|
||||
{
|
||||
typedef typename coordinate_type<Destination>::type coordinate_type;
|
||||
|
||||
set<Dimension>(destination, boost::numeric_cast<coordinate_type>(get<Dimension>(source)));
|
||||
point_to_point<Source, Destination, Dimension + 1, DimensionCount>::apply(source, destination);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Source, typename Destination, std::size_t DimensionCount>
|
||||
struct point_to_point<Source, Destination, DimensionCount, DimensionCount>
|
||||
{
|
||||
static inline void apply(Source const& , Destination& )
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
template <typename Source, typename Destination>
|
||||
inline void convert_point_to_point(Source const& source, Destination& destination)
|
||||
{
|
||||
point_to_point<Source, Destination, 0, dimension<Destination>::value>::apply(source, destination);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}} // namespace detail::conversion
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CONVERT_POINT_TO_POINT_HPP
|
||||
225
test/external/boost/geometry/algorithms/detail/disjoint.hpp
vendored
Normal file
225
test/external/boost/geometry/algorithms/detail/disjoint.hpp
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_HPP
|
||||
|
||||
// Note: contrary to most files, the geometry::detail::disjoint namespace
|
||||
// is partly implemented in a separate file, to avoid circular references
|
||||
// disjoint -> get_turns -> disjoint
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/reverse_dispatch.hpp>
|
||||
|
||||
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace disjoint
|
||||
{
|
||||
|
||||
|
||||
struct disjoint_interrupt_policy
|
||||
{
|
||||
static bool const enabled = true;
|
||||
bool has_intersections;
|
||||
|
||||
inline disjoint_interrupt_policy()
|
||||
: has_intersections(false)
|
||||
{}
|
||||
|
||||
template <typename Range>
|
||||
inline bool apply(Range const& range)
|
||||
{
|
||||
// If there is any IP in the range, it is NOT disjoint
|
||||
if (boost::size(range) > 0)
|
||||
{
|
||||
has_intersections = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Point1, typename Point2,
|
||||
std::size_t Dimension, std::size_t DimensionCount
|
||||
>
|
||||
struct point_point
|
||||
{
|
||||
static inline bool apply(Point1 const& p1, Point2 const& p2)
|
||||
{
|
||||
if (! geometry::math::equals(get<Dimension>(p1), get<Dimension>(p2)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return point_point
|
||||
<
|
||||
Point1, Point2,
|
||||
Dimension + 1, DimensionCount
|
||||
>::apply(p1, p2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Point1, typename Point2, std::size_t DimensionCount>
|
||||
struct point_point<Point1, Point2, DimensionCount, DimensionCount>
|
||||
{
|
||||
static inline bool apply(Point1 const& , Point2 const& )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Point, typename Box,
|
||||
std::size_t Dimension, std::size_t DimensionCount
|
||||
>
|
||||
struct point_box
|
||||
{
|
||||
static inline bool apply(Point const& point, Box const& box)
|
||||
{
|
||||
if (get<Dimension>(point) < get<min_corner, Dimension>(box)
|
||||
|| get<Dimension>(point) > get<max_corner, Dimension>(box))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return point_box
|
||||
<
|
||||
Point, Box,
|
||||
Dimension + 1, DimensionCount
|
||||
>::apply(point, box);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Point, typename Box, std::size_t DimensionCount>
|
||||
struct point_box<Point, Box, DimensionCount, DimensionCount>
|
||||
{
|
||||
static inline bool apply(Point const& , Box const& )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1, typename Box2,
|
||||
std::size_t Dimension, std::size_t DimensionCount
|
||||
>
|
||||
struct box_box
|
||||
{
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2)
|
||||
{
|
||||
if (get<max_corner, Dimension>(box1) < get<min_corner, Dimension>(box2))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (get<min_corner, Dimension>(box1) > get<max_corner, Dimension>(box2))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return box_box
|
||||
<
|
||||
Box1, Box2,
|
||||
Dimension + 1, DimensionCount
|
||||
>::apply(box1, box2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Box1, typename Box2, std::size_t DimensionCount>
|
||||
struct box_box<Box1, Box2, DimensionCount, DimensionCount>
|
||||
{
|
||||
static inline bool apply(Box1 const& , Box2 const& )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Internal utility function to detect of boxes are disjoint
|
||||
\note Is used from other algorithms, declared separately
|
||||
to avoid circular references
|
||||
*/
|
||||
template <typename Box1, typename Box2>
|
||||
inline bool disjoint_box_box(Box1 const& box1, Box2 const& box2)
|
||||
{
|
||||
return box_box
|
||||
<
|
||||
Box1, Box2,
|
||||
0, dimension<Box1>::type::value
|
||||
>::apply(box1, box2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Internal utility function to detect of points are disjoint
|
||||
\note To avoid circular references
|
||||
*/
|
||||
template <typename Point1, typename Point2>
|
||||
inline bool disjoint_point_point(Point1 const& point1, Point2 const& point2)
|
||||
{
|
||||
return point_point
|
||||
<
|
||||
Point1, Point2,
|
||||
0, dimension<Point1>::type::value
|
||||
>::apply(point1, point2);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace detail::disjoint
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace equals
|
||||
{
|
||||
|
||||
/*!
|
||||
\brief Internal utility function to detect of points are disjoint
|
||||
\note To avoid circular references
|
||||
*/
|
||||
template <typename Point1, typename Point2>
|
||||
inline bool equals_point_point(Point1 const& point1, Point2 const& point2)
|
||||
{
|
||||
return ! detail::disjoint::disjoint_point_point(point1, point2);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace detail::equals
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_HPP
|
||||
315
test/external/boost/geometry/algorithms/detail/equals/collect_vectors.hpp
vendored
Normal file
315
test/external/boost/geometry/algorithms/detail/equals/collect_vectors.hpp
vendored
Normal file
@@ -0,0 +1,315 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_COLLECT_VECTORS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_COLLECT_VECTORS_HPP
|
||||
|
||||
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
|
||||
#include <boost/geometry/multi/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
// TODO: if Boost.LA of Emil Dotchevski is accepted, adapt this
|
||||
template <typename T>
|
||||
struct collected_vector
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
inline collected_vector()
|
||||
{}
|
||||
|
||||
inline collected_vector(T const& px, T const& py,
|
||||
T const& pdx, T const& pdy)
|
||||
: x(px)
|
||||
, y(py)
|
||||
, dx(pdx)
|
||||
, dy(pdy)
|
||||
, dx_0(T())
|
||||
, dy_0(T())
|
||||
{}
|
||||
|
||||
T x, y;
|
||||
T dx, dy;
|
||||
T dx_0, dy_0;
|
||||
|
||||
// For sorting
|
||||
inline bool operator<(collected_vector<T> const& other) const
|
||||
{
|
||||
if (math::equals(x, other.x))
|
||||
{
|
||||
if (math::equals(y, other.y))
|
||||
{
|
||||
if (math::equals(dx, other.dx))
|
||||
{
|
||||
return dy < other.dy;
|
||||
}
|
||||
return dx < other.dx;
|
||||
}
|
||||
return y < other.y;
|
||||
}
|
||||
return x < other.x;
|
||||
}
|
||||
|
||||
inline bool same_direction(collected_vector<T> const& other) const
|
||||
{
|
||||
// For high precision arithmetic, we have to be
|
||||
// more relaxed then using ==
|
||||
// Because 2/sqrt( (0,0)<->(2,2) ) == 1/sqrt( (0,0)<->(1,1) )
|
||||
// is not always true (at least, it is not for ttmath)
|
||||
return math::equals_with_epsilon(dx, other.dx)
|
||||
&& math::equals_with_epsilon(dy, other.dy);
|
||||
}
|
||||
|
||||
// For std::equals
|
||||
inline bool operator==(collected_vector<T> const& other) const
|
||||
{
|
||||
return math::equals(x, other.x)
|
||||
&& math::equals(y, other.y)
|
||||
&& same_direction(other);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace collect_vectors
|
||||
{
|
||||
|
||||
|
||||
template <typename Range, typename Collection>
|
||||
struct range_collect_vectors
|
||||
{
|
||||
typedef typename boost::range_value<Collection>::type item_type;
|
||||
typedef typename item_type::type calculation_type;
|
||||
|
||||
static inline void apply(Collection& collection, Range const& range)
|
||||
{
|
||||
if (boost::size(range) < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
typedef typename boost::range_iterator<Range const>::type iterator;
|
||||
|
||||
bool first = true;
|
||||
iterator it = boost::begin(range);
|
||||
|
||||
for (iterator prev = it++;
|
||||
it != boost::end(range);
|
||||
prev = it++)
|
||||
{
|
||||
typename boost::range_value<Collection>::type v;
|
||||
|
||||
v.x = get<0>(*prev);
|
||||
v.y = get<1>(*prev);
|
||||
v.dx = get<0>(*it) - v.x;
|
||||
v.dy = get<1>(*it) - v.y;
|
||||
v.dx_0 = v.dx;
|
||||
v.dy_0 = v.dy;
|
||||
|
||||
// Normalize the vector -> this results in points+direction
|
||||
// and is comparible between geometries
|
||||
calculation_type magnitude = sqrt(
|
||||
boost::numeric_cast<calculation_type>(v.dx * v.dx + v.dy * v.dy));
|
||||
|
||||
// Avoid non-duplicate points (AND division by zero)
|
||||
if (magnitude > 0)
|
||||
{
|
||||
v.dx /= magnitude;
|
||||
v.dy /= magnitude;
|
||||
|
||||
// Avoid non-direction changing points
|
||||
if (first || ! v.same_direction(collection.back()))
|
||||
{
|
||||
collection.push_back(v);
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
// If first one has same direction as last one, remove first one
|
||||
if (boost::size(collection) > 1
|
||||
&& collection.front().same_direction(collection.back()))
|
||||
{
|
||||
collection.erase(collection.begin());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Box, typename Collection>
|
||||
struct box_collect_vectors
|
||||
{
|
||||
// Calculate on coordinate type, but if it is integer,
|
||||
// then use double
|
||||
typedef typename boost::range_value<Collection>::type item_type;
|
||||
typedef typename item_type::type calculation_type;
|
||||
|
||||
static inline void apply(Collection& collection, Box const& box)
|
||||
{
|
||||
typename point_type<Box>::type lower_left, lower_right,
|
||||
upper_left, upper_right;
|
||||
geometry::detail::assign_box_corners(box, lower_left, lower_right,
|
||||
upper_left, upper_right);
|
||||
|
||||
typedef typename boost::range_value<Collection>::type item;
|
||||
|
||||
collection.push_back(item(get<0>(lower_left), get<1>(lower_left), 0, 1));
|
||||
collection.push_back(item(get<0>(upper_left), get<1>(upper_left), 1, 0));
|
||||
collection.push_back(item(get<0>(upper_right), get<1>(upper_right), 0, -1));
|
||||
collection.push_back(item(get<0>(lower_right), get<1>(lower_right), -1, 0));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Polygon, typename Collection>
|
||||
struct polygon_collect_vectors
|
||||
{
|
||||
static inline void apply(Collection& collection, Polygon const& polygon)
|
||||
{
|
||||
typedef typename geometry::ring_type<Polygon>::type ring_type;
|
||||
|
||||
typedef range_collect_vectors<ring_type, Collection> per_range;
|
||||
per_range::apply(collection, exterior_ring(polygon));
|
||||
|
||||
typename interior_return_type<Polygon const>::type rings
|
||||
= interior_rings(polygon);
|
||||
for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
|
||||
{
|
||||
per_range::apply(collection, *it);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename MultiGeometry, typename Collection, typename SinglePolicy>
|
||||
struct multi_collect_vectors
|
||||
{
|
||||
static inline void apply(Collection& collection, MultiGeometry const& multi)
|
||||
{
|
||||
for (typename boost::range_iterator<MultiGeometry const>::type
|
||||
it = boost::begin(multi);
|
||||
it != boost::end(multi);
|
||||
++it)
|
||||
{
|
||||
SinglePolicy::apply(collection, *it);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::collect_vectors
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag,
|
||||
typename Collection,
|
||||
typename Geometry
|
||||
>
|
||||
struct collect_vectors
|
||||
{
|
||||
static inline void apply(Collection&, Geometry const&)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
template <typename Collection, typename Box>
|
||||
struct collect_vectors<box_tag, Collection, Box>
|
||||
: detail::collect_vectors::box_collect_vectors<Box, Collection>
|
||||
{};
|
||||
|
||||
|
||||
|
||||
template <typename Collection, typename Ring>
|
||||
struct collect_vectors<ring_tag, Collection, Ring>
|
||||
: detail::collect_vectors::range_collect_vectors<Ring, Collection>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Collection, typename LineString>
|
||||
struct collect_vectors<linestring_tag, Collection, LineString>
|
||||
: detail::collect_vectors::range_collect_vectors<LineString, Collection>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Collection, typename Polygon>
|
||||
struct collect_vectors<polygon_tag, Collection, Polygon>
|
||||
: detail::collect_vectors::polygon_collect_vectors<Polygon, Collection>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Collection, typename MultiPolygon>
|
||||
struct collect_vectors<multi_polygon_tag, Collection, MultiPolygon>
|
||||
: detail::collect_vectors::multi_collect_vectors
|
||||
<
|
||||
MultiPolygon,
|
||||
Collection,
|
||||
detail::collect_vectors::polygon_collect_vectors
|
||||
<
|
||||
typename boost::range_value<MultiPolygon>::type,
|
||||
Collection
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
\ingroup collect_vectors
|
||||
\tparam Collection Collection type, should be e.g. std::vector<>
|
||||
\tparam Geometry geometry type
|
||||
\param collection the collection of vectors
|
||||
\param geometry the geometry to make collect_vectors
|
||||
*/
|
||||
template <typename Collection, typename Geometry>
|
||||
inline void collect_vectors(Collection& collection, Geometry const& geometry)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
dispatch::collect_vectors
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Collection,
|
||||
Geometry
|
||||
>::apply(collection, geometry);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_COLLECT_VECTORS_HPP
|
||||
125
test/external/boost/geometry/algorithms/detail/for_each_range.hpp
vendored
Normal file
125
test/external/boost/geometry/algorithms/detail/for_each_range.hpp
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_FOR_EACH_RANGE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_FOR_EACH_RANGE_HPP
|
||||
|
||||
|
||||
#include <boost/concept/requires.hpp>
|
||||
|
||||
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tag_cast.hpp>
|
||||
|
||||
#include <boost/geometry/util/add_const_if_c.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace for_each
|
||||
{
|
||||
|
||||
|
||||
template <typename Range, typename Actor, bool IsConst>
|
||||
struct fe_range_range
|
||||
{
|
||||
static inline void apply(
|
||||
typename add_const_if_c<IsConst, Range>::type& range,
|
||||
Actor& actor)
|
||||
{
|
||||
actor.apply(range);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Polygon, typename Actor, bool IsConst>
|
||||
struct fe_range_polygon
|
||||
{
|
||||
static inline void apply(
|
||||
typename add_const_if_c<IsConst, Polygon>::type& polygon,
|
||||
Actor& actor)
|
||||
{
|
||||
actor.apply(exterior_ring(polygon));
|
||||
|
||||
// TODO: If some flag says true, also do the inner rings.
|
||||
// for convex hull, it's not necessary
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::for_each
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag,
|
||||
typename Geometry,
|
||||
typename Actor,
|
||||
bool IsConst
|
||||
>
|
||||
struct for_each_range {};
|
||||
|
||||
|
||||
template <typename Linestring, typename Actor, bool IsConst>
|
||||
struct for_each_range<linestring_tag, Linestring, Actor, IsConst>
|
||||
: detail::for_each::fe_range_range<Linestring, Actor, IsConst>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Ring, typename Actor, bool IsConst>
|
||||
struct for_each_range<ring_tag, Ring, Actor, IsConst>
|
||||
: detail::for_each::fe_range_range<Ring, Actor, IsConst>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename Actor, bool IsConst>
|
||||
struct for_each_range<polygon_tag, Polygon, Actor, IsConst>
|
||||
: detail::for_each::fe_range_polygon<Polygon, Actor, IsConst>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename Geometry, typename Actor>
|
||||
inline void for_each_range(Geometry const& geometry, Actor& actor)
|
||||
{
|
||||
dispatch::for_each_range
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
Actor,
|
||||
true
|
||||
>::apply(geometry, actor);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_FOR_EACH_RANGE_HPP
|
||||
120
test/external/boost/geometry/algorithms/detail/has_self_intersections.hpp
vendored
Normal file
120
test/external/boost/geometry/algorithms/detail/has_self_intersections.hpp
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_HAS_SELF_INTERSECTIONS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_HAS_SELF_INTERSECTIONS_HPP
|
||||
|
||||
#include <deque>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
|
||||
|
||||
#include <boost/geometry/multi/algorithms/detail/overlay/self_turn_points.hpp>
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_HAS_SELF_INTERSECTIONS
|
||||
# include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
|
||||
# include <boost/geometry/util/write_dsv.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#if ! defined(BOOST_GEOMETRY_OVERLAY_NO_THROW)
|
||||
|
||||
/*!
|
||||
\brief Overlay Invalid Input Exception
|
||||
\ingroup overlay
|
||||
\details The overlay_invalid_input_exception is thrown at invalid input
|
||||
*/
|
||||
class overlay_invalid_input_exception : public geometry::exception
|
||||
{
|
||||
public:
|
||||
|
||||
inline overlay_invalid_input_exception() {}
|
||||
|
||||
virtual char const* what() const throw()
|
||||
{
|
||||
return "Boost.Geometry Overlay invalid input exception";
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
|
||||
template <typename Geometry>
|
||||
inline bool has_self_intersections(Geometry const& geometry)
|
||||
{
|
||||
typedef typename point_type<Geometry>::type point_type;
|
||||
typedef detail::overlay::turn_info<point_type> turn_info;
|
||||
std::deque<turn_info> turns;
|
||||
detail::disjoint::disjoint_interrupt_policy policy;
|
||||
geometry::self_turns<detail::overlay::assign_null_policy>(geometry, turns, policy);
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_HAS_SELF_INTERSECTIONS
|
||||
bool first = true;
|
||||
#endif
|
||||
for(typename std::deque<turn_info>::const_iterator it = boost::begin(turns);
|
||||
it != boost::end(turns); ++it)
|
||||
{
|
||||
turn_info const& info = *it;
|
||||
bool const both_union_turn =
|
||||
info.operations[0].operation == detail::overlay::operation_union
|
||||
&& info.operations[1].operation == detail::overlay::operation_union;
|
||||
bool const both_intersection_turn =
|
||||
info.operations[0].operation == detail::overlay::operation_intersection
|
||||
&& info.operations[1].operation == detail::overlay::operation_intersection;
|
||||
|
||||
bool const valid = (both_union_turn || both_intersection_turn)
|
||||
&& (info.method == detail::overlay::method_touch
|
||||
|| info.method == detail::overlay::method_touch_interior);
|
||||
|
||||
if (! valid)
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_HAS_SELF_INTERSECTIONS
|
||||
if (first)
|
||||
{
|
||||
std::cout << "turn points: " << std::endl;
|
||||
first = false;
|
||||
}
|
||||
std::cout << method_char(info.method);
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
std::cout << " " << operation_char(info.operations[i].operation);
|
||||
}
|
||||
std::cout << " " << geometry::dsv(info.point) << std::endl;
|
||||
#endif
|
||||
|
||||
#if ! defined(BOOST_GEOMETRY_OVERLAY_NO_THROW)
|
||||
throw overlay_invalid_input_exception();
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_HAS_SELF_INTERSECTIONS_HPP
|
||||
|
||||
50
test/external/boost/geometry/algorithms/detail/not.hpp
vendored
Normal file
50
test/external/boost/geometry/algorithms/detail/not.hpp
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_NOT_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_NOT_HPP
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail
|
||||
{
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Structure negating the result of specified policy
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam Policy
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\return Negation of the result of the policy
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2, typename Policy>
|
||||
struct not_
|
||||
{
|
||||
static inline bool apply(Geometry1 const &geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
return ! Policy::apply(geometry1, geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_NOT_HPP
|
||||
134
test/external/boost/geometry/algorithms/detail/overlay/add_rings.hpp
vendored
Normal file
134
test/external/boost/geometry/algorithms/detail/overlay/add_rings.hpp
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/convert_ring.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryOut,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename RingCollection
|
||||
>
|
||||
inline void convert_and_add(GeometryOut& result,
|
||||
Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
RingCollection const& collection,
|
||||
ring_identifier id,
|
||||
bool reversed, bool append)
|
||||
{
|
||||
typedef typename geometry::tag<Geometry1>::type tag1;
|
||||
typedef typename geometry::tag<Geometry2>::type tag2;
|
||||
typedef typename geometry::tag<GeometryOut>::type tag_out;
|
||||
|
||||
if (id.source_index == 0)
|
||||
{
|
||||
convert_ring<tag_out>::apply(result,
|
||||
get_ring<tag1>::apply(id, geometry1),
|
||||
append, reversed);
|
||||
}
|
||||
else if (id.source_index == 1)
|
||||
{
|
||||
convert_ring<tag_out>::apply(result,
|
||||
get_ring<tag2>::apply(id, geometry2),
|
||||
append, reversed);
|
||||
}
|
||||
else if (id.source_index == 2)
|
||||
{
|
||||
convert_ring<tag_out>::apply(result,
|
||||
get_ring<void>::apply(id, collection),
|
||||
append, reversed);
|
||||
}
|
||||
}
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryOut,
|
||||
typename SelectionMap,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename RingCollection,
|
||||
typename OutputIterator
|
||||
>
|
||||
inline OutputIterator add_rings(SelectionMap const& map,
|
||||
Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
RingCollection const& collection,
|
||||
OutputIterator out)
|
||||
{
|
||||
typedef typename SelectionMap::const_iterator iterator;
|
||||
|
||||
for (iterator it = boost::begin(map);
|
||||
it != boost::end(map);
|
||||
++it)
|
||||
{
|
||||
if (! it->second.discarded
|
||||
&& it->second.parent.source_index == -1)
|
||||
{
|
||||
GeometryOut result;
|
||||
convert_and_add(result, geometry1, geometry2, collection,
|
||||
it->first, it->second.reversed, false);
|
||||
|
||||
// Add children
|
||||
for (typename std::vector<ring_identifier>::const_iterator child_it
|
||||
= it->second.children.begin();
|
||||
child_it != it->second.children.end();
|
||||
++child_it)
|
||||
{
|
||||
iterator mit = map.find(*child_it);
|
||||
if (mit != map.end()
|
||||
&& ! mit->second.discarded)
|
||||
{
|
||||
convert_and_add(result, geometry1, geometry2, collection,
|
||||
*child_it, mit->second.reversed, true);
|
||||
}
|
||||
}
|
||||
*out++ = result;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryOut,
|
||||
typename SelectionMap,
|
||||
typename Geometry,
|
||||
typename RingCollection,
|
||||
typename OutputIterator
|
||||
>
|
||||
inline OutputIterator add_rings(SelectionMap const& map,
|
||||
Geometry const& geometry,
|
||||
RingCollection const& collection,
|
||||
OutputIterator out)
|
||||
{
|
||||
Geometry empty;
|
||||
return add_rings<GeometryOut>(map, geometry, empty, collection, out);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP
|
||||
53
test/external/boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp
vendored
Normal file
53
test/external/boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_APPEND_NO_DUPLICATES_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_APPEND_NO_DUPLICATES_HPP
|
||||
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/append.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint.hpp>
|
||||
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
template <typename Range, typename Point>
|
||||
inline void append_no_duplicates(Range& range, Point const& point, bool force = false)
|
||||
{
|
||||
if (boost::size(range) == 0
|
||||
|| force
|
||||
|| ! geometry::detail::equals::equals_point_point(*(boost::end(range)-1), point))
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
|
||||
std::cout << " add: ("
|
||||
<< geometry::get<0>(point) << ", " << geometry::get<1>(point) << ")"
|
||||
<< std::endl;
|
||||
#endif
|
||||
geometry::append(range, point);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_APPEND_NO_DUPLICATES_HPP
|
||||
337
test/external/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
vendored
Normal file
337
test/external/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
vendored
Normal file
@@ -0,0 +1,337 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ASSIGN_PARENTS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ASSIGN_PARENTS_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/area.hpp>
|
||||
#include <boost/geometry/algorithms/envelope.hpp>
|
||||
#include <boost/geometry/algorithms/expand.hpp>
|
||||
#include <boost/geometry/algorithms/detail/partition.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
|
||||
#include <boost/geometry/algorithms/within.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/box.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Item,
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename RingCollection
|
||||
>
|
||||
static inline bool within_selected_input(Item const& item2, ring_identifier const& ring_id,
|
||||
Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
RingCollection const& collection)
|
||||
{
|
||||
typedef typename geometry::tag<Geometry1>::type tag1;
|
||||
typedef typename geometry::tag<Geometry2>::type tag2;
|
||||
|
||||
switch (ring_id.source_index)
|
||||
{
|
||||
case 0 :
|
||||
return geometry::within(item2.point,
|
||||
get_ring<tag1>::apply(ring_id, geometry1));
|
||||
break;
|
||||
case 1 :
|
||||
return geometry::within(item2.point,
|
||||
get_ring<tag2>::apply(ring_id, geometry2));
|
||||
break;
|
||||
case 2 :
|
||||
return geometry::within(item2.point,
|
||||
get_ring<void>::apply(ring_id, collection));
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template <typename Point>
|
||||
struct ring_info_helper
|
||||
{
|
||||
typedef typename geometry::default_area_result<Point>::type area_type;
|
||||
|
||||
ring_identifier id;
|
||||
area_type real_area;
|
||||
area_type abs_area;
|
||||
model::box<Point> envelope;
|
||||
|
||||
inline ring_info_helper()
|
||||
: real_area(0), abs_area(0)
|
||||
{}
|
||||
|
||||
inline ring_info_helper(ring_identifier i, area_type a)
|
||||
: id(i), real_area(a), abs_area(geometry::math::abs(a))
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
struct ring_info_helper_get_box
|
||||
{
|
||||
template <typename Box, typename InputItem>
|
||||
static inline void apply(Box& total, InputItem const& item)
|
||||
{
|
||||
geometry::expand(total, item.envelope);
|
||||
}
|
||||
};
|
||||
|
||||
struct ring_info_helper_ovelaps_box
|
||||
{
|
||||
template <typename Box, typename InputItem>
|
||||
static inline bool apply(Box const& box, InputItem const& item)
|
||||
{
|
||||
return ! geometry::detail::disjoint::disjoint_box_box(box, item.envelope);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Collection, typename RingMap>
|
||||
struct assign_visitor
|
||||
{
|
||||
typedef typename RingMap::mapped_type ring_info_type;
|
||||
|
||||
Geometry1 const& m_geometry1;
|
||||
Geometry2 const& m_geometry2;
|
||||
Collection const& m_collection;
|
||||
RingMap& m_ring_map;
|
||||
bool m_check_for_orientation;
|
||||
|
||||
|
||||
inline assign_visitor(Geometry1 const& g1, Geometry2 const& g2, Collection const& c,
|
||||
RingMap& map, bool check)
|
||||
: m_geometry1(g1)
|
||||
, m_geometry2(g2)
|
||||
, m_collection(c)
|
||||
, m_ring_map(map)
|
||||
, m_check_for_orientation(check)
|
||||
{}
|
||||
|
||||
template <typename Item>
|
||||
inline void apply(Item const& outer, Item const& inner, bool first = true)
|
||||
{
|
||||
if (first && outer.real_area < 0)
|
||||
{
|
||||
// Reverse arguments
|
||||
apply(inner, outer, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (outer.real_area > 0)
|
||||
{
|
||||
if (inner.real_area < 0 || m_check_for_orientation)
|
||||
{
|
||||
ring_info_type& inner_in_map = m_ring_map[inner.id];
|
||||
|
||||
if (geometry::within(inner_in_map.point, outer.envelope)
|
||||
&& within_selected_input(inner_in_map, outer.id, m_geometry1, m_geometry2, m_collection)
|
||||
)
|
||||
{
|
||||
// Only assign parent if that parent is smaller (or if it is the first)
|
||||
if (inner_in_map.parent.source_index == -1
|
||||
|| outer.abs_area < inner_in_map.parent_area)
|
||||
{
|
||||
inner_in_map.parent = outer.id;
|
||||
inner_in_map.parent_area = outer.abs_area;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename RingCollection,
|
||||
typename RingMap
|
||||
>
|
||||
inline void assign_parents(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
RingCollection const& collection,
|
||||
RingMap& ring_map,
|
||||
bool check_for_orientation = false)
|
||||
{
|
||||
typedef typename geometry::tag<Geometry1>::type tag1;
|
||||
typedef typename geometry::tag<Geometry2>::type tag2;
|
||||
|
||||
typedef typename RingMap::mapped_type ring_info_type;
|
||||
typedef typename ring_info_type::point_type point_type;
|
||||
typedef model::box<point_type> box_type;
|
||||
|
||||
typedef typename RingMap::iterator map_iterator_type;
|
||||
|
||||
{
|
||||
typedef ring_info_helper<point_type> helper;
|
||||
typedef std::vector<helper> vector_type;
|
||||
typedef typename boost::range_iterator<vector_type const>::type vector_iterator_type;
|
||||
|
||||
#ifdef BOOST_GEOMETRY_TIME_OVERLAY
|
||||
boost::timer timer;
|
||||
#endif
|
||||
|
||||
|
||||
std::size_t count_total = ring_map.size();
|
||||
std::size_t count_positive = 0;
|
||||
std::size_t index_positive = 0; // only used if count_positive>0
|
||||
std::size_t index = 0;
|
||||
|
||||
// Copy to vector (with new approach this might be obsolete as well, using the map directly)
|
||||
vector_type vector(count_total);
|
||||
|
||||
for (map_iterator_type it = boost::begin(ring_map);
|
||||
it != boost::end(ring_map); ++it, ++index)
|
||||
{
|
||||
vector[index] = helper(it->first, it->second.get_area());
|
||||
helper& item = vector[index];
|
||||
switch(it->first.source_index)
|
||||
{
|
||||
case 0 :
|
||||
geometry::envelope(get_ring<tag1>::apply(it->first, geometry1),
|
||||
item.envelope);
|
||||
break;
|
||||
case 1 :
|
||||
geometry::envelope(get_ring<tag2>::apply(it->first, geometry2),
|
||||
item.envelope);
|
||||
break;
|
||||
case 2 :
|
||||
geometry::envelope(get_ring<void>::apply(it->first, collection),
|
||||
item.envelope);
|
||||
break;
|
||||
}
|
||||
if (item.real_area > 0)
|
||||
{
|
||||
count_positive++;
|
||||
index_positive = index;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOOST_GEOMETRY_TIME_OVERLAY
|
||||
std::cout << " ap: created helper vector: " << timer.elapsed() << std::endl;
|
||||
#endif
|
||||
|
||||
if (! check_for_orientation)
|
||||
{
|
||||
if (count_positive == count_total)
|
||||
{
|
||||
// Optimization for only positive rings
|
||||
// -> no assignment of parents or reversal necessary, ready here.
|
||||
return;
|
||||
}
|
||||
|
||||
if (count_positive == 1)
|
||||
{
|
||||
// Optimization for one outer ring
|
||||
// -> assign this as parent to all others (all interior rings)
|
||||
// In unions, this is probably the most occuring case and gives
|
||||
// a dramatic improvement (factor 5 for star_comb testcase)
|
||||
ring_identifier id_of_positive = vector[index_positive].id;
|
||||
ring_info_type& outer = ring_map[id_of_positive];
|
||||
std::size_t index = 0;
|
||||
for (vector_iterator_type it = boost::begin(vector);
|
||||
it != boost::end(vector); ++it, ++index)
|
||||
{
|
||||
if (index != index_positive)
|
||||
{
|
||||
ring_info_type& inner = ring_map[it->id];
|
||||
inner.parent = id_of_positive;
|
||||
outer.children.push_back(it->id);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
assign_visitor
|
||||
<
|
||||
Geometry1, Geometry2,
|
||||
RingCollection, RingMap
|
||||
> visitor(geometry1, geometry2, collection, ring_map, check_for_orientation);
|
||||
|
||||
geometry::partition
|
||||
<
|
||||
box_type, ring_info_helper_get_box, ring_info_helper_ovelaps_box
|
||||
>::apply(vector, visitor);
|
||||
|
||||
#ifdef BOOST_GEOMETRY_TIME_OVERLAY
|
||||
std::cout << " ap: quadradic loop: " << timer.elapsed() << std::endl;
|
||||
std::cout << " ap: check_for_orientation " << check_for_orientation << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (check_for_orientation)
|
||||
{
|
||||
for (map_iterator_type it = boost::begin(ring_map);
|
||||
it != boost::end(ring_map); ++it)
|
||||
{
|
||||
if (geometry::math::equals(it->second.get_area(), 0))
|
||||
{
|
||||
it->second.discarded = true;
|
||||
}
|
||||
else if (it->second.parent.source_index >= 0 && it->second.get_area() > 0)
|
||||
{
|
||||
// Discard positive inner ring with parent
|
||||
it->second.discarded = true;
|
||||
it->second.parent.source_index = -1;
|
||||
}
|
||||
else if (it->second.parent.source_index < 0 && it->second.get_area() < 0)
|
||||
{
|
||||
// Reverse negative ring without parent
|
||||
it->second.reversed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Assign childlist
|
||||
for (map_iterator_type it = boost::begin(ring_map);
|
||||
it != boost::end(ring_map); ++it)
|
||||
{
|
||||
if (it->second.parent.source_index >= 0)
|
||||
{
|
||||
ring_map[it->second.parent].children.push_back(it->first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename RingCollection,
|
||||
typename RingMap
|
||||
>
|
||||
inline void assign_parents(Geometry const& geometry,
|
||||
RingCollection const& collection,
|
||||
RingMap& ring_map)
|
||||
{
|
||||
// Call it with an empty geometry
|
||||
// (ring_map should be empty for source_id==1)
|
||||
|
||||
Geometry empty;
|
||||
assign_parents(geometry, empty, collection, ring_map, true);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ASSIGN_PARENTS_HPP
|
||||
181
test/external/boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp
vendored
Normal file
181
test/external/boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_BACKTRACK_CHECK_SI_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_BACKTRACK_CHECK_SI_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
|
||||
# include <boost/geometry/algorithms/detail/has_self_intersections.hpp>
|
||||
|
||||
|
||||
#if defined(BOOST_GEOMETRY_DEBUG_INTERSECTION) || defined(BOOST_GEOMETRY_OVERLAY_REPORT_WKT)
|
||||
# include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
|
||||
# include <boost/geometry/domains/gis/io/wkt/wkt.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
|
||||
template <typename Turns>
|
||||
inline void clear_visit_info(Turns& turns)
|
||||
{
|
||||
typedef typename boost::range_value<Turns>::type tp_type;
|
||||
|
||||
for (typename boost::range_iterator<Turns>::type
|
||||
it = boost::begin(turns);
|
||||
it != boost::end(turns);
|
||||
++it)
|
||||
{
|
||||
for (typename boost::range_iterator
|
||||
<
|
||||
typename tp_type::container_type
|
||||
>::type op_it = boost::begin(it->operations);
|
||||
op_it != boost::end(it->operations);
|
||||
++op_it)
|
||||
{
|
||||
op_it->visited.clear();
|
||||
}
|
||||
it->discarded = false;
|
||||
}
|
||||
}
|
||||
|
||||
struct backtrack_state
|
||||
{
|
||||
bool m_good;
|
||||
|
||||
inline backtrack_state() : m_good(true) {}
|
||||
inline void reset() { m_good = true; }
|
||||
inline bool good() const { return m_good; }
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2
|
||||
>
|
||||
class backtrack_check_self_intersections
|
||||
{
|
||||
struct state : public backtrack_state
|
||||
{
|
||||
bool m_checked;
|
||||
inline state()
|
||||
: m_checked()
|
||||
{}
|
||||
};
|
||||
public :
|
||||
typedef state state_type;
|
||||
|
||||
template <typename Operation, typename Rings, typename Turns>
|
||||
static inline void apply(std::size_t size_at_start,
|
||||
Rings& rings, typename boost::range_value<Rings>::type& ring,
|
||||
Turns& turns, Operation& operation,
|
||||
std::string const& ,
|
||||
Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
state_type& state
|
||||
)
|
||||
{
|
||||
state.m_good = false;
|
||||
|
||||
// Check self-intersections and throw exception if appropriate
|
||||
if (! state.m_checked)
|
||||
{
|
||||
state.m_checked = true;
|
||||
has_self_intersections(geometry1);
|
||||
has_self_intersections(geometry2);
|
||||
}
|
||||
|
||||
// Make bad output clean
|
||||
rings.resize(size_at_start);
|
||||
ring.clear();
|
||||
|
||||
// Reject this as a starting point
|
||||
operation.visited.set_rejected();
|
||||
|
||||
// And clear all visit info
|
||||
clear_visit_info(turns);
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef BOOST_GEOMETRY_OVERLAY_REPORT_WKT
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2
|
||||
>
|
||||
class backtrack_debug
|
||||
{
|
||||
public :
|
||||
typedef backtrack_state state_type;
|
||||
|
||||
template <typename Operation, typename Rings, typename Turns>
|
||||
static inline void apply(std::size_t size_at_start,
|
||||
Rings& rings, typename boost::range_value<Rings>::type& ring,
|
||||
Turns& turns, Operation& operation,
|
||||
std::string const& reason,
|
||||
Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
state_type& state
|
||||
)
|
||||
{
|
||||
std::cout << " REJECT " << reason << std::endl;
|
||||
|
||||
state.m_good = false;
|
||||
|
||||
rings.resize(size_at_start);
|
||||
ring.clear();
|
||||
operation.visited.set_rejected();
|
||||
clear_visit_info(turns);
|
||||
|
||||
int c = 0;
|
||||
for (int i = 0; i < turns.size(); i++)
|
||||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
if (turns[i].operations[j].visited.rejected())
|
||||
{
|
||||
c++;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << "BACKTRACK (" << reason << " )"
|
||||
<< " " << c << " of " << turns.size() << " rejected"
|
||||
<< std::endl;
|
||||
std::cout
|
||||
<< geometry::wkt(geometry1) << std::endl
|
||||
<< geometry::wkt(geometry2) << std::endl;
|
||||
}
|
||||
};
|
||||
#endif // BOOST_GEOMETRY_OVERLAY_REPORT_WKT
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_BACKTRACK_CHECK_SI_HPP
|
||||
52
test/external/boost/geometry/algorithms/detail/overlay/calculate_distance_policy.hpp
vendored
Normal file
52
test/external/boost/geometry/algorithms/detail/overlay/calculate_distance_policy.hpp
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CALCULATE_DISTANCE_POLICY_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CALCULATE_DISTANCE_POLICY_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/algorithms/comparable_distance.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
|
||||
/*!
|
||||
\brief Policy calculating distance
|
||||
\details get_turn_info has an optional policy to get some
|
||||
extra information.
|
||||
This policy calculates the distance (using default distance strategy)
|
||||
*/
|
||||
struct calculate_distance_policy
|
||||
{
|
||||
template <typename Point1, typename Point2, typename Info>
|
||||
static inline void apply(Info& info, Point1 const& p1, Point2 const& p2)
|
||||
{
|
||||
info.operations[0].enriched.distance
|
||||
= geometry::comparable_distance(info.point, p1);
|
||||
info.operations[1].enriched.distance
|
||||
= geometry::comparable_distance(info.point, p2);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif //DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CALCULATE_DISTANCE_POLICY_HPP
|
||||
172
test/external/boost/geometry/algorithms/detail/overlay/check_enrich.hpp
vendored
Normal file
172
test/external/boost/geometry/algorithms/detail/overlay/check_enrich.hpp
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CHECK_ENRICH_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CHECK_ENRICH_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/range.hpp>
|
||||
|
||||
|
||||
|
||||
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
|
||||
template<typename Turn>
|
||||
struct meta_turn
|
||||
{
|
||||
int index;
|
||||
Turn const* turn;
|
||||
bool handled[2];
|
||||
|
||||
inline meta_turn(int i, Turn const& t)
|
||||
: index(i), turn(&t)
|
||||
{
|
||||
handled[0] = false;
|
||||
handled[1] = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename MetaTurn>
|
||||
inline void display(MetaTurn const& meta_turn, std::string const& reason = "")
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
|
||||
std::cout << meta_turn.index
|
||||
<< "\tMethods: " << method_char(meta_turn.turn->method)
|
||||
<< " operations: " << operation_char(meta_turn.turn->operations[0].operation)
|
||||
<< operation_char(meta_turn.turn->operations[1].operation)
|
||||
<< " travels to " << meta_turn.turn->operations[0].enriched.travels_to_ip_index
|
||||
<< " and " << meta_turn.turn->operations[1].enriched.travels_to_ip_index
|
||||
//<< " -> " << op_index
|
||||
<< " " << reason
|
||||
<< std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <typename MetaTurns, typename MetaTurn>
|
||||
inline void check_detailed(MetaTurns& meta_turns, MetaTurn const& meta_turn,
|
||||
int op_index, int cycle, int start, operation_type for_operation,
|
||||
bool& error)
|
||||
{
|
||||
display(meta_turn);
|
||||
int const ip_index = meta_turn.turn->operations[op_index].enriched.travels_to_ip_index;
|
||||
if (ip_index >= 0)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
if (ip_index == start)
|
||||
{
|
||||
display(meta_turns[ip_index], " FINISH");
|
||||
return;
|
||||
}
|
||||
|
||||
// check on continuing, or on same-operation-on-same-geometry
|
||||
if (! meta_turns[ip_index].handled[op_index]
|
||||
&& (meta_turns[ip_index].turn->operations[op_index].operation == operation_continue
|
||||
|| meta_turns[ip_index].turn->operations[op_index].operation == for_operation)
|
||||
)
|
||||
{
|
||||
meta_turns[ip_index].handled[op_index] = true;
|
||||
check_detailed(meta_turns, meta_turns[ip_index], op_index, cycle, start, for_operation, error);
|
||||
found = true;
|
||||
}
|
||||
// check on other geometry
|
||||
if (! found)
|
||||
{
|
||||
int const other_index = 1 - op_index;
|
||||
if (! meta_turns[ip_index].handled[other_index]
|
||||
&& meta_turns[ip_index].turn->operations[other_index].operation == for_operation)
|
||||
{
|
||||
meta_turns[ip_index].handled[other_index] = true;
|
||||
check_detailed(meta_turns, meta_turns[ip_index], other_index, cycle, start, for_operation, error);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (! found)
|
||||
{
|
||||
display(meta_turns[ip_index], " STOP");
|
||||
error = true;
|
||||
#ifndef BOOST_GEOMETRY_DEBUG_ENRICH
|
||||
//std::cout << " STOP";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename TurnPoints>
|
||||
inline bool check_graph(TurnPoints& turn_points, operation_type for_operation)
|
||||
{
|
||||
typedef typename boost::range_value<TurnPoints>::type turn_point_type;
|
||||
|
||||
bool error = false;
|
||||
int index = 0;
|
||||
|
||||
std::vector<meta_turn<turn_point_type> > meta_turns;
|
||||
for (typename boost::range_iterator<TurnPoints const>::type
|
||||
it = boost::begin(turn_points);
|
||||
it != boost::end(turn_points);
|
||||
++it, ++index)
|
||||
{
|
||||
meta_turns.push_back(meta_turn<turn_point_type>(index, *it));
|
||||
}
|
||||
|
||||
int cycle = 0;
|
||||
for (typename boost::range_iterator<std::vector<meta_turn<turn_point_type> > > ::type
|
||||
it = boost::begin(meta_turns);
|
||||
it != boost::end(meta_turns);
|
||||
++it)
|
||||
{
|
||||
if (! (it->turn->blocked() || it->turn->is_discarded()))
|
||||
{
|
||||
for (int i = 0 ; i < 2; i++)
|
||||
{
|
||||
if (! it->handled[i]
|
||||
&& it->turn->operations[i].operation == for_operation)
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
|
||||
std::cout << "CYCLE " << cycle << std::endl;
|
||||
#endif
|
||||
it->handled[i] = true;
|
||||
check_detailed(meta_turns, *it, i, cycle++, it->index, for_operation, error);
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
|
||||
std::cout <<" END CYCLE " << it->index << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif //DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CHECK_ENRICH_HPP
|
||||
242
test/external/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp
vendored
Normal file
242
test/external/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CLIP_LINESTRING_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CLIP_LINESTRING_HPP
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/clear.hpp>
|
||||
#include <boost/geometry/algorithms/convert.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp>
|
||||
|
||||
#include <boost/geometry/util/select_coordinate_type.hpp>
|
||||
#include <boost/geometry/geometries/segment.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace strategy { namespace intersection
|
||||
{
|
||||
|
||||
/*!
|
||||
\brief Strategy: line clipping algorithm after Liang Barsky
|
||||
\ingroup overlay
|
||||
\details The Liang-Barsky line clipping algorithm clips a line with a clipping box.
|
||||
It is slightly adapted in the sense that it returns which points are clipped
|
||||
\tparam B input box type of clipping box
|
||||
\tparam P input/output point-type of segments to be clipped
|
||||
\note The algorithm is currently only implemented for 2D Cartesian points
|
||||
\note Though it is implemented in namespace strategy, and theoretically another
|
||||
strategy could be used, it is not (yet) updated to the general strategy concepts,
|
||||
and not (yet) splitted into a file in folder strategies
|
||||
\author Barend Gehrels, and the following recourses
|
||||
- A tutorial: http://www.skytopia.com/project/articles/compsci/clipping.html
|
||||
- a German applet (link broken): http://ls7-www.cs.uni-dortmund.de/students/projectgroups/acit/lineclip.shtml
|
||||
*/
|
||||
template<typename Box, typename Point>
|
||||
class liang_barsky
|
||||
{
|
||||
private:
|
||||
typedef model::referring_segment<Point> segment_type;
|
||||
|
||||
template <typename T>
|
||||
inline bool check_edge(T const& p, T const& q, T& t1, T& t2) const
|
||||
{
|
||||
bool visible = true;
|
||||
|
||||
if(p < 0)
|
||||
{
|
||||
T const r = q / p;
|
||||
if (r > t2)
|
||||
visible = false;
|
||||
else if (r > t1)
|
||||
t1 = r;
|
||||
}
|
||||
else if(p > 0)
|
||||
{
|
||||
T const r = q / p;
|
||||
if (r < t1)
|
||||
visible = false;
|
||||
else if (r < t2)
|
||||
t2 = r;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (q < 0)
|
||||
visible = false;
|
||||
}
|
||||
|
||||
return visible;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
inline bool clip_segment(Box const& b, segment_type& s, bool& sp1_clipped, bool& sp2_clipped) const
|
||||
{
|
||||
typedef typename select_coordinate_type<Box, Point>::type coordinate_type;
|
||||
|
||||
coordinate_type t1 = 0;
|
||||
coordinate_type t2 = 1;
|
||||
|
||||
coordinate_type const dx = get<1, 0>(s) - get<0, 0>(s);
|
||||
coordinate_type const dy = get<1, 1>(s) - get<0, 1>(s);
|
||||
|
||||
coordinate_type const p1 = -dx;
|
||||
coordinate_type const p2 = dx;
|
||||
coordinate_type const p3 = -dy;
|
||||
coordinate_type const p4 = dy;
|
||||
|
||||
coordinate_type const q1 = get<0, 0>(s) - get<min_corner, 0>(b);
|
||||
coordinate_type const q2 = get<max_corner, 0>(b) - get<0, 0>(s);
|
||||
coordinate_type const q3 = get<0, 1>(s) - get<min_corner, 1>(b);
|
||||
coordinate_type const q4 = get<max_corner, 1>(b) - get<0, 1>(s);
|
||||
|
||||
if (check_edge(p1, q1, t1, t2) // left
|
||||
&& check_edge(p2, q2, t1, t2) // right
|
||||
&& check_edge(p3, q3, t1, t2) // bottom
|
||||
&& check_edge(p4, q4, t1, t2)) // top
|
||||
{
|
||||
sp1_clipped = t1 > 0;
|
||||
sp2_clipped = t2 < 1;
|
||||
|
||||
if (sp2_clipped)
|
||||
{
|
||||
set<1, 0>(s, get<0, 0>(s) + t2 * dx);
|
||||
set<1, 1>(s, get<0, 1>(s) + t2 * dy);
|
||||
}
|
||||
|
||||
if(sp1_clipped)
|
||||
{
|
||||
set<0, 0>(s, get<0, 0>(s) + t1 * dx);
|
||||
set<0, 1>(s, get<0, 1>(s) + t1 * dy);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename Linestring, typename OutputIterator>
|
||||
inline void apply(Linestring& line_out, OutputIterator out) const
|
||||
{
|
||||
if (!boost::empty(line_out))
|
||||
{
|
||||
*out = line_out;
|
||||
++out;
|
||||
geometry::clear(line_out);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace strategy::intersection
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace intersection
|
||||
{
|
||||
|
||||
/*!
|
||||
\brief Clips a linestring with a box
|
||||
\details A linestring is intersected (clipped) by the specified box
|
||||
and the resulting linestring, or pieces of linestrings, are sent to the specified output operator.
|
||||
\tparam OutputLinestring type of the output linestrings
|
||||
\tparam OutputIterator an output iterator which outputs linestrings
|
||||
\tparam Linestring linestring-type, for example a vector of points, matching the output-iterator type,
|
||||
the points should also match the input-iterator type
|
||||
\tparam Box box type
|
||||
\tparam Strategy strategy, a clipping strategy which should implement the methods "clip_segment" and "apply"
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename OutputLinestring,
|
||||
typename OutputIterator,
|
||||
typename Range,
|
||||
typename Box,
|
||||
typename Strategy
|
||||
>
|
||||
OutputIterator clip_range_with_box(Box const& b, Range const& range,
|
||||
OutputIterator out, Strategy const& strategy)
|
||||
{
|
||||
if (boost::begin(range) == boost::end(range))
|
||||
{
|
||||
return out;
|
||||
}
|
||||
|
||||
typedef typename point_type<OutputLinestring>::type point_type;
|
||||
|
||||
OutputLinestring line_out;
|
||||
|
||||
typedef typename boost::range_iterator<Range const>::type iterator_type;
|
||||
iterator_type vertex = boost::begin(range);
|
||||
for(iterator_type previous = vertex++;
|
||||
vertex != boost::end(range);
|
||||
++previous, ++vertex)
|
||||
{
|
||||
point_type p1, p2;
|
||||
geometry::convert(*previous, p1);
|
||||
geometry::convert(*vertex, p2);
|
||||
|
||||
// Clip the segment. Five situations:
|
||||
// 1. Segment is invisible, finish line if any (shouldn't occur)
|
||||
// 2. Segment is completely visible. Add (p1)-p2 to line
|
||||
// 3. Point 1 is invisible (clipped), point 2 is visible. Start new line from p1-p2...
|
||||
// 4. Point 1 is visible, point 2 is invisible (clipped). End the line with ...p2
|
||||
// 5. Point 1 and point 2 are both invisible (clipped). Start/finish an independant line p1-p2
|
||||
//
|
||||
// This results in:
|
||||
// a. if p1 is clipped, start new line
|
||||
// b. if segment is partly or completely visible, add the segment
|
||||
// c. if p2 is clipped, end the line
|
||||
|
||||
bool c1 = false;
|
||||
bool c2 = false;
|
||||
model::referring_segment<point_type> s(p1, p2);
|
||||
|
||||
if (!strategy.clip_segment(b, s, c1, c2))
|
||||
{
|
||||
strategy.apply(line_out, out);
|
||||
}
|
||||
else
|
||||
{
|
||||
// a. If necessary, finish the line and add a start a new one
|
||||
if (c1)
|
||||
{
|
||||
strategy.apply(line_out, out);
|
||||
}
|
||||
|
||||
// b. Add p1 only if it is the first point, then add p2
|
||||
if (boost::empty(line_out))
|
||||
{
|
||||
detail::overlay::append_no_duplicates(line_out, p1, true);
|
||||
}
|
||||
detail::overlay::append_no_duplicates(line_out, p2);
|
||||
|
||||
// c. If c2 is clipped, finish the line
|
||||
if (c2)
|
||||
{
|
||||
strategy.apply(line_out, out);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Add last part
|
||||
strategy.apply(line_out, out);
|
||||
return out;
|
||||
}
|
||||
|
||||
}} // namespace detail::intersection
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CLIP_LINESTRING_HPP
|
||||
99
test/external/boost/geometry/algorithms/detail/overlay/convert_ring.hpp
vendored
Normal file
99
test/external/boost/geometry/algorithms/detail/overlay/convert_ring.hpp
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CONVERT_RING_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CONVERT_RING_HPP
|
||||
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/range/algorithm/reverse.hpp>
|
||||
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/convert.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
|
||||
template<typename Tag>
|
||||
struct convert_ring
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TAG
|
||||
, (types<Tag>)
|
||||
);
|
||||
};
|
||||
|
||||
template<>
|
||||
struct convert_ring<ring_tag>
|
||||
{
|
||||
template<typename Destination, typename Source>
|
||||
static inline void apply(Destination& destination, Source const& source,
|
||||
bool append, bool reverse)
|
||||
{
|
||||
if (! append)
|
||||
{
|
||||
geometry::convert(source, destination);
|
||||
if (reverse)
|
||||
{
|
||||
boost::reverse(destination);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
struct convert_ring<polygon_tag>
|
||||
{
|
||||
template<typename Destination, typename Source>
|
||||
static inline void apply(Destination& destination, Source const& source,
|
||||
bool append, bool reverse)
|
||||
{
|
||||
if (! append)
|
||||
{
|
||||
geometry::convert(source, exterior_ring(destination));
|
||||
if (reverse)
|
||||
{
|
||||
boost::reverse(exterior_ring(destination));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
interior_rings(destination).resize(
|
||||
interior_rings(destination).size() + 1);
|
||||
geometry::convert(source, interior_rings(destination).back());
|
||||
if (reverse)
|
||||
{
|
||||
boost::reverse(interior_rings(destination).back());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CONVERT_RING_HPP
|
||||
295
test/external/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp
vendored
Normal file
295
test/external/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp
vendored
Normal file
@@ -0,0 +1,295 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENT_POINT_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENT_POINT_HPP
|
||||
|
||||
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/core/ring_type.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/algorithms/convert.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/views/closeable_view.hpp>
|
||||
#include <boost/geometry/views/reversible_view.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace copy_segments
|
||||
{
|
||||
|
||||
|
||||
template <typename Range, bool Reverse, typename SegmentIdentifier, typename PointOut>
|
||||
struct copy_segment_point_range
|
||||
{
|
||||
typedef typename closeable_view
|
||||
<
|
||||
Range const,
|
||||
closure<Range>::value
|
||||
>::type cview_type;
|
||||
|
||||
typedef typename reversible_view
|
||||
<
|
||||
cview_type const,
|
||||
Reverse ? iterate_reverse : iterate_forward
|
||||
>::type rview_type;
|
||||
|
||||
static inline bool apply(Range const& range,
|
||||
SegmentIdentifier const& seg_id, bool second,
|
||||
PointOut& point)
|
||||
{
|
||||
int index = seg_id.segment_index;
|
||||
if (second)
|
||||
{
|
||||
index++;
|
||||
if (index >= boost::size(range))
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Exception?
|
||||
if (index >= boost::size(range))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
cview_type cview(range);
|
||||
rview_type view(cview);
|
||||
|
||||
|
||||
geometry::convert(*(boost::begin(view) + index), point);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Polygon, bool Reverse, typename SegmentIdentifier, typename PointOut>
|
||||
struct copy_segment_point_polygon
|
||||
{
|
||||
static inline bool apply(Polygon const& polygon,
|
||||
SegmentIdentifier const& seg_id, bool second,
|
||||
PointOut& point)
|
||||
{
|
||||
// Call ring-version with the right ring
|
||||
return copy_segment_point_range
|
||||
<
|
||||
typename geometry::ring_type<Polygon>::type,
|
||||
Reverse,
|
||||
SegmentIdentifier,
|
||||
PointOut
|
||||
>::apply
|
||||
(
|
||||
seg_id.ring_index < 0
|
||||
? geometry::exterior_ring(polygon)
|
||||
: geometry::interior_rings(polygon)[seg_id.ring_index],
|
||||
seg_id, second,
|
||||
point
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Box, bool Reverse, typename SegmentIdentifier, typename PointOut>
|
||||
struct copy_segment_point_box
|
||||
{
|
||||
static inline bool apply(Box const& box,
|
||||
SegmentIdentifier const& seg_id, bool second,
|
||||
PointOut& point)
|
||||
{
|
||||
int index = seg_id.segment_index;
|
||||
if (second)
|
||||
{
|
||||
index++;
|
||||
}
|
||||
|
||||
boost::array<typename point_type<Box>::type, 4> bp;
|
||||
assign_box_corners_oriented<Reverse>(box, bp);
|
||||
point = bp[index % 4];
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}} // namespace detail::copy_segments
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag,
|
||||
typename GeometryIn,
|
||||
bool Reverse,
|
||||
typename SegmentIdentifier,
|
||||
typename PointOut
|
||||
>
|
||||
struct copy_segment_point
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
|
||||
, (types<GeometryIn>)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
template <typename LineString, bool Reverse, typename SegmentIdentifier, typename PointOut>
|
||||
struct copy_segment_point<linestring_tag, LineString, Reverse, SegmentIdentifier, PointOut>
|
||||
: detail::copy_segments::copy_segment_point_range
|
||||
<
|
||||
LineString, Reverse, SegmentIdentifier, PointOut
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Ring, bool Reverse, typename SegmentIdentifier, typename PointOut>
|
||||
struct copy_segment_point<ring_tag, Ring, Reverse, SegmentIdentifier, PointOut>
|
||||
: detail::copy_segments::copy_segment_point_range
|
||||
<
|
||||
Ring, Reverse, SegmentIdentifier, PointOut
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename Polygon, bool Reverse, typename SegmentIdentifier, typename PointOut>
|
||||
struct copy_segment_point<polygon_tag, Polygon, Reverse, SegmentIdentifier, PointOut>
|
||||
: detail::copy_segments::copy_segment_point_polygon
|
||||
<
|
||||
Polygon, Reverse, SegmentIdentifier, PointOut
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Box, bool Reverse, typename SegmentIdentifier, typename PointOut>
|
||||
struct copy_segment_point<box_tag, Box, Reverse, SegmentIdentifier, PointOut>
|
||||
: detail::copy_segments::copy_segment_point_box
|
||||
<
|
||||
Box, Reverse, SegmentIdentifier, PointOut
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Helper function, copies a point from a segment
|
||||
\ingroup overlay
|
||||
*/
|
||||
template<bool Reverse, typename Geometry, typename SegmentIdentifier, typename PointOut>
|
||||
inline bool copy_segment_point(Geometry const& geometry,
|
||||
SegmentIdentifier const& seg_id, bool second,
|
||||
PointOut& point_out)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
return dispatch::copy_segment_point
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
Reverse,
|
||||
SegmentIdentifier,
|
||||
PointOut
|
||||
>::apply(geometry, seg_id, second, point_out);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Helper function, to avoid the same construct several times,
|
||||
copies a point, based on a source-index and two geometries
|
||||
\ingroup overlay
|
||||
*/
|
||||
template
|
||||
<
|
||||
bool Reverse1, bool Reverse2,
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename SegmentIdentifier,
|
||||
typename PointOut
|
||||
>
|
||||
inline bool copy_segment_point(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
SegmentIdentifier const& seg_id, bool second,
|
||||
PointOut& point_out)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
if (seg_id.source_index == 0)
|
||||
{
|
||||
return dispatch::copy_segment_point
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
Geometry1,
|
||||
Reverse1,
|
||||
SegmentIdentifier,
|
||||
PointOut
|
||||
>::apply(geometry1, seg_id, second, point_out);
|
||||
}
|
||||
else if (seg_id.source_index == 1)
|
||||
{
|
||||
return dispatch::copy_segment_point
|
||||
<
|
||||
typename tag<Geometry2>::type,
|
||||
Geometry2,
|
||||
Reverse2,
|
||||
SegmentIdentifier,
|
||||
PointOut
|
||||
>::apply(geometry2, seg_id, second, point_out);
|
||||
}
|
||||
// Exception?
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Helper function, to avoid the same construct several times,
|
||||
copies a point, based on a source-index and two geometries
|
||||
\ingroup overlay
|
||||
*/
|
||||
template
|
||||
<
|
||||
bool Reverse1, bool Reverse2,
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename SegmentIdentifier,
|
||||
typename PointOut
|
||||
>
|
||||
inline bool copy_segment_points(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
SegmentIdentifier const& seg_id,
|
||||
PointOut& point1, PointOut& point2)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
return copy_segment_point<Reverse1, Reverse2>(geometry1, geometry2, seg_id, false, point1)
|
||||
&& copy_segment_point<Reverse1, Reverse2>(geometry1, geometry2, seg_id, true, point2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENT_POINT_HPP
|
||||
278
test/external/boost/geometry/algorithms/detail/overlay/copy_segments.hpp
vendored
Normal file
278
test/external/boost/geometry/algorithms/detail/overlay/copy_segments.hpp
vendored
Normal file
@@ -0,0 +1,278 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENTS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENTS_HPP
|
||||
|
||||
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/core/ring_type.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/iterators/ever_circling_iterator.hpp>
|
||||
#include <boost/geometry/views/closeable_view.hpp>
|
||||
#include <boost/geometry/views/reversible_view.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace copy_segments
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Ring,
|
||||
bool Reverse,
|
||||
typename SegmentIdentifier,
|
||||
typename RangeOut
|
||||
>
|
||||
struct copy_segments_ring
|
||||
{
|
||||
typedef typename closeable_view
|
||||
<
|
||||
Ring const,
|
||||
closure<Ring>::value
|
||||
>::type cview_type;
|
||||
|
||||
typedef typename reversible_view
|
||||
<
|
||||
cview_type const,
|
||||
Reverse ? iterate_reverse : iterate_forward
|
||||
>::type rview_type;
|
||||
|
||||
typedef typename boost::range_iterator<rview_type const>::type iterator;
|
||||
typedef geometry::ever_circling_iterator<iterator> ec_iterator;
|
||||
|
||||
static inline void apply(Ring const& ring,
|
||||
SegmentIdentifier const& seg_id, int to_index,
|
||||
RangeOut& current_output)
|
||||
{
|
||||
cview_type cview(ring);
|
||||
rview_type view(cview);
|
||||
|
||||
// The problem: sometimes we want to from "3" to "2"
|
||||
// -> end = "3" -> end == begin
|
||||
// This is not convenient with iterators.
|
||||
|
||||
// So we use the ever-circling iterator and determine when to step out
|
||||
|
||||
int const from_index = seg_id.segment_index + 1;
|
||||
|
||||
// Sanity check
|
||||
BOOST_ASSERT(from_index < boost::size(view));
|
||||
|
||||
ec_iterator it(boost::begin(view), boost::end(view),
|
||||
boost::begin(view) + from_index);
|
||||
|
||||
// [2..4] -> 4 - 2 + 1 = 3 -> {2,3,4} -> OK
|
||||
// [4..2],size=6 -> 6 - 4 + 2 + 1 = 5 -> {4,5,0,1,2} -> OK
|
||||
// [1..1], travel the whole ring round
|
||||
typedef typename boost::range_difference<Ring>::type size_type;
|
||||
size_type const count = from_index <= to_index
|
||||
? to_index - from_index + 1
|
||||
: boost::size(view) - from_index + to_index + 1;
|
||||
|
||||
for (size_type i = 0; i < count; ++i, ++it)
|
||||
{
|
||||
detail::overlay::append_no_duplicates(current_output, *it);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Polygon,
|
||||
bool Reverse,
|
||||
typename SegmentIdentifier,
|
||||
typename RangeOut
|
||||
>
|
||||
struct copy_segments_polygon
|
||||
{
|
||||
static inline void apply(Polygon const& polygon,
|
||||
SegmentIdentifier const& seg_id, int to_index,
|
||||
RangeOut& current_output)
|
||||
{
|
||||
// Call ring-version with the right ring
|
||||
copy_segments_ring
|
||||
<
|
||||
typename geometry::ring_type<Polygon>::type,
|
||||
Reverse,
|
||||
SegmentIdentifier,
|
||||
RangeOut
|
||||
>::apply
|
||||
(
|
||||
seg_id.ring_index < 0
|
||||
? geometry::exterior_ring(polygon)
|
||||
: geometry::interior_rings(polygon)[seg_id.ring_index],
|
||||
seg_id, to_index,
|
||||
current_output
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Box,
|
||||
bool Reverse,
|
||||
typename SegmentIdentifier,
|
||||
typename RangeOut
|
||||
>
|
||||
struct copy_segments_box
|
||||
{
|
||||
static inline void apply(Box const& box,
|
||||
SegmentIdentifier const& seg_id, int to_index,
|
||||
RangeOut& current_output)
|
||||
{
|
||||
int index = seg_id.segment_index + 1;
|
||||
BOOST_ASSERT(index < 5);
|
||||
|
||||
int const count = index <= to_index
|
||||
? to_index - index + 1
|
||||
: 5 - index + to_index + 1;
|
||||
|
||||
// Create array of points, the fifth one closes it
|
||||
boost::array<typename point_type<Box>::type, 5> bp;
|
||||
assign_box_corners_oriented<Reverse>(box, bp);
|
||||
bp[4] = bp[0];
|
||||
|
||||
// (possibly cyclic) copy to output
|
||||
// (see comments in ring-version)
|
||||
for (int i = 0; i < count; i++, index++)
|
||||
{
|
||||
detail::overlay::append_no_duplicates(current_output, bp[index % 5]);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::copy_segments
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag,
|
||||
typename GeometryIn,
|
||||
bool Reverse,
|
||||
typename SegmentIdentifier,
|
||||
typename RangeOut
|
||||
>
|
||||
struct copy_segments
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
|
||||
, (types<GeometryIn>)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Ring,
|
||||
bool Reverse,
|
||||
typename SegmentIdentifier,
|
||||
typename RangeOut
|
||||
>
|
||||
struct copy_segments<ring_tag, Ring, Reverse, SegmentIdentifier, RangeOut>
|
||||
: detail::copy_segments::copy_segments_ring
|
||||
<
|
||||
Ring, Reverse, SegmentIdentifier, RangeOut
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Polygon,
|
||||
bool Reverse,
|
||||
typename SegmentIdentifier,
|
||||
typename RangeOut
|
||||
>
|
||||
struct copy_segments<polygon_tag, Polygon, Reverse, SegmentIdentifier, RangeOut>
|
||||
: detail::copy_segments::copy_segments_polygon
|
||||
<
|
||||
Polygon, Reverse, SegmentIdentifier, RangeOut
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Box,
|
||||
bool Reverse,
|
||||
typename SegmentIdentifier,
|
||||
typename RangeOut
|
||||
>
|
||||
struct copy_segments<box_tag, Box, Reverse, SegmentIdentifier, RangeOut>
|
||||
: detail::copy_segments::copy_segments_box
|
||||
<
|
||||
Box, Reverse, SegmentIdentifier, RangeOut
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief Copy segments from a geometry, starting with the specified segment (seg_id)
|
||||
until the specified index (to_index)
|
||||
\ingroup overlay
|
||||
*/
|
||||
template
|
||||
<
|
||||
bool Reverse,
|
||||
typename Geometry,
|
||||
typename SegmentIdentifier,
|
||||
typename RangeOut
|
||||
>
|
||||
inline void copy_segments(Geometry const& geometry,
|
||||
SegmentIdentifier const& seg_id, int to_index,
|
||||
RangeOut& range_out)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
dispatch::copy_segments
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
Reverse,
|
||||
SegmentIdentifier,
|
||||
RangeOut
|
||||
>::apply(geometry, seg_id, to_index, range_out);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENTS_HPP
|
||||
64
test/external/boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp
vendored
Normal file
64
test/external/boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_DEBUG_TURN_INFO_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_DEBUG_TURN_INFO_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/visit_info.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
inline char method_char(detail::overlay::method_type const& method)
|
||||
{
|
||||
using namespace detail::overlay;
|
||||
switch(method)
|
||||
{
|
||||
case method_none : return '-';
|
||||
case method_disjoint : return 'd';
|
||||
case method_crosses : return 'i';
|
||||
case method_touch : return 't';
|
||||
case method_touch_interior : return 'm';
|
||||
case method_collinear : return 'c';
|
||||
case method_equal : return 'e';
|
||||
default : return '?';
|
||||
}
|
||||
}
|
||||
|
||||
inline char operation_char(detail::overlay::operation_type const& operation)
|
||||
{
|
||||
using namespace detail::overlay;
|
||||
switch(operation)
|
||||
{
|
||||
case operation_none : return '-';
|
||||
case operation_union : return 'u';
|
||||
case operation_intersection : return 'i';
|
||||
case operation_blocked : return 'x';
|
||||
case operation_continue : return 'c';
|
||||
default : return '?';
|
||||
}
|
||||
}
|
||||
|
||||
inline char visited_char(detail::overlay::visit_info const& v)
|
||||
{
|
||||
if (v.rejected()) return 'R';
|
||||
if (v.started()) return 's';
|
||||
if (v.visited()) return 'v';
|
||||
if (v.none()) return '-';
|
||||
if (v.finished()) return 'f';
|
||||
return '?';
|
||||
}
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_DEBUG_TURN_INFO_HPP
|
||||
531
test/external/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp
vendored
Normal file
531
test/external/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp
vendored
Normal file
@@ -0,0 +1,531 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ENRICH_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ENRICH_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
|
||||
# include <iostream>
|
||||
# include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
|
||||
# include <boost/geometry/domains/gis/io/wkt/wkt.hpp>
|
||||
# define BOOST_GEOMETRY_DEBUG_IDENTIFIER
|
||||
#endif
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/range.hpp>
|
||||
|
||||
|
||||
|
||||
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_relative_order.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp>
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
|
||||
# include <boost/geometry/algorithms/detail/overlay/check_enrich.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
// Wraps "turn_operation" from turn_info.hpp,
|
||||
// giving it extra information
|
||||
template <typename TurnOperation>
|
||||
struct indexed_turn_operation
|
||||
{
|
||||
typedef TurnOperation type;
|
||||
|
||||
int index;
|
||||
int operation_index;
|
||||
bool discarded;
|
||||
TurnOperation subject;
|
||||
|
||||
inline indexed_turn_operation(int i, int oi, TurnOperation const& s)
|
||||
: index(i)
|
||||
, operation_index(oi)
|
||||
, discarded(false)
|
||||
, subject(s)
|
||||
{}
|
||||
};
|
||||
|
||||
template <typename IndexedTurnOperation>
|
||||
struct remove_discarded
|
||||
{
|
||||
inline bool operator()(IndexedTurnOperation const& operation) const
|
||||
{
|
||||
return operation.discarded;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename TurnPoints,
|
||||
typename Indexed,
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2,
|
||||
typename Strategy
|
||||
>
|
||||
struct sort_on_segment_and_distance
|
||||
{
|
||||
inline sort_on_segment_and_distance(TurnPoints const& turn_points
|
||||
, Geometry1 const& geometry1
|
||||
, Geometry2 const& geometry2
|
||||
, Strategy const& strategy
|
||||
, bool* clustered)
|
||||
: m_turn_points(turn_points)
|
||||
, m_geometry1(geometry1)
|
||||
, m_geometry2(geometry2)
|
||||
, m_strategy(strategy)
|
||||
, m_clustered(clustered)
|
||||
{
|
||||
}
|
||||
|
||||
private :
|
||||
|
||||
TurnPoints const& m_turn_points;
|
||||
Geometry1 const& m_geometry1;
|
||||
Geometry2 const& m_geometry2;
|
||||
Strategy const& m_strategy;
|
||||
mutable bool* m_clustered;
|
||||
|
||||
inline bool consider_relative_order(Indexed const& left,
|
||||
Indexed const& right) const
|
||||
{
|
||||
typedef typename geometry::point_type<Geometry1>::type point_type;
|
||||
point_type pi, pj, ri, rj, si, sj;
|
||||
|
||||
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
|
||||
left.subject.seg_id,
|
||||
pi, pj);
|
||||
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
|
||||
left.subject.other_id,
|
||||
ri, rj);
|
||||
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
|
||||
right.subject.other_id,
|
||||
si, sj);
|
||||
|
||||
int const order = get_relative_order
|
||||
<
|
||||
point_type
|
||||
>::apply(pi, pj,ri, rj, si, sj);
|
||||
//debug("r/o", order == -1);
|
||||
return order == -1;
|
||||
}
|
||||
|
||||
public :
|
||||
|
||||
// Note that left/right do NOT correspond to m_geometry1/m_geometry2
|
||||
// but to the "indexed_turn_operation"
|
||||
inline bool operator()(Indexed const& left, Indexed const& right) const
|
||||
{
|
||||
segment_identifier const& sl = left.subject.seg_id;
|
||||
segment_identifier const& sr = right.subject.seg_id;
|
||||
|
||||
if (sl == sr
|
||||
&& geometry::math::equals(left.subject.enriched.distance
|
||||
, right.subject.enriched.distance))
|
||||
{
|
||||
// Both left and right are located on the SAME segment.
|
||||
|
||||
// First check "real" intersection (crosses)
|
||||
// -> distance zero due to precision, solve it by sorting
|
||||
if (m_turn_points[left.index].method == method_crosses
|
||||
&& m_turn_points[right.index].method == method_crosses)
|
||||
{
|
||||
return consider_relative_order(left, right);
|
||||
}
|
||||
|
||||
// If that is not the case, cluster it later on.
|
||||
// Indicate that this is necessary.
|
||||
*m_clustered = true;
|
||||
|
||||
return left.index < right.index;
|
||||
}
|
||||
return sl == sr
|
||||
? left.subject.enriched.distance < right.subject.enriched.distance
|
||||
: sl < sr;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename Turns, typename Operations>
|
||||
inline void update_discarded(Turns& turn_points, Operations& operations)
|
||||
{
|
||||
// Vice-versa, set discarded to true for discarded operations;
|
||||
// AND set discarded points to true
|
||||
for (typename boost::range_iterator<Operations>::type it = boost::begin(operations);
|
||||
it != boost::end(operations);
|
||||
++it)
|
||||
{
|
||||
if (turn_points[it->index].discarded)
|
||||
{
|
||||
it->discarded = true;
|
||||
}
|
||||
else if (it->discarded)
|
||||
{
|
||||
turn_points[it->index].discarded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Sorts IP-s of this ring on segment-identifier, and if on same segment,
|
||||
// on distance.
|
||||
// Then assigns for each IP which is the next IP on this segment,
|
||||
// plus the vertex-index to travel to, plus the next IP
|
||||
// (might be on another segment)
|
||||
template
|
||||
<
|
||||
typename IndexType,
|
||||
bool Reverse1, bool Reverse2,
|
||||
typename Container,
|
||||
typename TurnPoints,
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Strategy
|
||||
>
|
||||
inline void enrich_sort(Container& operations,
|
||||
TurnPoints& turn_points,
|
||||
operation_type for_operation,
|
||||
Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename IndexType::type operations_type;
|
||||
|
||||
bool clustered = false;
|
||||
std::sort(boost::begin(operations),
|
||||
boost::end(operations),
|
||||
sort_on_segment_and_distance
|
||||
<
|
||||
TurnPoints,
|
||||
IndexType,
|
||||
Geometry1, Geometry2,
|
||||
Reverse1, Reverse2,
|
||||
Strategy
|
||||
>(turn_points, geometry1, geometry2, strategy, &clustered));
|
||||
|
||||
// DONT'T discard xx / (for union) ix / ii / (for intersection) ux / uu here
|
||||
// It would give way to "lonely" ui turn points, traveling all
|
||||
// the way round. See #105
|
||||
|
||||
if (clustered)
|
||||
{
|
||||
typedef typename boost::range_iterator<Container>::type nc_iterator;
|
||||
nc_iterator it = boost::begin(operations);
|
||||
nc_iterator begin_cluster = boost::end(operations);
|
||||
for (nc_iterator prev = it++;
|
||||
it != boost::end(operations);
|
||||
prev = it++)
|
||||
{
|
||||
operations_type& prev_op = turn_points[prev->index]
|
||||
.operations[prev->operation_index];
|
||||
operations_type& op = turn_points[it->index]
|
||||
.operations[it->operation_index];
|
||||
|
||||
if (prev_op.seg_id == op.seg_id
|
||||
&& (turn_points[prev->index].method != method_crosses
|
||||
|| turn_points[it->index].method != method_crosses)
|
||||
&& geometry::math::equals(prev_op.enriched.distance,
|
||||
op.enriched.distance))
|
||||
{
|
||||
if (begin_cluster == boost::end(operations))
|
||||
{
|
||||
begin_cluster = prev;
|
||||
}
|
||||
}
|
||||
else if (begin_cluster != boost::end(operations))
|
||||
{
|
||||
handle_cluster<IndexType, Reverse1, Reverse2>(begin_cluster, it, turn_points,
|
||||
for_operation, geometry1, geometry2, strategy);
|
||||
begin_cluster = boost::end(operations);
|
||||
}
|
||||
}
|
||||
if (begin_cluster != boost::end(operations))
|
||||
{
|
||||
handle_cluster<IndexType, Reverse1, Reverse2>(begin_cluster, it, turn_points,
|
||||
for_operation, geometry1, geometry2, strategy);
|
||||
}
|
||||
}
|
||||
|
||||
update_discarded(turn_points, operations);
|
||||
}
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename IndexType,
|
||||
typename Container,
|
||||
typename TurnPoints
|
||||
>
|
||||
inline void enrich_discard(Container& operations, TurnPoints& turn_points)
|
||||
{
|
||||
update_discarded(turn_points, operations);
|
||||
|
||||
// Then delete discarded operations from vector
|
||||
remove_discarded<IndexType> predicate;
|
||||
operations.erase(
|
||||
std::remove_if(boost::begin(operations),
|
||||
boost::end(operations),
|
||||
predicate),
|
||||
boost::end(operations));
|
||||
}
|
||||
|
||||
template
|
||||
<
|
||||
typename IndexType,
|
||||
typename Container,
|
||||
typename TurnPoints,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Strategy
|
||||
>
|
||||
inline void enrich_assign(Container& operations,
|
||||
TurnPoints& turn_points,
|
||||
operation_type for_operation,
|
||||
Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename IndexType::type operations_type;
|
||||
typedef typename boost::range_iterator<Container const>::type iterator_type;
|
||||
|
||||
|
||||
if (operations.size() > 0)
|
||||
{
|
||||
// Assign travel-to-vertex/ip index for each turning point.
|
||||
// Because IP's are circular, PREV starts at the very last one,
|
||||
// being assigned from the first one.
|
||||
// "next ip on same segment" should not be considered circular.
|
||||
bool first = true;
|
||||
iterator_type it = boost::begin(operations);
|
||||
for (iterator_type prev = it + (boost::size(operations) - 1);
|
||||
it != boost::end(operations);
|
||||
prev = it++)
|
||||
{
|
||||
operations_type& prev_op
|
||||
= turn_points[prev->index].operations[prev->operation_index];
|
||||
operations_type& op
|
||||
= turn_points[it->index].operations[it->operation_index];
|
||||
|
||||
prev_op.enriched.travels_to_ip_index
|
||||
= it->index;
|
||||
prev_op.enriched.travels_to_vertex_index
|
||||
= it->subject.seg_id.segment_index;
|
||||
|
||||
if (! first
|
||||
&& prev_op.seg_id.segment_index == op.seg_id.segment_index)
|
||||
{
|
||||
prev_op.enriched.next_ip_index = it->index;
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
// DEBUG
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
|
||||
{
|
||||
for (iterator_type it = boost::begin(operations);
|
||||
it != boost::end(operations);
|
||||
++it)
|
||||
{
|
||||
operations_type& op = turn_points[it->index]
|
||||
.operations[it->operation_index];
|
||||
|
||||
std::cout << it->index
|
||||
<< " meth: " << method_char(turn_points[it->index].method)
|
||||
<< " seg: " << op.seg_id
|
||||
<< " dst: " << boost::numeric_cast<double>(op.enriched.distance)
|
||||
<< " op: " << operation_char(turn_points[it->index].operations[0].operation)
|
||||
<< operation_char(turn_points[it->index].operations[1].operation)
|
||||
<< " dsc: " << (turn_points[it->index].discarded ? "T" : "F")
|
||||
<< " ->vtx " << op.enriched.travels_to_vertex_index
|
||||
<< " ->ip " << op.enriched.travels_to_ip_index
|
||||
<< " ->nxt ip " << op.enriched.next_ip_index
|
||||
//<< " vis: " << visited_char(op.visited)
|
||||
<< std::endl;
|
||||
;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// END DEBUG
|
||||
|
||||
}
|
||||
|
||||
|
||||
template <typename IndexedType, typename TurnPoints, typename MappedVector>
|
||||
inline void create_map(TurnPoints const& turn_points, MappedVector& mapped_vector)
|
||||
{
|
||||
typedef typename boost::range_value<TurnPoints>::type turn_point_type;
|
||||
typedef typename turn_point_type::container_type container_type;
|
||||
|
||||
int index = 0;
|
||||
for (typename boost::range_iterator<TurnPoints const>::type
|
||||
it = boost::begin(turn_points);
|
||||
it != boost::end(turn_points);
|
||||
++it, ++index)
|
||||
{
|
||||
// Add operations on this ring, but skip discarded ones
|
||||
if (! it->discarded)
|
||||
{
|
||||
int op_index = 0;
|
||||
for (typename boost::range_iterator<container_type const>::type
|
||||
op_it = boost::begin(it->operations);
|
||||
op_it != boost::end(it->operations);
|
||||
++op_it, ++op_index)
|
||||
{
|
||||
// We should NOT skip blocked operations here
|
||||
// because they can be relevant for "the other side"
|
||||
// NOT if (op_it->operation != operation_blocked)
|
||||
|
||||
ring_identifier ring_id
|
||||
(
|
||||
op_it->seg_id.source_index,
|
||||
op_it->seg_id.multi_index,
|
||||
op_it->seg_id.ring_index
|
||||
);
|
||||
mapped_vector[ring_id].push_back
|
||||
(
|
||||
IndexedType(index, op_index, *op_it)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif //DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief All intersection points are enriched with successor information
|
||||
\ingroup overlay
|
||||
\tparam TurnPoints type of intersection container
|
||||
(e.g. vector of "intersection/turn point"'s)
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam Strategy side strategy type
|
||||
\param turn_points container containing intersectionpoints
|
||||
\param for_operation operation_type (union or intersection)
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param strategy strategy
|
||||
*/
|
||||
template
|
||||
<
|
||||
bool Reverse1, bool Reverse2,
|
||||
typename TurnPoints,
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Strategy
|
||||
>
|
||||
inline void enrich_intersection_points(TurnPoints& turn_points,
|
||||
detail::overlay::operation_type for_operation,
|
||||
Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename boost::range_value<TurnPoints>::type turn_point_type;
|
||||
typedef typename turn_point_type::turn_operation_type turn_operation_type;
|
||||
typedef detail::overlay::indexed_turn_operation
|
||||
<
|
||||
turn_operation_type
|
||||
> indexed_turn_operation;
|
||||
|
||||
typedef std::map
|
||||
<
|
||||
ring_identifier,
|
||||
std::vector<indexed_turn_operation>
|
||||
> mapped_vector_type;
|
||||
|
||||
// DISCARD ALL UU
|
||||
// #76 is the reason that this is necessary...
|
||||
// With uu, at all points there is the risk that rings are being traversed twice or more.
|
||||
// Without uu, all rings having only uu will be untouched and gathered by assemble
|
||||
for (typename boost::range_iterator<TurnPoints>::type
|
||||
it = boost::begin(turn_points);
|
||||
it != boost::end(turn_points);
|
||||
++it)
|
||||
{
|
||||
if (it->both(detail::overlay::operation_union))
|
||||
{
|
||||
it->discarded = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Create a map of vectors of indexed operation-types to be able
|
||||
// to sort intersection points PER RING
|
||||
mapped_vector_type mapped_vector;
|
||||
|
||||
detail::overlay::create_map<indexed_turn_operation>(turn_points, mapped_vector);
|
||||
|
||||
|
||||
// No const-iterator; contents of mapped copy is temporary,
|
||||
// and changed by enrich
|
||||
for (typename mapped_vector_type::iterator mit
|
||||
= mapped_vector.begin();
|
||||
mit != mapped_vector.end();
|
||||
++mit)
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
|
||||
std::cout << "ENRICH-sort Ring "
|
||||
<< mit->first << std::endl;
|
||||
#endif
|
||||
detail::overlay::enrich_sort<indexed_turn_operation, Reverse1, Reverse2>(mit->second, turn_points, for_operation,
|
||||
geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
for (typename mapped_vector_type::iterator mit
|
||||
= mapped_vector.begin();
|
||||
mit != mapped_vector.end();
|
||||
++mit)
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
|
||||
std::cout << "ENRICH-discard Ring "
|
||||
<< mit->first << std::endl;
|
||||
#endif
|
||||
detail::overlay::enrich_discard<indexed_turn_operation>(mit->second, turn_points);
|
||||
}
|
||||
|
||||
for (typename mapped_vector_type::iterator mit
|
||||
= mapped_vector.begin();
|
||||
mit != mapped_vector.end();
|
||||
++mit)
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
|
||||
std::cout << "ENRICH-assign Ring "
|
||||
<< mit->first << std::endl;
|
||||
#endif
|
||||
detail::overlay::enrich_assign<indexed_turn_operation>(mit->second, turn_points, for_operation,
|
||||
geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
|
||||
//detail::overlay::check_graph(turn_points, for_operation);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ENRICH_HPP
|
||||
76
test/external/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp
vendored
Normal file
76
test/external/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ENRICHMENT_INFO_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ENRICHMENT_INFO_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/strategies/distance.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
|
||||
/*!
|
||||
\brief Keeps info to enrich intersection info (per source)
|
||||
\details Class to keep information necessary for traversal phase (a phase
|
||||
of the overlay process). The information is gathered during the
|
||||
enrichment phase
|
||||
*/
|
||||
template<typename P>
|
||||
struct enrichment_info
|
||||
{
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
typename strategy::distance::services::comparable_type
|
||||
<
|
||||
typename strategy::distance::services::default_strategy
|
||||
<
|
||||
point_tag,
|
||||
P
|
||||
>::type
|
||||
>::type
|
||||
>::type distance_type;
|
||||
|
||||
inline enrichment_info()
|
||||
: travels_to_vertex_index(-1)
|
||||
, travels_to_ip_index(-1)
|
||||
, next_ip_index(-1)
|
||||
, distance(distance_type())
|
||||
{}
|
||||
|
||||
// vertex to which is free travel after this IP,
|
||||
// so from "segment_index+1" to "travels_to_vertex_index", without IP-s,
|
||||
// can be -1
|
||||
int travels_to_vertex_index;
|
||||
|
||||
// same but now IP index, so "next IP index" but not on THIS segment
|
||||
int travels_to_ip_index;
|
||||
|
||||
// index of next IP on this segment, -1 if there is no one
|
||||
int next_ip_index;
|
||||
|
||||
distance_type distance; // distance-measurement from segment.first to IP
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif //DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ENRICHMENT_INFO_HPP
|
||||
146
test/external/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp
vendored
Normal file
146
test/external/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_INTERSECTION_POINTS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_INTERSECTION_POINTS_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/geometry/algorithms/convert.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/segment.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace get_intersection_points
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename TurnInfo
|
||||
>
|
||||
struct get_turn_without_info
|
||||
{
|
||||
typedef strategy_intersection
|
||||
<
|
||||
typename cs_tag<typename TurnInfo::point_type>::type,
|
||||
Point1,
|
||||
Point2,
|
||||
typename TurnInfo::point_type
|
||||
> si;
|
||||
|
||||
typedef typename si::segment_intersection_strategy_type strategy;
|
||||
|
||||
|
||||
|
||||
template <typename OutputIterator>
|
||||
static inline OutputIterator apply(
|
||||
Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
TurnInfo const& tp_model,
|
||||
OutputIterator out)
|
||||
{
|
||||
typedef model::referring_segment<Point1 const> segment_type1;
|
||||
typedef model::referring_segment<Point1 const> segment_type2;
|
||||
segment_type1 p1(pi, pj), p2(pj, pk);
|
||||
segment_type2 q1(qi, qj), q2(qj, qk);
|
||||
|
||||
//
|
||||
typename strategy::return_type result = strategy::apply(p1, q1);
|
||||
|
||||
for (std::size_t i = 0; i < result.template get<0>().count; i++)
|
||||
{
|
||||
|
||||
TurnInfo tp;
|
||||
geometry::convert(result.template get<0>().intersections[i], tp.point);
|
||||
*out++ = tp;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::get_intersection_points
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Turns
|
||||
>
|
||||
inline void get_intersection_points(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Turns& turns)
|
||||
{
|
||||
concept::check_concepts_and_equal_dimensions<Geometry1 const, Geometry2 const>();
|
||||
|
||||
typedef detail::get_intersection_points::get_turn_without_info
|
||||
<
|
||||
typename point_type<Geometry1>::type,
|
||||
typename point_type<Geometry2>::type,
|
||||
typename boost::range_value<Turns>::type
|
||||
> TurnPolicy;
|
||||
|
||||
typedef typename strategy_intersection
|
||||
<
|
||||
typename cs_tag<Geometry1>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
typename boost::range_value<Turns>::type
|
||||
>::segment_intersection_strategy_type segment_intersection_strategy_type;
|
||||
|
||||
detail::get_turns::no_interrupt_policy interrupt_policy;
|
||||
|
||||
boost::mpl::if_c
|
||||
<
|
||||
reverse_dispatch<Geometry1, Geometry2>::type::value,
|
||||
dispatch::get_turns_reversed
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
Geometry1, Geometry2,
|
||||
false, false,
|
||||
Turns, TurnPolicy,
|
||||
//segment_intersection_strategy_type,
|
||||
detail::get_turns::no_interrupt_policy
|
||||
>,
|
||||
dispatch::get_turns
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
Geometry1, Geometry2,
|
||||
false, false,
|
||||
Turns, TurnPolicy,
|
||||
//segment_intersection_strategy_type,
|
||||
detail::get_turns::no_interrupt_policy
|
||||
>
|
||||
>::type::apply(
|
||||
0, geometry1,
|
||||
1, geometry2,
|
||||
turns, interrupt_policy);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_INTERSECTION_POINTS_HPP
|
||||
108
test/external/boost/geometry/algorithms/detail/overlay/get_relative_order.hpp
vendored
Normal file
108
test/external/boost/geometry/algorithms/detail/overlay/get_relative_order.hpp
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RELATIVE_ORDER_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RELATIVE_ORDER_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/algorithms/distance.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/intersection.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
|
||||
/*!
|
||||
\brief Get relative order
|
||||
\details Can indicate which of two segments R and S,
|
||||
both crossing a common segment P, comes first.
|
||||
If the two segments cross P very close (e.g. in a spike),
|
||||
the distance between the intersection points can be zero,
|
||||
but we still need to know which comes first.
|
||||
Therefore, it is useful that using sides we are able to discover this.
|
||||
*/
|
||||
template <typename Point1>
|
||||
struct get_relative_order
|
||||
{
|
||||
typedef strategy_intersection
|
||||
<
|
||||
typename cs_tag<Point1>::type,
|
||||
Point1,
|
||||
Point1,
|
||||
Point1
|
||||
> si;
|
||||
|
||||
typedef typename si::side_strategy_type strategy;
|
||||
|
||||
template <typename Point>
|
||||
static inline int value_via_product(Point const& ti, Point const& tj,
|
||||
Point const& ui, Point const& uj, int factor)
|
||||
{
|
||||
int const side_ti_u = strategy::apply(ti, tj, ui);
|
||||
int const side_tj_u = strategy::apply(ti, tj, uj);
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_RELATIVE_ORDER
|
||||
std::cout << (factor == 1 ? " r//s " : " s//r ")
|
||||
<< side_ti_u << " / " << side_tj_u;
|
||||
#endif
|
||||
|
||||
return side_ti_u * side_tj_u >= 0
|
||||
? factor * (side_ti_u != 0 ? side_ti_u : side_tj_u)
|
||||
: 0;
|
||||
}
|
||||
|
||||
|
||||
static inline int apply(
|
||||
Point1 const& pi, Point1 const& pj,
|
||||
Point1 const& ri, Point1 const& rj,
|
||||
Point1 const& si, Point1 const& sj)
|
||||
{
|
||||
int const side_ri_p = strategy::apply(pi, pj, ri);
|
||||
int const side_si_p = strategy::apply(pi, pj, si);
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_RELATIVE_ORDER
|
||||
int const side_rj_p = strategy::apply(pi, pj, rj);
|
||||
int const side_sj_p = strategy::apply(pi, pj, sj);
|
||||
std::cout << "r//p: " << side_ri_p << " / " << side_rj_p;
|
||||
std::cout << " s//p: " << side_si_p << " / " << side_sj_p;
|
||||
#endif
|
||||
|
||||
int value = value_via_product(si, sj, ri, rj, 1);
|
||||
if (value == 0)
|
||||
{
|
||||
value = value_via_product(ri, rj, si, sj, -1);
|
||||
}
|
||||
|
||||
int const order = side_ri_p * side_ri_p * side_si_p * value;
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_RELATIVE_ORDER
|
||||
std::cout
|
||||
<< " o: " << order
|
||||
<< std::endl << std::endl;
|
||||
#endif
|
||||
|
||||
return order;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif //DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RELATIVE_ORDER_HPP
|
||||
102
test/external/boost/geometry/algorithms/detail/overlay/get_ring.hpp
vendored
Normal file
102
test/external/boost/geometry/algorithms/detail/overlay/get_ring.hpp
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RING_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RING_HPP
|
||||
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/range.hpp>
|
||||
|
||||
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
|
||||
template<typename Tag>
|
||||
struct get_ring
|
||||
{};
|
||||
|
||||
// A container 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)
|
||||
{
|
||||
return container[id.multi_index];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
template<>
|
||||
struct get_ring<ring_tag>
|
||||
{
|
||||
template<typename Ring>
|
||||
static inline Ring const& apply(ring_identifier const& , Ring const& ring)
|
||||
{
|
||||
return ring;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
struct get_ring<box_tag>
|
||||
{
|
||||
template<typename Box>
|
||||
static inline Box const& apply(ring_identifier const& ,
|
||||
Box const& box)
|
||||
{
|
||||
return box;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
struct get_ring<polygon_tag>
|
||||
{
|
||||
template<typename Polygon>
|
||||
static inline typename ring_return_type<Polygon const>::type const apply(
|
||||
ring_identifier const& id,
|
||||
Polygon const& polygon)
|
||||
{
|
||||
BOOST_ASSERT
|
||||
(
|
||||
id.ring_index >= -1
|
||||
&& id.ring_index < boost::size(interior_rings(polygon))
|
||||
);
|
||||
return id.ring_index < 0
|
||||
? exterior_ring(polygon)
|
||||
: interior_rings(polygon)[id.ring_index];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RING_HPP
|
||||
897
test/external/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp
vendored
Normal file
897
test/external/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp
vendored
Normal file
@@ -0,0 +1,897 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HPP
|
||||
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/strategies/intersection.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/convert.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/segment.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
|
||||
struct base_turn_handler
|
||||
{
|
||||
// Returns true if both sides are opposite
|
||||
static inline bool opposite(int side1, int side2)
|
||||
{
|
||||
// We cannot state side1 == -side2, because 0 == -0
|
||||
// So either side1*side2==-1 or side1==-side2 && side1 != 0
|
||||
return side1 * side2 == -1;
|
||||
}
|
||||
|
||||
// Same side of a segment (not being 0)
|
||||
static inline bool same(int side1, int side2)
|
||||
{
|
||||
return side1 * side2 == 1;
|
||||
}
|
||||
|
||||
// Both continue
|
||||
template <typename TurnInfo>
|
||||
static inline void both(TurnInfo& ti, operation_type const op)
|
||||
{
|
||||
ti.operations[0].operation = op;
|
||||
ti.operations[1].operation = op;
|
||||
}
|
||||
|
||||
// If condition, first union/second intersection, else vice versa
|
||||
template <typename TurnInfo>
|
||||
static inline void ui_else_iu(bool condition, TurnInfo& ti)
|
||||
{
|
||||
ti.operations[0].operation = condition
|
||||
? operation_union : operation_intersection;
|
||||
ti.operations[1].operation = condition
|
||||
? operation_intersection : operation_union;
|
||||
}
|
||||
|
||||
// If condition, both union, else both intersection
|
||||
template <typename TurnInfo>
|
||||
static inline void uu_else_ii(bool condition, TurnInfo& ti)
|
||||
{
|
||||
both(ti, condition ? operation_union : operation_intersection);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename TurnInfo,
|
||||
typename SideStrategy
|
||||
>
|
||||
struct touch_interior : public base_turn_handler
|
||||
{
|
||||
// Index: 0, P is the interior, Q is touching and vice versa
|
||||
template
|
||||
<
|
||||
int Index,
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename IntersectionInfo,
|
||||
typename DirInfo
|
||||
>
|
||||
static inline void apply(
|
||||
Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
TurnInfo& ti,
|
||||
IntersectionInfo const& intersection_info,
|
||||
DirInfo const& dir_info)
|
||||
{
|
||||
ti.method = method_touch_interior;
|
||||
geometry::convert(intersection_info.intersections[0], ti.point);
|
||||
|
||||
// Both segments of q touch segment p somewhere in its interior
|
||||
// 1) We know: if q comes from LEFT or RIGHT
|
||||
// (i.e. dir_info.sides.get<Index,0>() == 1 or -1)
|
||||
// 2) Important is: if q_k goes to LEFT, RIGHT, COLLINEAR
|
||||
// and, if LEFT/COLL, if it is lying LEFT or RIGHT w.r.t. q_i
|
||||
|
||||
static int const index_p = Index;
|
||||
static int const index_q = 1 - Index;
|
||||
|
||||
int const side_qi_p = dir_info.sides.template get<index_q, 0>();
|
||||
int const side_qk_p = SideStrategy::apply(pi, pj, qk);
|
||||
|
||||
if (side_qi_p == -side_qk_p)
|
||||
{
|
||||
// Q crosses P from left->right or from right->left (test "ML1")
|
||||
// Union: folow P (left->right) or Q (right->left)
|
||||
// Intersection: other turn
|
||||
int index = side_qk_p == -1 ? index_p : index_q;
|
||||
ti.operations[index].operation = operation_union;
|
||||
ti.operations[1 - index].operation = operation_intersection;
|
||||
return;
|
||||
}
|
||||
|
||||
int const side_qk_q = SideStrategy::apply(qi, qj, qk);
|
||||
|
||||
if (side_qi_p == -1 && side_qk_p == -1 && side_qk_q == 1)
|
||||
{
|
||||
// Q turns left on the right side of P (test "MR3")
|
||||
// Both directions for "intersection"
|
||||
both(ti, operation_intersection);
|
||||
}
|
||||
else if (side_qi_p == 1 && side_qk_p == 1 && side_qk_q == -1)
|
||||
{
|
||||
// Q turns right on the left side of P (test "ML3")
|
||||
// Union: take both operation
|
||||
// Intersection: skip
|
||||
both(ti, operation_union);
|
||||
}
|
||||
else if (side_qi_p == side_qk_p && side_qi_p == side_qk_q)
|
||||
{
|
||||
// Q turns left on the left side of P (test "ML2")
|
||||
// or Q turns right on the right side of P (test "MR2")
|
||||
// Union: take left turn (Q if Q turns left, P if Q turns right)
|
||||
// Intersection: other turn
|
||||
int index = side_qk_q == 1 ? index_q : index_p;
|
||||
ti.operations[index].operation = operation_union;
|
||||
ti.operations[1 - index].operation = operation_intersection;
|
||||
}
|
||||
else if (side_qk_p == 0)
|
||||
{
|
||||
// Q intersects on interior of P and continues collinearly
|
||||
if (side_qk_q == side_qi_p)
|
||||
{
|
||||
// Collinearly in the same direction
|
||||
// (Q comes from left of P and turns left,
|
||||
// OR Q comes from right of P and turns right)
|
||||
// Omit intersection point.
|
||||
// Union: just continue
|
||||
// Intersection: just continue
|
||||
both(ti, operation_continue);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Opposite direction, which is never travelled.
|
||||
// If Q turns left, P continues for intersection
|
||||
// If Q turns right, P continues for union
|
||||
ti.operations[Index].operation = side_qk_q == 1
|
||||
? operation_intersection
|
||||
: operation_union;
|
||||
ti.operations[1 - Index].operation = operation_blocked;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Should not occur!
|
||||
ti.method = method_error;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename TurnInfo,
|
||||
typename SideStrategy
|
||||
>
|
||||
struct touch : public base_turn_handler
|
||||
{
|
||||
static inline bool between(int side1, int side2, int turn)
|
||||
{
|
||||
return side1 == side2 && ! opposite(side1, turn);
|
||||
}
|
||||
|
||||
/*static inline void block_second(bool block, TurnInfo& ti)
|
||||
{
|
||||
if (block)
|
||||
{
|
||||
ti.operations[1].operation = operation_blocked;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename IntersectionInfo,
|
||||
typename DirInfo
|
||||
>
|
||||
static inline void apply(
|
||||
Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
TurnInfo& ti,
|
||||
IntersectionInfo const& intersection_info,
|
||||
DirInfo const& dir_info)
|
||||
{
|
||||
ti.method = method_touch;
|
||||
geometry::convert(intersection_info.intersections[0], ti.point);
|
||||
|
||||
int const side_qi_p1 = dir_info.sides.template get<1, 0>();
|
||||
int const side_qk_p1 = SideStrategy::apply(pi, pj, qk);
|
||||
|
||||
|
||||
// If Qi and Qk are both at same side of Pi-Pj,
|
||||
// or collinear (so: not opposite sides)
|
||||
if (! opposite(side_qi_p1, side_qk_p1))
|
||||
{
|
||||
int const side_pk_q2 = SideStrategy::apply(qj, qk, pk);
|
||||
int const side_pk_p = SideStrategy::apply(pi, pj, pk);
|
||||
int const side_qk_q = SideStrategy::apply(qi, qj, qk);
|
||||
bool const q_turns_left = side_qk_q == 1;
|
||||
bool const block_q = side_qk_p1 == 0
|
||||
&& ! same(side_qi_p1, side_qk_q);
|
||||
|
||||
// If Pk at same side as Qi/Qk
|
||||
// (the "or" is for collinear case)
|
||||
// or Q is fully collinear && P turns not to left
|
||||
if (side_pk_p == side_qi_p1
|
||||
|| side_pk_p == side_qk_p1
|
||||
|| (side_qi_p1 == 0 && side_qk_p1 == 0 && side_pk_p != -1)
|
||||
)
|
||||
{
|
||||
// Collinear -> lines join, continue
|
||||
// (#BRL2)
|
||||
if (side_pk_q2 == 0 && ! block_q)
|
||||
{
|
||||
both(ti, operation_continue);
|
||||
return;
|
||||
}
|
||||
|
||||
int const side_pk_q1 = SideStrategy::apply(qi, qj, pk);
|
||||
|
||||
|
||||
// Collinear opposite case -> block P
|
||||
// (#BRL4, #BLR8)
|
||||
if (side_pk_q1 == 0)
|
||||
{
|
||||
ti.operations[0].operation = operation_blocked;
|
||||
// Q turns right -> union (both independant),
|
||||
// Q turns left -> intersection
|
||||
ti.operations[1].operation = block_q ? operation_blocked
|
||||
: q_turns_left ? operation_intersection
|
||||
: operation_union;
|
||||
return;
|
||||
}
|
||||
|
||||
// Pk between Qi and Qk
|
||||
// (#BRL3, #BRL7)
|
||||
if (between(side_pk_q1, side_pk_q2, side_qk_q))
|
||||
{
|
||||
ui_else_iu(q_turns_left, ti);
|
||||
if (block_q)
|
||||
{
|
||||
ti.operations[1].operation = operation_blocked;
|
||||
}
|
||||
//block_second(block_q, ti);
|
||||
return;
|
||||
}
|
||||
|
||||
// Pk between Qk and P, so left of Qk (if Q turns right) and vv
|
||||
// (#BRL1)
|
||||
if (side_pk_q2 == -side_qk_q)
|
||||
{
|
||||
ui_else_iu(! q_turns_left, ti);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// (#BRL5, #BRL9)
|
||||
if (side_pk_q1 == -side_qk_q)
|
||||
{
|
||||
uu_else_ii(! q_turns_left, ti);
|
||||
if (block_q)
|
||||
{
|
||||
ti.operations[1].operation = operation_blocked;
|
||||
}
|
||||
//block_second(block_q, ti);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pk at other side than Qi/Pk
|
||||
int const side_qk_q = SideStrategy::apply(qi, qj, qk);
|
||||
bool const q_turns_left = side_qk_q == 1;
|
||||
|
||||
ti.operations[0].operation = q_turns_left
|
||||
? operation_intersection
|
||||
: operation_union;
|
||||
ti.operations[1].operation = block_q
|
||||
? operation_blocked
|
||||
: side_qi_p1 == 1 || side_qk_p1 == 1
|
||||
? operation_union
|
||||
: operation_intersection;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// From left to right or from right to left
|
||||
int const side_pk_p = SideStrategy::apply(pi, pj, pk);
|
||||
bool const right_to_left = side_qk_p1 == 1;
|
||||
|
||||
// If p turns into direction of qi (1,2)
|
||||
if (side_pk_p == side_qi_p1)
|
||||
{
|
||||
int const side_pk_q1 = SideStrategy::apply(qi, qj, pk);
|
||||
|
||||
// Collinear opposite case -> block P
|
||||
if (side_pk_q1 == 0)
|
||||
{
|
||||
ti.operations[0].operation = operation_blocked;
|
||||
ti.operations[1].operation = right_to_left
|
||||
? operation_union : operation_intersection;
|
||||
return;
|
||||
}
|
||||
|
||||
if (side_pk_q1 == side_qk_p1)
|
||||
{
|
||||
uu_else_ii(right_to_left, ti);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If p turns into direction of qk (4,5)
|
||||
if (side_pk_p == side_qk_p1)
|
||||
{
|
||||
int const side_pk_q2 = SideStrategy::apply(qj, qk, pk);
|
||||
|
||||
// Collinear case -> lines join, continue
|
||||
if (side_pk_q2 == 0)
|
||||
{
|
||||
both(ti, operation_continue);
|
||||
return;
|
||||
}
|
||||
if (side_pk_q2 == side_qk_p1)
|
||||
{
|
||||
ui_else_iu(right_to_left, ti);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// otherwise (3)
|
||||
ui_else_iu(! right_to_left, ti);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_GET_TURNS
|
||||
// Normally a robustness issue.
|
||||
// TODO: more research if still occuring
|
||||
std::cout << "Not yet handled" << std::endl
|
||||
<< "pi " << get<0>(pi) << " , " << get<1>(pi)
|
||||
<< " pj " << get<0>(pj) << " , " << get<1>(pj)
|
||||
<< " pk " << get<0>(pk) << " , " << get<1>(pk)
|
||||
<< std::endl
|
||||
<< "qi " << get<0>(qi) << " , " << get<1>(qi)
|
||||
<< " qj " << get<0>(qj) << " , " << get<1>(qj)
|
||||
<< " qk " << get<0>(qk) << " , " << get<1>(qk)
|
||||
<< std::endl;
|
||||
#endif
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename TurnInfo,
|
||||
typename SideStrategy
|
||||
>
|
||||
struct equal : public base_turn_handler
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename IntersectionInfo,
|
||||
typename DirInfo
|
||||
>
|
||||
static inline void apply(
|
||||
Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
TurnInfo& ti,
|
||||
IntersectionInfo const& intersection_info,
|
||||
DirInfo const& dir_info)
|
||||
{
|
||||
ti.method = method_equal;
|
||||
// Copy the SECOND intersection point
|
||||
geometry::convert(intersection_info.intersections[1], ti.point);
|
||||
|
||||
int const side_pk_q2 = SideStrategy::apply(qj, qk, pk);
|
||||
int const side_pk_p = SideStrategy::apply(pi, pj, pk);
|
||||
int const side_qk_p = SideStrategy::apply(pi, pj, qk);
|
||||
|
||||
// If pk is collinear with qj-qk, they continue collinearly.
|
||||
// This can be on either side of p1 (== q1), or collinear
|
||||
// The second condition checks if they do not continue
|
||||
// oppositely
|
||||
if (side_pk_q2 == 0 && side_pk_p == side_qk_p)
|
||||
{
|
||||
both(ti, operation_continue);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// If they turn to same side (not opposite sides)
|
||||
if (! opposite(side_pk_p, side_qk_p))
|
||||
{
|
||||
int const side_pk_q2 = SideStrategy::apply(qj, qk, pk);
|
||||
|
||||
// If pk is left of q2 or collinear: p: union, q: intersection
|
||||
ui_else_iu(side_pk_q2 != -1, ti);
|
||||
}
|
||||
else
|
||||
{
|
||||
// They turn opposite sides. If p turns left (or collinear),
|
||||
// p: union, q: intersection
|
||||
ui_else_iu(side_pk_p != -1, ti);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename TurnInfo,
|
||||
typename SideStrategy
|
||||
>
|
||||
struct collinear : public base_turn_handler
|
||||
{
|
||||
/*
|
||||
arrival P pk//p1 qk//q1 product* case result
|
||||
1 1 1 CLL1 ui
|
||||
-1 1 -1 CLL2 iu
|
||||
1 1 1 CLR1 ui
|
||||
-1 -1 1 CLR2 ui
|
||||
|
||||
1 -1 -1 CRL1 iu
|
||||
-1 1 -1 CRL2 iu
|
||||
1 -1 -1 CRR1 iu
|
||||
-1 -1 1 CRR2 ui
|
||||
|
||||
1 0 0 CC1 cc
|
||||
-1 0 0 CC2 cc
|
||||
|
||||
*product = arrival * (pk//p1 or qk//q1)
|
||||
|
||||
Stated otherwise:
|
||||
- if P arrives: look at turn P
|
||||
- if Q arrives: look at turn Q
|
||||
- if P arrives and P turns left: union for P
|
||||
- if P arrives and P turns right: intersection for P
|
||||
- if Q arrives and Q turns left: union for Q (=intersection for P)
|
||||
- if Q arrives and Q turns right: intersection for Q (=union for P)
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename IntersectionInfo,
|
||||
typename DirInfo
|
||||
>
|
||||
static inline void apply(
|
||||
Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
TurnInfo& ti,
|
||||
IntersectionInfo const& intersection_info,
|
||||
DirInfo const& dir_info)
|
||||
{
|
||||
ti.method = method_collinear;
|
||||
geometry::convert(intersection_info.intersections[1], ti.point);
|
||||
|
||||
int const arrival = dir_info.arrival[0];
|
||||
// Should not be 0, this is checked before
|
||||
BOOST_ASSERT(arrival != 0);
|
||||
|
||||
// If p arrives, use p, else use q
|
||||
int const side_p_or_q = arrival == 1
|
||||
? SideStrategy::apply(pi, pj, pk)
|
||||
: SideStrategy::apply(qi, qj, qk)
|
||||
;
|
||||
|
||||
// See comments above,
|
||||
// resulting in a strange sort of mathematic rule here:
|
||||
// The arrival-info multiplied by the relevant side
|
||||
// delivers a consistent result.
|
||||
|
||||
int const product = arrival * side_p_or_q;
|
||||
|
||||
if(product == 0)
|
||||
{
|
||||
both(ti, operation_continue);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui_else_iu(product == 1, ti);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename TurnInfo,
|
||||
typename SideStrategy,
|
||||
typename AssignPolicy
|
||||
>
|
||||
struct collinear_opposite : public base_turn_handler
|
||||
{
|
||||
private :
|
||||
/*
|
||||
arrival P arrival Q pk//p1 qk//q1 case result2 result
|
||||
--------------------------------------------------------------
|
||||
1 1 1 -1 CLO1 ix xu
|
||||
1 1 1 0 CLO2 ix (xx)
|
||||
1 1 1 1 CLO3 ix xi
|
||||
|
||||
1 1 0 -1 CCO1 (xx) xu
|
||||
1 1 0 0 CCO2 (xx) (xx)
|
||||
1 1 0 1 CCO3 (xx) xi
|
||||
|
||||
1 1 -1 -1 CRO1 ux xu
|
||||
1 1 -1 0 CRO2 ux (xx)
|
||||
1 1 -1 1 CRO3 ux xi
|
||||
|
||||
-1 1 -1 CXO1 xu
|
||||
-1 1 0 CXO2 (xx)
|
||||
-1 1 1 CXO3 xi
|
||||
|
||||
1 -1 1 CXO1 ix
|
||||
1 -1 0 CXO2 (xx)
|
||||
1 -1 -1 CXO3 ux
|
||||
*/
|
||||
|
||||
template
|
||||
<
|
||||
int Index,
|
||||
typename Point,
|
||||
typename IntersectionInfo
|
||||
>
|
||||
static inline bool set_tp(Point const& ri, Point const& rj, Point const& rk,
|
||||
TurnInfo& tp, IntersectionInfo const& intersection_info)
|
||||
{
|
||||
int const side_rk_r = SideStrategy::apply(ri, rj, rk);
|
||||
switch(side_rk_r)
|
||||
{
|
||||
|
||||
case 1 :
|
||||
// Turning left on opposite collinear: intersection
|
||||
tp.operations[Index].operation = operation_intersection;
|
||||
break;
|
||||
case -1 :
|
||||
// Turning right on opposite collinear: union
|
||||
tp.operations[Index].operation = operation_union;
|
||||
break;
|
||||
case 0 :
|
||||
// No turn on opposite collinear: block, do not traverse
|
||||
// But this "xx" is ignored here, it is useless to include
|
||||
// two operation blocked, so the whole point does not need
|
||||
// to be generated.
|
||||
// So return false to indicate nothing is to be done.
|
||||
return false;
|
||||
}
|
||||
|
||||
// The other direction is always blocked when collinear opposite
|
||||
tp.operations[1 - Index].operation = operation_blocked;
|
||||
|
||||
// If P arrives within Q, set info on P (which is done above, index=0),
|
||||
// this turn-info belongs to the second intersection point, index=1
|
||||
// (see e.g. figure CLO1)
|
||||
geometry::convert(intersection_info.intersections[1 - Index], tp.point);
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
template
|
||||
<
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename OutputIterator,
|
||||
typename IntersectionInfo,
|
||||
typename DirInfo
|
||||
>
|
||||
static inline void apply(
|
||||
Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
|
||||
// Opposite collinear can deliver 2 intersection points,
|
||||
TurnInfo const& tp_model,
|
||||
OutputIterator& out,
|
||||
|
||||
IntersectionInfo const& intersection_info,
|
||||
DirInfo const& dir_info)
|
||||
{
|
||||
/*
|
||||
std::cout << "arrivals: "
|
||||
<< dir_info.arrival[0]
|
||||
<< "/" << dir_info.arrival[1]
|
||||
<< std::endl;
|
||||
*/
|
||||
|
||||
TurnInfo tp = tp_model;
|
||||
|
||||
tp.method = method_collinear;
|
||||
|
||||
// If P arrives within Q, there is a turn dependant on P
|
||||
if (dir_info.arrival[0] == 1
|
||||
&& set_tp<0>(pi, pj, pk, tp, intersection_info))
|
||||
{
|
||||
AssignPolicy::apply(tp, pi, qi);
|
||||
*out++ = tp;
|
||||
}
|
||||
|
||||
// If Q arrives within P, there is a turn dependant on Q
|
||||
if (dir_info.arrival[1] == 1
|
||||
&& set_tp<1>(qi, qj, qk, tp, intersection_info))
|
||||
{
|
||||
AssignPolicy::apply(tp, pi, qi);
|
||||
*out++ = tp;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename TurnInfo,
|
||||
typename SideStrategy
|
||||
>
|
||||
struct crosses : public base_turn_handler
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename IntersectionInfo,
|
||||
typename DirInfo
|
||||
>
|
||||
static inline void apply(
|
||||
Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
TurnInfo& ti,
|
||||
IntersectionInfo const& intersection_info,
|
||||
DirInfo const& dir_info)
|
||||
{
|
||||
ti.method = method_crosses;
|
||||
geometry::convert(intersection_info.intersections[0], ti.point);
|
||||
|
||||
// In all casees:
|
||||
// If Q crosses P from left to right
|
||||
// Union: take P
|
||||
// Intersection: take Q
|
||||
// Otherwise: vice versa
|
||||
int const side_qi_p1 = dir_info.sides.template get<1, 0>();
|
||||
int const index = side_qi_p1 == 1 ? 0 : 1;
|
||||
ti.operations[index].operation = operation_union;
|
||||
ti.operations[1 - index].operation = operation_intersection;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
\brief Policy doing nothing
|
||||
\details get_turn_info can have an optional policy to get/assign some
|
||||
extra information. By default it does not, and this class
|
||||
is that default.
|
||||
*/
|
||||
struct assign_null_policy
|
||||
{
|
||||
template <typename Point1, typename Point2, typename Info>
|
||||
static inline void apply(Info& info, Point1 const& p1, Point2 const& p2)
|
||||
{}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
\brief Turn information: intersection point, method, and turn information
|
||||
\details Information necessary for traversal phase (a phase
|
||||
of the overlay process). The information is gathered during the
|
||||
get_turns (segment intersection) phase.
|
||||
\tparam Point1 point type of first segment
|
||||
\tparam Point2 point type of second segment
|
||||
\tparam TurnInfo type of class getting intersection and turn info
|
||||
\tparam AssignPolicy policy to assign extra info,
|
||||
e.g. to calculate distance from segment's first points
|
||||
to intersection points
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename TurnInfo,
|
||||
typename AssignPolicy = assign_null_policy
|
||||
>
|
||||
struct get_turn_info
|
||||
{
|
||||
typedef strategy_intersection
|
||||
<
|
||||
typename cs_tag<typename TurnInfo::point_type>::type,
|
||||
Point1,
|
||||
Point2,
|
||||
typename TurnInfo::point_type
|
||||
> si;
|
||||
|
||||
typedef typename si::segment_intersection_strategy_type strategy;
|
||||
|
||||
|
||||
|
||||
template <typename OutputIterator>
|
||||
static inline OutputIterator apply(
|
||||
Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
TurnInfo const& tp_model,
|
||||
OutputIterator out)
|
||||
{
|
||||
typedef model::referring_segment<Point1 const> segment_type1;
|
||||
typedef model::referring_segment<Point1 const> segment_type2;
|
||||
segment_type1 p1(pi, pj), p2(pj, pk);
|
||||
segment_type2 q1(qi, qj), q2(qj, qk);
|
||||
|
||||
typename strategy::return_type result = strategy::apply(p1, q1);
|
||||
|
||||
char const method = result.template get<1>().how;
|
||||
|
||||
// Copy, to copy possibly extended fields
|
||||
TurnInfo tp = tp_model;
|
||||
|
||||
|
||||
// Select method and apply
|
||||
switch(method)
|
||||
{
|
||||
case 'a' :
|
||||
case 'f' :
|
||||
case 's' :
|
||||
case 'd' :
|
||||
break;
|
||||
|
||||
case 'm' :
|
||||
{
|
||||
typedef touch_interior
|
||||
<
|
||||
TurnInfo,
|
||||
typename si::side_strategy_type
|
||||
> policy;
|
||||
|
||||
// If Q (1) arrives (1)
|
||||
if (result.template get<1>().arrival[1] == 1)
|
||||
{
|
||||
policy::template apply<0>(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Swap p/q
|
||||
policy::template apply<1>(qi, qj, qk, pi, pj, pk,
|
||||
tp, result.template get<0>(), result.template get<1>());
|
||||
}
|
||||
AssignPolicy::apply(tp, pi, qi);
|
||||
*out++ = tp;
|
||||
}
|
||||
break;
|
||||
case 'i' :
|
||||
{
|
||||
typedef crosses
|
||||
<
|
||||
TurnInfo,
|
||||
typename si::side_strategy_type
|
||||
> policy;
|
||||
|
||||
policy::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi);
|
||||
*out++ = tp;
|
||||
}
|
||||
break;
|
||||
case 't' :
|
||||
{
|
||||
// Both touch (both arrive there)
|
||||
typedef touch
|
||||
<
|
||||
TurnInfo,
|
||||
typename si::side_strategy_type
|
||||
> policy;
|
||||
|
||||
policy::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi);
|
||||
*out++ = tp;
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
{
|
||||
if (! result.template get<1>().opposite)
|
||||
{
|
||||
// Both equal
|
||||
// or collinear-and-ending at intersection point
|
||||
typedef equal
|
||||
<
|
||||
TurnInfo,
|
||||
typename si::side_strategy_type
|
||||
> policy;
|
||||
|
||||
policy::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi);
|
||||
*out++ = tp;
|
||||
}
|
||||
// If they ARE opposite, don't do anything.
|
||||
}
|
||||
break;
|
||||
case 'c' :
|
||||
{
|
||||
// Collinear
|
||||
if (! result.template get<1>().opposite)
|
||||
{
|
||||
|
||||
if (result.template get<1>().arrival[0] == 0)
|
||||
{
|
||||
// Collinear, but similar thus handled as equal
|
||||
equal
|
||||
<
|
||||
TurnInfo,
|
||||
typename si::side_strategy_type
|
||||
>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>());
|
||||
|
||||
// override assigned method
|
||||
tp.method = method_collinear;
|
||||
}
|
||||
else
|
||||
{
|
||||
collinear
|
||||
<
|
||||
TurnInfo,
|
||||
typename si::side_strategy_type
|
||||
>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>());
|
||||
}
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi);
|
||||
*out++ = tp;
|
||||
}
|
||||
else
|
||||
{
|
||||
collinear_opposite
|
||||
<
|
||||
TurnInfo,
|
||||
typename si::side_strategy_type,
|
||||
AssignPolicy
|
||||
>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, out, result.template get<0>(), result.template get<1>());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '0' :
|
||||
// degenerate points
|
||||
break;
|
||||
default :
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_GET_TURNS
|
||||
std::cout << "get_turns, nyi: " << method << std::endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif //DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HPP
|
||||
864
test/external/boost/geometry/algorithms/detail/overlay/get_turns.hpp
vendored
Normal file
864
test/external/boost/geometry/algorithms/detail/overlay/get_turns.hpp
vendored
Normal file
@@ -0,0 +1,864 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
#include <map>
|
||||
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/reverse_dispatch.hpp>
|
||||
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/ring_type.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
#include <boost/geometry/views/closeable_view.hpp>
|
||||
#include <boost/geometry/views/reversible_view.hpp>
|
||||
#include <boost/geometry/views/detail/range_type.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/box.hpp>
|
||||
#include <boost/geometry/geometries/segment.hpp>
|
||||
|
||||
#include <boost/geometry/iterators/ever_circling_iterator.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/cartesian/cart_intersect.hpp>
|
||||
#include <boost/geometry/strategies/intersection.hpp>
|
||||
#include <boost/geometry/strategies/intersection_result.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/disjoint.hpp>
|
||||
#include <boost/geometry/algorithms/detail/partition.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
|
||||
|
||||
|
||||
#include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/expand.hpp>
|
||||
#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
|
||||
# include <sstream>
|
||||
# include <boost/geometry/util/write_dsv.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace get_turns
|
||||
{
|
||||
|
||||
|
||||
struct no_interrupt_policy
|
||||
{
|
||||
static bool const enabled = false;
|
||||
|
||||
template <typename Range>
|
||||
static inline bool apply(Range const&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2,
|
||||
typename Section1, typename Section2,
|
||||
typename Turns,
|
||||
typename TurnPolicy,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
class get_turns_in_sections
|
||||
{
|
||||
typedef typename closeable_view
|
||||
<
|
||||
typename range_type<Geometry1>::type const,
|
||||
closure<Geometry1>::value
|
||||
>::type cview_type1;
|
||||
typedef typename closeable_view
|
||||
<
|
||||
typename range_type<Geometry2>::type const,
|
||||
closure<Geometry2>::value
|
||||
>::type cview_type2;
|
||||
|
||||
typedef typename reversible_view
|
||||
<
|
||||
cview_type1 const,
|
||||
Reverse1 ? iterate_reverse : iterate_forward
|
||||
>::type view_type1;
|
||||
typedef typename reversible_view
|
||||
<
|
||||
cview_type2 const,
|
||||
Reverse2 ? iterate_reverse : iterate_forward
|
||||
>::type view_type2;
|
||||
|
||||
typedef typename boost::range_iterator
|
||||
<
|
||||
view_type1 const
|
||||
>::type range1_iterator;
|
||||
|
||||
typedef typename boost::range_iterator
|
||||
<
|
||||
view_type2 const
|
||||
>::type range2_iterator;
|
||||
|
||||
|
||||
template <typename Geometry, typename Section>
|
||||
static inline bool neighbouring(Section const& section,
|
||||
int index1, int index2)
|
||||
{
|
||||
// About n-2:
|
||||
// (square: range_count=5, indices 0,1,2,3
|
||||
// -> 0-3 are adjacent, don't check on intersections)
|
||||
// Also tested for open polygons, and/or duplicates
|
||||
// About first condition: will be optimized by compiler (static)
|
||||
// It checks if it is areal (box,ring,(multi)polygon
|
||||
int const n = int(section.range_count);
|
||||
return boost::is_same
|
||||
<
|
||||
typename tag_cast
|
||||
<
|
||||
typename geometry::point_type<Geometry1>::type,
|
||||
areal_tag
|
||||
>::type,
|
||||
areal_tag
|
||||
>::value
|
||||
&& index1 == 0
|
||||
&& index2 >= n - 2
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
public :
|
||||
// Returns true if terminated, false if interrupted
|
||||
static inline bool apply(
|
||||
int source_id1, Geometry1 const& geometry1, Section1 const& sec1,
|
||||
int source_id2, Geometry2 const& geometry2, Section2 const& sec2,
|
||||
Turns& turns,
|
||||
InterruptPolicy& interrupt_policy)
|
||||
{
|
||||
cview_type1 cview1(range_by_section(geometry1, sec1));
|
||||
cview_type2 cview2(range_by_section(geometry2, sec2));
|
||||
view_type1 view1(cview1);
|
||||
view_type2 view2(cview2);
|
||||
|
||||
range1_iterator begin_range_1 = boost::begin(view1);
|
||||
range1_iterator end_range_1 = boost::end(view1);
|
||||
|
||||
range2_iterator begin_range_2 = boost::begin(view2);
|
||||
range2_iterator end_range_2 = boost::end(view2);
|
||||
|
||||
int const dir1 = sec1.directions[0];
|
||||
int const dir2 = sec2.directions[0];
|
||||
int index1 = sec1.begin_index;
|
||||
int ndi1 = sec1.non_duplicate_index;
|
||||
|
||||
bool const same_source =
|
||||
source_id1 == source_id2
|
||||
&& sec1.ring_id.multi_index == sec2.ring_id.multi_index
|
||||
&& sec1.ring_id.ring_index == sec2.ring_id.ring_index;
|
||||
|
||||
range1_iterator prev1, it1, end1;
|
||||
|
||||
get_start_point_iterator(sec1, view1, prev1, it1, end1,
|
||||
index1, ndi1, dir1, sec2.bounding_box);
|
||||
|
||||
// We need a circular iterator because it might run through the closing point.
|
||||
// One circle is actually enough but this one is just convenient.
|
||||
ever_circling_iterator<range1_iterator> next1(begin_range_1, end_range_1, it1, true);
|
||||
next1++;
|
||||
|
||||
// Walk through section and stop if we exceed the other box
|
||||
// section 2: [--------------]
|
||||
// section 1: |----|---|---|---|---|
|
||||
for (prev1 = it1++, next1++;
|
||||
it1 != end1 && ! exceeding<0>(dir1, *prev1, sec2.bounding_box);
|
||||
++prev1, ++it1, ++index1, ++next1, ++ndi1)
|
||||
{
|
||||
ever_circling_iterator<range1_iterator> nd_next1(
|
||||
begin_range_1, end_range_1, next1, true);
|
||||
advance_to_non_duplicate_next(nd_next1, it1, sec1);
|
||||
|
||||
int index2 = sec2.begin_index;
|
||||
int ndi2 = sec2.non_duplicate_index;
|
||||
|
||||
range2_iterator prev2, it2, end2;
|
||||
|
||||
get_start_point_iterator(sec2, view2, prev2, it2, end2,
|
||||
index2, ndi2, dir2, sec1.bounding_box);
|
||||
ever_circling_iterator<range2_iterator> next2(begin_range_2, end_range_2, it2, true);
|
||||
next2++;
|
||||
|
||||
for (prev2 = it2++, next2++;
|
||||
it2 != end2 && ! exceeding<0>(dir2, *prev2, sec1.bounding_box);
|
||||
++prev2, ++it2, ++index2, ++next2, ++ndi2)
|
||||
{
|
||||
bool skip = same_source;
|
||||
if (skip)
|
||||
{
|
||||
// If sources are the same (possibly self-intersecting):
|
||||
// skip if it is a neighbouring segment.
|
||||
// (including first-last segment
|
||||
// and two segments with one or more degenerate/duplicate
|
||||
// (zero-length) segments in between)
|
||||
|
||||
// Also skip if index1 < index2 to avoid getting all
|
||||
// intersections twice (only do this on same source!)
|
||||
|
||||
skip = index1 >= index2
|
||||
|| ndi2 == ndi1 + 1
|
||||
|| neighbouring<Geometry1>(sec1, index1, index2)
|
||||
;
|
||||
}
|
||||
|
||||
if (! skip)
|
||||
{
|
||||
// Move to the "non duplicate next"
|
||||
ever_circling_iterator<range2_iterator> nd_next2(
|
||||
begin_range_2, end_range_2, next2, true);
|
||||
advance_to_non_duplicate_next(nd_next2, it2, sec2);
|
||||
|
||||
typedef typename boost::range_value<Turns>::type turn_info;
|
||||
typedef typename turn_info::point_type ip;
|
||||
|
||||
turn_info ti;
|
||||
ti.operations[0].seg_id = segment_identifier(source_id1,
|
||||
sec1.ring_id.multi_index, sec1.ring_id.ring_index, index1),
|
||||
ti.operations[1].seg_id = segment_identifier(source_id2,
|
||||
sec2.ring_id.multi_index, sec2.ring_id.ring_index, index2),
|
||||
|
||||
ti.operations[0].other_id = ti.operations[1].seg_id;
|
||||
ti.operations[1].other_id = ti.operations[0].seg_id;
|
||||
|
||||
std::size_t const size_before = boost::size(turns);
|
||||
|
||||
TurnPolicy::apply(*prev1, *it1, *nd_next1, *prev2, *it2, *nd_next2,
|
||||
ti, std::back_inserter(turns));
|
||||
|
||||
if (InterruptPolicy::enabled)
|
||||
{
|
||||
if (interrupt_policy.apply(
|
||||
std::make_pair(boost::begin(turns) + size_before,
|
||||
boost::end(turns))))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private :
|
||||
typedef typename geometry::point_type<Geometry1>::type point1_type;
|
||||
typedef typename geometry::point_type<Geometry2>::type point2_type;
|
||||
typedef typename model::referring_segment<point1_type const> segment1_type;
|
||||
typedef typename model::referring_segment<point2_type const> segment2_type;
|
||||
|
||||
|
||||
template <size_t Dim, typename Point, typename Box>
|
||||
static inline bool preceding(int dir, Point const& point, Box const& box)
|
||||
{
|
||||
return (dir == 1 && get<Dim>(point) < get<min_corner, Dim>(box))
|
||||
|| (dir == -1 && get<Dim>(point) > get<max_corner, Dim>(box));
|
||||
}
|
||||
|
||||
template <size_t Dim, typename Point, typename Box>
|
||||
static inline bool exceeding(int dir, Point const& point, Box const& box)
|
||||
{
|
||||
return (dir == 1 && get<Dim>(point) > get<max_corner, Dim>(box))
|
||||
|| (dir == -1 && get<Dim>(point) < get<min_corner, Dim>(box));
|
||||
}
|
||||
|
||||
template <typename Iterator, typename RangeIterator, typename Section>
|
||||
static inline void advance_to_non_duplicate_next(Iterator& next,
|
||||
RangeIterator const& it, Section const& section)
|
||||
{
|
||||
// To see where the next segments bend to, in case of touch/intersections
|
||||
// on end points, we need (in case of degenerate/duplicate points) an extra
|
||||
// iterator which moves to the REAL next point, so non duplicate.
|
||||
// This needs an extra comparison (disjoint).
|
||||
// (Note that within sections, non duplicate points are already asserted,
|
||||
// by the sectionalize process).
|
||||
|
||||
// So advance to the "non duplicate next"
|
||||
// (the check is defensive, to avoid endless loops)
|
||||
std::size_t check = 0;
|
||||
while(! detail::disjoint::disjoint_point_point(*it, *next)
|
||||
&& check++ < section.range_count)
|
||||
{
|
||||
next++;
|
||||
}
|
||||
}
|
||||
|
||||
// It is NOT possible to have section-iterators here
|
||||
// because of the logistics of "index" (the section-iterator automatically
|
||||
// skips to the begin-point, we loose the index or have to recalculate it)
|
||||
// So we mimic it here
|
||||
template <typename Range, typename Section, typename Box>
|
||||
static inline void get_start_point_iterator(Section & section,
|
||||
Range const& range,
|
||||
typename boost::range_iterator<Range const>::type& it,
|
||||
typename boost::range_iterator<Range const>::type& prev,
|
||||
typename boost::range_iterator<Range const>::type& end,
|
||||
int& index, int& ndi,
|
||||
int dir, Box const& other_bounding_box)
|
||||
{
|
||||
it = boost::begin(range) + section.begin_index;
|
||||
end = boost::begin(range) + section.end_index + 1;
|
||||
|
||||
// Mimic section-iterator:
|
||||
// Skip to point such that section interects other box
|
||||
prev = it++;
|
||||
for(; it != end && preceding<0>(dir, *it, other_bounding_box);
|
||||
prev = it++, index++, ndi++)
|
||||
{}
|
||||
// Go back one step because we want to start completely preceding
|
||||
it = prev;
|
||||
}
|
||||
};
|
||||
|
||||
struct get_section_box
|
||||
{
|
||||
template <typename Box, typename InputItem>
|
||||
static inline void apply(Box& total, InputItem const& item)
|
||||
{
|
||||
geometry::expand(total, item.bounding_box);
|
||||
}
|
||||
};
|
||||
|
||||
struct ovelaps_section_box
|
||||
{
|
||||
template <typename Box, typename InputItem>
|
||||
static inline bool apply(Box const& box, InputItem const& item)
|
||||
{
|
||||
return ! detail::disjoint::disjoint_box_box(box, item.bounding_box);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2,
|
||||
typename Turns,
|
||||
typename TurnPolicy,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
struct section_visitor
|
||||
{
|
||||
int m_source_id1;
|
||||
Geometry1 const& m_geometry1;
|
||||
int m_source_id2;
|
||||
Geometry2 const& m_geometry2;
|
||||
Turns& m_turns;
|
||||
InterruptPolicy& m_interrupt_policy;
|
||||
|
||||
section_visitor(int id1, Geometry1 const& g1,
|
||||
int id2, Geometry2 const& g2,
|
||||
Turns& turns, InterruptPolicy& ip)
|
||||
: m_source_id1(id1), m_geometry1(g1)
|
||||
, m_source_id2(id2), m_geometry2(g2)
|
||||
, m_turns(turns)
|
||||
, m_interrupt_policy(ip)
|
||||
{}
|
||||
|
||||
template <typename Section>
|
||||
inline bool apply(Section const& sec1, Section const& sec2)
|
||||
{
|
||||
if (! detail::disjoint::disjoint_box_box(sec1.bounding_box, sec2.bounding_box))
|
||||
{
|
||||
return get_turns_in_sections
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
Reverse1, Reverse2,
|
||||
Section, Section,
|
||||
Turns,
|
||||
TurnPolicy,
|
||||
InterruptPolicy
|
||||
>::apply(
|
||||
m_source_id1, m_geometry1, sec1,
|
||||
m_source_id2, m_geometry2, sec2,
|
||||
m_turns, m_interrupt_policy);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2,
|
||||
typename Turns,
|
||||
typename TurnPolicy,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
class get_turns_generic
|
||||
{
|
||||
|
||||
public:
|
||||
static inline void apply(
|
||||
int source_id1, Geometry1 const& geometry1,
|
||||
int source_id2, Geometry2 const& geometry2,
|
||||
Turns& turns, InterruptPolicy& interrupt_policy)
|
||||
{
|
||||
// First create monotonic sections...
|
||||
typedef typename boost::range_value<Turns>::type ip_type;
|
||||
typedef typename ip_type::point_type point_type;
|
||||
typedef model::box<point_type> box_type;
|
||||
typedef typename geometry::sections<box_type, 2> sections_type;
|
||||
|
||||
sections_type sec1, sec2;
|
||||
|
||||
geometry::sectionalize<Reverse1>(geometry1, sec1, 0);
|
||||
geometry::sectionalize<Reverse2>(geometry2, sec2, 1);
|
||||
|
||||
// ... and then partition them, intersecting overlapping sections in visitor method
|
||||
section_visitor
|
||||
<
|
||||
Geometry1, Geometry2,
|
||||
Reverse1, Reverse2,
|
||||
Turns, TurnPolicy, InterruptPolicy
|
||||
> visitor(source_id1, geometry1, source_id2, geometry2, turns, interrupt_policy);
|
||||
|
||||
geometry::partition
|
||||
<
|
||||
box_type, get_section_box, ovelaps_section_box
|
||||
>::apply(sec1, sec2, visitor);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Get turns for a range with a box, following Cohen-Sutherland (cs) approach
|
||||
template
|
||||
<
|
||||
typename Range, typename Box,
|
||||
bool ReverseRange, bool ReverseBox,
|
||||
typename Turns,
|
||||
typename TurnPolicy,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
struct get_turns_cs
|
||||
{
|
||||
typedef typename boost::range_value<Turns>::type turn_info;
|
||||
typedef typename geometry::point_type<Range>::type point_type;
|
||||
typedef typename geometry::point_type<Box>::type box_point_type;
|
||||
|
||||
typedef typename closeable_view
|
||||
<
|
||||
Range const,
|
||||
closure<Range>::value
|
||||
>::type cview_type;
|
||||
|
||||
typedef typename reversible_view
|
||||
<
|
||||
cview_type const,
|
||||
ReverseRange ? iterate_reverse : iterate_forward
|
||||
>::type view_type;
|
||||
|
||||
typedef typename boost::range_iterator
|
||||
<
|
||||
view_type const
|
||||
>::type iterator_type;
|
||||
|
||||
|
||||
static inline void apply(
|
||||
int source_id1, Range const& range,
|
||||
int source_id2, Box const& box,
|
||||
Turns& turns,
|
||||
InterruptPolicy& ,
|
||||
int multi_index = -1, int ring_index = -1)
|
||||
{
|
||||
if (boost::size(range) <= 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
boost::array<box_point_type,4> bp;
|
||||
assign_box_corners_oriented<ReverseBox>(box, bp);
|
||||
|
||||
cview_type cview(range);
|
||||
view_type view(cview);
|
||||
|
||||
iterator_type it = boost::begin(view);
|
||||
|
||||
ever_circling_iterator<iterator_type> next(
|
||||
boost::begin(view), boost::end(view), it, true);
|
||||
next++;
|
||||
next++;
|
||||
|
||||
//bool first = true;
|
||||
|
||||
//char previous_side[2] = {0, 0};
|
||||
|
||||
int index = 0;
|
||||
|
||||
for (iterator_type prev = it++;
|
||||
it != boost::end(view);
|
||||
prev = it++, next++, index++)
|
||||
{
|
||||
segment_identifier seg_id(source_id1,
|
||||
multi_index, ring_index, index);
|
||||
|
||||
/*if (first)
|
||||
{
|
||||
previous_side[0] = get_side<0>(box, *prev);
|
||||
previous_side[1] = get_side<1>(box, *prev);
|
||||
}
|
||||
|
||||
char current_side[2];
|
||||
current_side[0] = get_side<0>(box, *it);
|
||||
current_side[1] = get_side<1>(box, *it);
|
||||
|
||||
// There can NOT be intersections if
|
||||
// 1) EITHER the two points are lying on one side of the box (! 0 && the same)
|
||||
// 2) OR same in Y-direction
|
||||
// 3) OR all points are inside the box (0)
|
||||
if (! (
|
||||
(current_side[0] != 0 && current_side[0] == previous_side[0])
|
||||
|| (current_side[1] != 0 && current_side[1] == previous_side[1])
|
||||
|| (current_side[0] == 0
|
||||
&& current_side[1] == 0
|
||||
&& previous_side[0] == 0
|
||||
&& previous_side[1] == 0)
|
||||
)
|
||||
)*/
|
||||
if (true)
|
||||
{
|
||||
get_turns_with_box(seg_id, source_id2,
|
||||
*prev, *it, *next,
|
||||
bp[0], bp[1], bp[2], bp[3],
|
||||
turns);
|
||||
// Future performance enhancement:
|
||||
// return if told by the interrupt policy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
template<std::size_t Index, typename Point>
|
||||
static inline int get_side(Box const& box, Point const& point)
|
||||
{
|
||||
// Inside -> 0
|
||||
// Outside -> -1 (left/below) or 1 (right/above)
|
||||
// On border -> -2 (left/lower) or 2 (right/upper)
|
||||
// The only purpose of the value is to not be the same,
|
||||
// and to denote if it is inside (0)
|
||||
|
||||
typename coordinate_type<Point>::type const& c = get<Index>(point);
|
||||
typename coordinate_type<Box>::type const& left = get<min_corner, Index>(box);
|
||||
typename coordinate_type<Box>::type const& right = get<max_corner, Index>(box);
|
||||
|
||||
if (geometry::math::equals(c, left)) return -2;
|
||||
else if (geometry::math::equals(c, right)) return 2;
|
||||
else if (c < left) return -1;
|
||||
else if (c > right) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
static inline void get_turns_with_box(segment_identifier const& seg_id, int source_id2,
|
||||
// Points from a range:
|
||||
point_type const& rp0,
|
||||
point_type const& rp1,
|
||||
point_type const& rp2,
|
||||
// Points from the box
|
||||
box_point_type const& bp0,
|
||||
box_point_type const& bp1,
|
||||
box_point_type const& bp2,
|
||||
box_point_type const& bp3,
|
||||
// Output
|
||||
Turns& turns)
|
||||
{
|
||||
// Depending on code some relations can be left out
|
||||
|
||||
typedef typename boost::range_value<Turns>::type turn_info;
|
||||
|
||||
turn_info ti;
|
||||
ti.operations[0].seg_id = seg_id;
|
||||
ti.operations[0].other_id = ti.operations[1].seg_id;
|
||||
ti.operations[1].other_id = seg_id;
|
||||
|
||||
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 0);
|
||||
TurnPolicy::apply(rp0, rp1, rp2, bp0, bp1, bp2,
|
||||
ti, std::back_inserter(turns));
|
||||
|
||||
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 1);
|
||||
TurnPolicy::apply(rp0, rp1, rp2, bp1, bp2, bp3,
|
||||
ti, std::back_inserter(turns));
|
||||
|
||||
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 2);
|
||||
TurnPolicy::apply(rp0, rp1, rp2, bp2, bp3, bp0,
|
||||
ti, std::back_inserter(turns));
|
||||
|
||||
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 3);
|
||||
TurnPolicy::apply(rp0, rp1, rp2, bp3, bp0, bp1,
|
||||
ti, std::back_inserter(turns));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Polygon, typename Box,
|
||||
bool Reverse, bool ReverseBox,
|
||||
typename Turns,
|
||||
typename TurnPolicy,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
struct get_turns_polygon_cs
|
||||
{
|
||||
static inline void apply(
|
||||
int source_id1, Polygon const& polygon,
|
||||
int source_id2, Box const& box,
|
||||
Turns& turns, InterruptPolicy& interrupt_policy,
|
||||
int multi_index = -1)
|
||||
{
|
||||
typedef typename geometry::ring_type<Polygon>::type ring_type;
|
||||
|
||||
typedef detail::get_turns::get_turns_cs
|
||||
<
|
||||
ring_type, Box,
|
||||
Reverse, ReverseBox,
|
||||
Turns,
|
||||
TurnPolicy,
|
||||
InterruptPolicy
|
||||
> intersector_type;
|
||||
|
||||
intersector_type::apply(
|
||||
source_id1, geometry::exterior_ring(polygon),
|
||||
source_id2, box, turns, interrupt_policy,
|
||||
multi_index, -1);
|
||||
|
||||
int i = 0;
|
||||
|
||||
typename interior_return_type<Polygon const>::type rings
|
||||
= interior_rings(polygon);
|
||||
for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings);
|
||||
++it, ++i)
|
||||
{
|
||||
intersector_type::apply(
|
||||
source_id1, *it,
|
||||
source_id2, box, turns, interrupt_policy,
|
||||
multi_index, i);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::get_turns
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
// Because this is "detail" method, and most implementations will use "generic",
|
||||
// we take the freedom to derive it from "generic".
|
||||
template
|
||||
<
|
||||
typename GeometryTag1, typename GeometryTag2,
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2,
|
||||
typename Turns,
|
||||
typename TurnPolicy,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
struct get_turns
|
||||
: detail::get_turns::get_turns_generic
|
||||
<
|
||||
Geometry1, Geometry2,
|
||||
Reverse1, Reverse2,
|
||||
Turns,
|
||||
TurnPolicy,
|
||||
InterruptPolicy
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Polygon, typename Box,
|
||||
bool ReversePolygon, bool ReverseBox,
|
||||
typename Turns,
|
||||
typename TurnPolicy,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
struct get_turns
|
||||
<
|
||||
polygon_tag, box_tag,
|
||||
Polygon, Box,
|
||||
ReversePolygon, ReverseBox,
|
||||
Turns,
|
||||
TurnPolicy,
|
||||
InterruptPolicy
|
||||
> : detail::get_turns::get_turns_polygon_cs
|
||||
<
|
||||
Polygon, Box,
|
||||
ReversePolygon, ReverseBox,
|
||||
Turns, TurnPolicy, InterruptPolicy
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Ring, typename Box,
|
||||
bool ReverseRing, bool ReverseBox,
|
||||
typename Turns,
|
||||
typename TurnPolicy,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
struct get_turns
|
||||
<
|
||||
ring_tag, box_tag,
|
||||
Ring, Box,
|
||||
ReverseRing, ReverseBox,
|
||||
Turns,
|
||||
TurnPolicy,
|
||||
InterruptPolicy
|
||||
> : detail::get_turns::get_turns_cs
|
||||
<
|
||||
Ring, Box, ReverseRing, ReverseBox,
|
||||
Turns, TurnPolicy, InterruptPolicy
|
||||
>
|
||||
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryTag1, typename GeometryTag2,
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2,
|
||||
typename Turns,
|
||||
typename TurnPolicy,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
struct get_turns_reversed
|
||||
{
|
||||
static inline void apply(
|
||||
int source_id1, Geometry1 const& g1,
|
||||
int source_id2, Geometry2 const& g2,
|
||||
Turns& turns, InterruptPolicy& interrupt_policy)
|
||||
{
|
||||
get_turns
|
||||
<
|
||||
GeometryTag2, GeometryTag1,
|
||||
Geometry2, Geometry1,
|
||||
Reverse2, Reverse1,
|
||||
Turns, TurnPolicy,
|
||||
InterruptPolicy
|
||||
>::apply(source_id2, g2, source_id1, g1, turns, interrupt_policy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc2{turn points}
|
||||
\ingroup overlay
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam Turns type of turn-container (e.g. vector of "intersection/turn point"'s)
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param turns container which will contain turn points
|
||||
\param interrupt_policy policy determining if process is stopped
|
||||
when intersection is found
|
||||
*/
|
||||
template
|
||||
<
|
||||
bool Reverse1, bool Reverse2,
|
||||
typename AssignPolicy,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Turns,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
inline void get_turns(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Turns& turns,
|
||||
InterruptPolicy& interrupt_policy)
|
||||
{
|
||||
concept::check_concepts_and_equal_dimensions<Geometry1 const, Geometry2 const>();
|
||||
|
||||
typedef typename strategy_intersection
|
||||
<
|
||||
typename cs_tag<Geometry1>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
typename boost::range_value<Turns>::type
|
||||
>::segment_intersection_strategy_type segment_intersection_strategy_type;
|
||||
|
||||
typedef detail::overlay::get_turn_info
|
||||
<
|
||||
typename point_type<Geometry1>::type,
|
||||
typename point_type<Geometry2>::type,
|
||||
typename boost::range_value<Turns>::type,
|
||||
AssignPolicy
|
||||
> TurnPolicy;
|
||||
|
||||
boost::mpl::if_c
|
||||
<
|
||||
reverse_dispatch<Geometry1, Geometry2>::type::value,
|
||||
dispatch::get_turns_reversed
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
Geometry1, Geometry2,
|
||||
Reverse1, Reverse2,
|
||||
Turns, TurnPolicy,
|
||||
InterruptPolicy
|
||||
>,
|
||||
dispatch::get_turns
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
Geometry1, Geometry2,
|
||||
Reverse1, Reverse2,
|
||||
Turns, TurnPolicy,
|
||||
InterruptPolicy
|
||||
>
|
||||
>::type::apply(
|
||||
0, geometry1,
|
||||
1, geometry2,
|
||||
turns, interrupt_policy);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP
|
||||
666
test/external/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp
vendored
Normal file
666
test/external/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp
vendored
Normal file
@@ -0,0 +1,666 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_HANDLE_TANGENCIES_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_HANDLE_TANGENCIES_HPP
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/segment.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename TurnPoints,
|
||||
typename Indexed,
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2,
|
||||
typename Strategy
|
||||
>
|
||||
struct sort_in_cluster
|
||||
{
|
||||
inline sort_in_cluster(TurnPoints const& turn_points
|
||||
, Geometry1 const& geometry1
|
||||
, Geometry2 const& geometry2
|
||||
, Strategy const& strategy)
|
||||
: m_turn_points(turn_points)
|
||||
, m_geometry1(geometry1)
|
||||
, m_geometry2(geometry2)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
private :
|
||||
|
||||
TurnPoints const& m_turn_points;
|
||||
Geometry1 const& m_geometry1;
|
||||
Geometry2 const& m_geometry2;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
typedef typename Indexed::type turn_operation_type;
|
||||
typedef typename geometry::point_type<Geometry1>::type point_type;
|
||||
typedef model::referring_segment<point_type const> segment_type;
|
||||
|
||||
// Determine how p/r and p/s are located.
|
||||
template <typename P>
|
||||
static inline void overlap_info(P const& pi, P const& pj,
|
||||
P const& ri, P const& rj,
|
||||
P const& si, P const& sj,
|
||||
bool& pr_overlap, bool& ps_overlap, bool& rs_overlap)
|
||||
{
|
||||
// Determine how p/r and p/s are located.
|
||||
// One of them is coming from opposite direction.
|
||||
|
||||
typedef strategy::intersection::relate_cartesian_segments
|
||||
<
|
||||
policies::relate::segments_intersection_points
|
||||
<
|
||||
segment_type,
|
||||
segment_type,
|
||||
segment_intersection_points<point_type>
|
||||
>
|
||||
> policy;
|
||||
|
||||
segment_type p(pi, pj);
|
||||
segment_type r(ri, rj);
|
||||
segment_type s(si, sj);
|
||||
|
||||
// Get the intersection point (or two points)
|
||||
segment_intersection_points<point_type> pr = policy::apply(p, r);
|
||||
segment_intersection_points<point_type> ps = policy::apply(p, s);
|
||||
segment_intersection_points<point_type> rs = policy::apply(r, s);
|
||||
|
||||
// Check on overlap
|
||||
pr_overlap = pr.count == 2;
|
||||
ps_overlap = ps.count == 2;
|
||||
rs_overlap = rs.count == 2;
|
||||
}
|
||||
|
||||
|
||||
inline void debug_consider(int order, Indexed const& left,
|
||||
Indexed const& right, std::string const& header,
|
||||
bool skip = true,
|
||||
std::string const& extra = "", bool ret = false
|
||||
) const
|
||||
{
|
||||
if (skip) return;
|
||||
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
|
||||
point_type pi, pj, ri, rj, si, sj;
|
||||
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
|
||||
left.subject.seg_id,
|
||||
pi, pj);
|
||||
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
|
||||
left.subject.other_id,
|
||||
ri, rj);
|
||||
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
|
||||
right.subject.other_id,
|
||||
si, sj);
|
||||
|
||||
bool prc = false, psc = false, rsc = false;
|
||||
overlap_info(pi, pj, ri, rj, si, sj, prc, psc, rsc);
|
||||
|
||||
int const side_ri_p = m_strategy.apply(pi, pj, ri);
|
||||
int const side_rj_p = m_strategy.apply(pi, pj, rj);
|
||||
int const side_si_p = m_strategy.apply(pi, pj, si);
|
||||
int const side_sj_p = m_strategy.apply(pi, pj, sj);
|
||||
int const side_si_r = m_strategy.apply(ri, rj, si);
|
||||
int const side_sj_r = m_strategy.apply(ri, rj, sj);
|
||||
|
||||
std::cout << "Case: " << header << " for " << left.index << " / " << right.index << std::endl;
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH_MORE
|
||||
std::cout << " Segment p:" << geometry::wkt(pi) << " .. " << geometry::wkt(pj) << std::endl;
|
||||
std::cout << " Segment r:" << geometry::wkt(ri) << " .. " << geometry::wkt(rj) << std::endl;
|
||||
std::cout << " Segment s:" << geometry::wkt(si) << " .. " << geometry::wkt(sj) << std::endl;
|
||||
|
||||
std::cout << " r//p: " << side_ri_p << " / " << side_rj_p << std::endl;
|
||||
std::cout << " s//p: " << side_si_p << " / " << side_sj_p << std::endl;
|
||||
std::cout << " s//r: " << side_si_r << " / " << side_sj_r << std::endl;
|
||||
#endif
|
||||
|
||||
std::cout << header
|
||||
//<< " order: " << order
|
||||
<< " ops: " << operation_char(left.subject.operation)
|
||||
<< "/" << operation_char(right.subject.operation)
|
||||
<< " ri//p: " << side_ri_p
|
||||
<< " si//p: " << side_si_p
|
||||
<< " si//r: " << side_si_r
|
||||
<< " cnts: " << int(prc) << "," << int(psc) << "," << int(rsc)
|
||||
//<< " idx: " << left.index << "/" << right.index
|
||||
;
|
||||
|
||||
if (! extra.empty())
|
||||
{
|
||||
std::cout << " " << extra << " " << (ret ? "true" : "false");
|
||||
}
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// ux/ux
|
||||
inline bool consider_ux_ux(Indexed const& left,
|
||||
Indexed const& right
|
||||
, std::string const& header
|
||||
) const
|
||||
{
|
||||
bool ret = left.index < right.index;
|
||||
|
||||
// In combination of u/x, x/u: take first union, then blocked.
|
||||
// Solves #88, #61, #56, #80
|
||||
if (left.subject.operation == operation_union
|
||||
&& right.subject.operation == operation_blocked)
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else if (left.subject.operation == operation_blocked
|
||||
&& right.subject.operation == operation_union)
|
||||
{
|
||||
ret = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
|
||||
std::cout << "ux/ux unhandled" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
//debug_consider(0, left, right, header, false, "-> return ", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline bool consider_iu_ux(Indexed const& left,
|
||||
Indexed const& right,
|
||||
int order // 1: iu first, -1: ux first
|
||||
, std::string const& header
|
||||
) const
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if (left.subject.operation == operation_union
|
||||
&& right.subject.operation == operation_union)
|
||||
{
|
||||
ret = order == 1;
|
||||
}
|
||||
else if (left.subject.operation == operation_union
|
||||
&& right.subject.operation == operation_blocked)
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else if (right.subject.operation == operation_union
|
||||
&& left.subject.operation == operation_blocked)
|
||||
{
|
||||
ret = false;
|
||||
}
|
||||
else if (left.subject.operation == operation_union)
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else if (right.subject.operation == operation_union)
|
||||
{
|
||||
ret = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
|
||||
// this still happens in the traverse.cpp test
|
||||
std::cout << " iu/ux unhandled" << std::endl;
|
||||
#endif
|
||||
ret = order == 1;
|
||||
}
|
||||
|
||||
//debug_consider(0, left, right, header, false, "-> return", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline bool consider_iu_ix(Indexed const& left,
|
||||
Indexed const& right,
|
||||
int order // 1: iu first, -1: ix first
|
||||
, std::string const& header
|
||||
) const
|
||||
{
|
||||
//debug_consider(order, left, right, header, false, "iu/ix");
|
||||
|
||||
return left.subject.operation == operation_intersection
|
||||
&& right.subject.operation == operation_intersection ? order == 1
|
||||
: left.subject.operation == operation_intersection ? false
|
||||
: right.subject.operation == operation_intersection ? true
|
||||
: order == 1;
|
||||
}
|
||||
|
||||
|
||||
inline bool consider_iu_iu(Indexed const& left, Indexed const& right,
|
||||
std::string const& header) const
|
||||
{
|
||||
//debug_consider(0, left, right, header);
|
||||
|
||||
// In general, order it like "union, intersection".
|
||||
if (left.subject.operation == operation_intersection
|
||||
&& right.subject.operation == operation_union)
|
||||
{
|
||||
//debug_consider(0, left, right, header, false, "i,u", false);
|
||||
return false;
|
||||
}
|
||||
else if (left.subject.operation == operation_union
|
||||
&& right.subject.operation == operation_intersection)
|
||||
{
|
||||
//debug_consider(0, left, right, header, false, "u,i", true);
|
||||
return true;
|
||||
}
|
||||
|
||||
point_type pi, pj, ri, rj, si, sj;
|
||||
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
|
||||
left.subject.seg_id,
|
||||
pi, pj);
|
||||
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
|
||||
left.subject.other_id,
|
||||
ri, rj);
|
||||
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
|
||||
right.subject.other_id,
|
||||
si, sj);
|
||||
|
||||
int const side_ri_p = m_strategy.apply(pi, pj, ri);
|
||||
int const side_si_p = m_strategy.apply(pi, pj, si);
|
||||
int const side_si_r = m_strategy.apply(ri, rj, si);
|
||||
|
||||
// Both located at same side (#58, pie_21_7_21_0_3)
|
||||
if (side_ri_p * side_si_p == 1 && side_si_r != 0)
|
||||
{
|
||||
// Take the most left one
|
||||
if (left.subject.operation == operation_union
|
||||
&& right.subject.operation == operation_union)
|
||||
{
|
||||
bool ret = side_si_r == 1;
|
||||
//debug_consider(0, left, right, header, false, "same side", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Coming from opposite sides (#59, #99)
|
||||
if (side_ri_p * side_si_p == -1)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
{
|
||||
ret = side_ri_p == 1; // #100
|
||||
debug_consider(0, left, right, header, false, "opp.", ret);
|
||||
return ret;
|
||||
}
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
|
||||
std::cout << " iu/iu coming from opposite unhandled" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
// We need EXTRA information here: are p/r/s overlapping?
|
||||
bool pr_ov = false, ps_ov = false, rs_ov = false;
|
||||
overlap_info(pi, pj, ri, rj, si, sj, pr_ov, ps_ov, rs_ov);
|
||||
|
||||
// One coming from right (#83,#90)
|
||||
// One coming from left (#90, #94, #95)
|
||||
if (side_si_r != 0 && (side_ri_p != 0 || side_si_p != 0))
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if (pr_ov || ps_ov)
|
||||
{
|
||||
int r = side_ri_p != 0 ? side_ri_p : side_si_p;
|
||||
ret = r * side_si_r == 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = side_si_r == 1;
|
||||
}
|
||||
|
||||
debug_consider(0, left, right, header, false, "left or right", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// All aligned (#92, #96)
|
||||
if (side_ri_p == 0 && side_si_p == 0 && side_si_r == 0)
|
||||
{
|
||||
// One of them is coming from opposite direction.
|
||||
|
||||
// Take the one NOT overlapping
|
||||
bool ret = false;
|
||||
bool found = false;
|
||||
if (pr_ov && ! ps_ov)
|
||||
{
|
||||
ret = true;
|
||||
found = true;
|
||||
}
|
||||
else if (!pr_ov && ps_ov)
|
||||
{
|
||||
ret = false;
|
||||
found = true;
|
||||
}
|
||||
|
||||
debug_consider(0, left, right, header, false, "aligned", ret);
|
||||
if (found)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
|
||||
std::cout << " iu/iu unhandled" << std::endl;
|
||||
debug_consider(0, left, right, header, false, "unhandled", left.index < right.index);
|
||||
#endif
|
||||
return left.index < right.index;
|
||||
}
|
||||
|
||||
inline bool consider_ii(Indexed const& left, Indexed const& right,
|
||||
std::string const& header) const
|
||||
{
|
||||
debug_consider(0, left, right, header);
|
||||
|
||||
point_type pi, pj, ri, rj, si, sj;
|
||||
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
|
||||
left.subject.seg_id,
|
||||
pi, pj);
|
||||
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
|
||||
left.subject.other_id,
|
||||
ri, rj);
|
||||
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
|
||||
right.subject.other_id,
|
||||
si, sj);
|
||||
|
||||
int const side_ri_p = m_strategy.apply(pi, pj, ri);
|
||||
int const side_si_p = m_strategy.apply(pi, pj, si);
|
||||
|
||||
// Two other points are (mostly) lying both right of the considered segment
|
||||
// Take the most left one
|
||||
int const side_si_r = m_strategy.apply(ri, rj, si);
|
||||
if (side_ri_p == -1
|
||||
&& side_si_p == -1
|
||||
&& side_si_r != 0)
|
||||
{
|
||||
bool const ret = side_si_r != 1;
|
||||
return ret;
|
||||
}
|
||||
return left.index < right.index;
|
||||
}
|
||||
|
||||
|
||||
public :
|
||||
inline bool operator()(Indexed const& left, Indexed const& right) const
|
||||
{
|
||||
bool const default_order = left.index < right.index;
|
||||
|
||||
if ((m_turn_points[left.index].discarded || left.discarded)
|
||||
&& (m_turn_points[right.index].discarded || right.discarded))
|
||||
{
|
||||
return default_order;
|
||||
}
|
||||
else if (m_turn_points[left.index].discarded || left.discarded)
|
||||
{
|
||||
// Be careful to sort discarded first, then all others
|
||||
return true;
|
||||
}
|
||||
else if (m_turn_points[right.index].discarded || right.discarded)
|
||||
{
|
||||
// See above so return false here such that right (discarded)
|
||||
// is sorted before left (not discarded)
|
||||
return false;
|
||||
}
|
||||
else if (m_turn_points[left.index].combination(operation_blocked, operation_union)
|
||||
&& m_turn_points[right.index].combination(operation_blocked, operation_union))
|
||||
{
|
||||
// ux/ux
|
||||
return consider_ux_ux(left, right, "ux/ux");
|
||||
}
|
||||
else if (m_turn_points[left.index].both(operation_union)
|
||||
&& m_turn_points[right.index].both(operation_union))
|
||||
{
|
||||
// uu/uu, Order is arbitrary
|
||||
// Note: uu/uu is discarded now before so this point will
|
||||
// not be reached.
|
||||
return default_order;
|
||||
}
|
||||
else if (m_turn_points[left.index].combination(operation_intersection, operation_union)
|
||||
&& m_turn_points[right.index].combination(operation_intersection, operation_union))
|
||||
{
|
||||
return consider_iu_iu(left, right, "iu/iu");
|
||||
}
|
||||
else if (m_turn_points[left.index].both(operation_intersection)
|
||||
&& m_turn_points[right.index].both(operation_intersection))
|
||||
{
|
||||
return consider_ii(left, right, "ii/ii");
|
||||
}
|
||||
else if (m_turn_points[left.index].combination(operation_union, operation_blocked)
|
||||
&& m_turn_points[right.index].combination(operation_intersection, operation_union))
|
||||
{
|
||||
return consider_iu_ux(left, right, -1, "ux/iu");
|
||||
}
|
||||
else if (m_turn_points[left.index].combination(operation_intersection, operation_union)
|
||||
&& m_turn_points[right.index].combination(operation_union, operation_blocked))
|
||||
{
|
||||
return consider_iu_ux(left, right, 1, "iu/ux");
|
||||
}
|
||||
else if (m_turn_points[left.index].combination(operation_intersection, operation_blocked)
|
||||
&& m_turn_points[right.index].combination(operation_intersection, operation_union))
|
||||
{
|
||||
return consider_iu_ix(left, right, 1, "ix/iu");
|
||||
}
|
||||
else if (m_turn_points[left.index].combination(operation_intersection, operation_union)
|
||||
&& m_turn_points[right.index].combination(operation_intersection, operation_blocked))
|
||||
{
|
||||
return consider_iu_ix(left, right, -1, "iu/ix");
|
||||
}
|
||||
else if (m_turn_points[left.index].method != method_equal
|
||||
&& m_turn_points[right.index].method == method_equal
|
||||
)
|
||||
{
|
||||
// If one of them was EQUAL or CONTINUES, it should always come first
|
||||
return false;
|
||||
}
|
||||
else if (m_turn_points[left.index].method == method_equal
|
||||
&& m_turn_points[right.index].method != method_equal
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Now we have no clue how to sort.
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
|
||||
std::cout << " Consider: " << operation_char(m_turn_points[left.index].operations[0].operation)
|
||||
<< operation_char(m_turn_points[left.index].operations[1].operation)
|
||||
<< "/" << operation_char(m_turn_points[right.index].operations[0].operation)
|
||||
<< operation_char(m_turn_points[right.index].operations[1].operation)
|
||||
<< " " << " Take " << left.index << " < " << right.index
|
||||
<< std::cout;
|
||||
#endif
|
||||
|
||||
return default_order;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename IndexType,
|
||||
typename Iterator,
|
||||
typename TurnPoints,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Strategy
|
||||
>
|
||||
inline void inspect_cluster(Iterator begin_cluster, Iterator end_cluster,
|
||||
TurnPoints& turn_points,
|
||||
operation_type for_operation,
|
||||
Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
// Make an analysis about all occuring cases here.
|
||||
std::map<std::pair<operation_type, operation_type>, int> inspection;
|
||||
for (Iterator it = begin_cluster; it != end_cluster; ++it)
|
||||
{
|
||||
operation_type first = turn_points[it->index].operations[0].operation;
|
||||
operation_type second = turn_points[it->index].operations[1].operation;
|
||||
if (first > second)
|
||||
{
|
||||
std::swap(first, second);
|
||||
}
|
||||
inspection[std::make_pair(first, second)]++;
|
||||
count++;
|
||||
}
|
||||
|
||||
|
||||
bool keep_cc = false;
|
||||
|
||||
// Decide about which is going to be discarded here.
|
||||
if (inspection[std::make_pair(operation_union, operation_union)] == 1
|
||||
&& inspection[std::make_pair(operation_continue, operation_continue)] == 1)
|
||||
{
|
||||
// In case of uu/cc, discard the uu, that indicates a tangency and
|
||||
// inclusion would disturb the (e.g.) cc-cc-cc ordering
|
||||
// NOTE: uu is now discarded anyhow.
|
||||
keep_cc = true;
|
||||
}
|
||||
else if (count == 2
|
||||
&& inspection[std::make_pair(operation_intersection, operation_intersection)] == 1
|
||||
&& inspection[std::make_pair(operation_union, operation_intersection)] == 1)
|
||||
{
|
||||
// In case of ii/iu, discard the iu. The ii should always be visited,
|
||||
// Because (in case of not discarding iu) correctly ordering of ii/iu appears impossible
|
||||
for (Iterator it = begin_cluster; it != end_cluster; ++it)
|
||||
{
|
||||
if (turn_points[it->index].combination(operation_intersection, operation_union))
|
||||
{
|
||||
it->discarded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Discard any continue turn, unless it is the only thing left
|
||||
// (necessary to avoid cc-only rings, all being discarded
|
||||
// e.g. traversal case #75)
|
||||
int nd_count= 0, cc_count = 0;
|
||||
for (Iterator it = begin_cluster; it != end_cluster; ++it)
|
||||
{
|
||||
if (! it->discarded)
|
||||
{
|
||||
nd_count++;
|
||||
if (turn_points[it->index].both(operation_continue))
|
||||
{
|
||||
cc_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nd_count == cc_count)
|
||||
{
|
||||
keep_cc = true;
|
||||
}
|
||||
|
||||
if (! keep_cc)
|
||||
{
|
||||
for (Iterator it = begin_cluster; it != end_cluster; ++it)
|
||||
{
|
||||
if (turn_points[it->index].both(operation_continue))
|
||||
{
|
||||
it->discarded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename IndexType,
|
||||
bool Reverse1, bool Reverse2,
|
||||
typename Iterator,
|
||||
typename TurnPoints,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Strategy
|
||||
>
|
||||
inline void handle_cluster(Iterator begin_cluster, Iterator end_cluster,
|
||||
TurnPoints& turn_points,
|
||||
operation_type for_operation,
|
||||
Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
// First inspect and (possibly) discard rows
|
||||
inspect_cluster<IndexType>(begin_cluster, end_cluster, turn_points,
|
||||
for_operation, geometry1, geometry2, strategy);
|
||||
|
||||
|
||||
// Then sort this range (discard rows will be ordered first and will be removed in enrich_assign)
|
||||
std::sort(begin_cluster, end_cluster,
|
||||
sort_in_cluster
|
||||
<
|
||||
TurnPoints,
|
||||
IndexType,
|
||||
Geometry1, Geometry2,
|
||||
Reverse1, Reverse2,
|
||||
Strategy
|
||||
>(turn_points, geometry1, geometry2, strategy));
|
||||
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
|
||||
typedef typename IndexType::type operations_type;
|
||||
operations_type const& op = turn_points[begin_cluster->index].operations[begin_cluster->operation_index];
|
||||
std::cout << "Clustered points on equal distance " << op.enriched.distance << std::endl;
|
||||
std::cout << "->Indexes ";
|
||||
|
||||
for (Iterator it = begin_cluster; it != end_cluster; ++it)
|
||||
{
|
||||
std::cout << " " << it->index;
|
||||
}
|
||||
std::cout << std::endl << "->Methods: ";
|
||||
for (Iterator it = begin_cluster; it != end_cluster; ++it)
|
||||
{
|
||||
std::cout << " " << method_char(turn_points[it->index].method);
|
||||
}
|
||||
std::cout << std::endl << "->Operations: ";
|
||||
for (Iterator it = begin_cluster; it != end_cluster; ++it)
|
||||
{
|
||||
std::cout << " " << operation_char(turn_points[it->index].operations[0].operation)
|
||||
<< operation_char(turn_points[it->index].operations[1].operation);
|
||||
}
|
||||
std::cout << std::endl << "->Discarded: ";
|
||||
for (Iterator it = begin_cluster; it != end_cluster; ++it)
|
||||
{
|
||||
std::cout << " " << (it->discarded ? "true" : "false");
|
||||
}
|
||||
std::cout << std::endl;
|
||||
//<< "\tOn segments: " << prev_op.seg_id << " / " << prev_op.other_id
|
||||
//<< " and " << op.seg_id << " / " << op.other_id
|
||||
//<< geometry::distance(turn_points[prev->index].point, turn_points[it->index].point)
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif //DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_HANDLE_TANGENCIES_HPP
|
||||
527
test/external/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp
vendored
Normal file
527
test/external/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp
vendored
Normal file
@@ -0,0 +1,527 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/range/metafunctions.hpp>
|
||||
|
||||
|
||||
#include <boost/geometry/core/is_areal.hpp>
|
||||
#include <boost/geometry/core/point_order.hpp>
|
||||
#include <boost/geometry/core/reverse_dispatch.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/algorithms/convert.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/clip_linestring.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
|
||||
#include <boost/geometry/views/segment_view.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace intersection
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Segment1, typename Segment2,
|
||||
typename OutputIterator, typename PointOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_segment_segment_point
|
||||
{
|
||||
static inline OutputIterator apply(Segment1 const& segment1,
|
||||
Segment2 const& segment2, OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename point_type<PointOut>::type point_type;
|
||||
|
||||
// Get the intersection point (or two points)
|
||||
segment_intersection_points<point_type> is
|
||||
= strategy::intersection::relate_cartesian_segments
|
||||
<
|
||||
policies::relate::segments_intersection_points
|
||||
<
|
||||
Segment1,
|
||||
Segment2,
|
||||
segment_intersection_points<point_type>
|
||||
>
|
||||
>::apply(segment1, segment2);
|
||||
|
||||
for (std::size_t i = 0; i < is.count; i++)
|
||||
{
|
||||
PointOut p;
|
||||
geometry::convert(is.intersections[i], p);
|
||||
*out++ = p;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Linestring1, typename Linestring2,
|
||||
typename OutputIterator, typename PointOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_linestring_linestring_point
|
||||
{
|
||||
static inline OutputIterator apply(Linestring1 const& linestring1,
|
||||
Linestring2 const& linestring2, OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename point_type<PointOut>::type point_type;
|
||||
|
||||
typedef detail::overlay::turn_info<point_type> turn_info;
|
||||
std::deque<turn_info> turns;
|
||||
|
||||
geometry::get_intersection_points(linestring1, linestring2, turns);
|
||||
|
||||
for (typename boost::range_iterator<std::deque<turn_info> const>::type
|
||||
it = boost::begin(turns); it != boost::end(turns); ++it)
|
||||
{
|
||||
PointOut p;
|
||||
geometry::convert(it->point, p);
|
||||
*out++ = p;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::intersection
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
// tag dispatching:
|
||||
typename TagIn1, typename TagIn2, typename TagOut,
|
||||
// orientation
|
||||
// metafunction finetuning helpers:
|
||||
bool Areal1, bool Areal2, bool ArealOut,
|
||||
// real types
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_insert
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPES_OR_ORIENTATIONS
|
||||
, (types<Geometry1, Geometry2, GeometryOut>)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename TagIn1, typename TagIn2, typename TagOut,
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
TagIn1, TagIn2, TagOut,
|
||||
true, true, true,
|
||||
Geometry1, Geometry2,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
> : detail::overlay::overlay
|
||||
<Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, OverlayType, Strategy>
|
||||
{};
|
||||
|
||||
|
||||
// Any areal type with box:
|
||||
template
|
||||
<
|
||||
typename TagIn, typename TagOut,
|
||||
typename Geometry, typename Box,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
TagIn, box_tag, TagOut,
|
||||
true, true, true,
|
||||
Geometry, Box,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
> : detail::overlay::overlay
|
||||
<Geometry, Box, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, OverlayType, Strategy>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Segment1, typename Segment2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
segment_tag, segment_tag, point_tag,
|
||||
false, false, false,
|
||||
Segment1, Segment2,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType, Strategy
|
||||
> : detail::intersection::intersection_segment_segment_point
|
||||
<
|
||||
Segment1, Segment2,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Linestring1, typename Linestring2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
linestring_tag, linestring_tag, point_tag,
|
||||
false, false, false,
|
||||
Linestring1, Linestring2,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType, Strategy
|
||||
> : detail::intersection::intersection_linestring_linestring_point
|
||||
<
|
||||
Linestring1, Linestring2,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Linestring, typename Box,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
linestring_tag, box_tag, linestring_tag,
|
||||
false, true, false,
|
||||
Linestring, Box,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
>
|
||||
{
|
||||
static inline OutputIterator apply(Linestring const& linestring,
|
||||
Box const& box, OutputIterator out, Strategy const& strategy)
|
||||
{
|
||||
typedef typename point_type<GeometryOut>::type point_type;
|
||||
strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
|
||||
return detail::intersection::clip_range_with_box
|
||||
<GeometryOut>(box, linestring, out, lb_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Segment, typename Box,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
segment_tag, box_tag, linestring_tag,
|
||||
false, true, false,
|
||||
Segment, Box,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
>
|
||||
{
|
||||
static inline OutputIterator apply(Segment const& segment,
|
||||
Box const& box, OutputIterator out, Strategy const& strategy)
|
||||
{
|
||||
geometry::segment_view<Segment> range(segment);
|
||||
|
||||
typedef typename point_type<GeometryOut>::type point_type;
|
||||
strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
|
||||
return detail::intersection::clip_range_with_box
|
||||
<GeometryOut>(box, range, out, lb_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag1, typename Tag2,
|
||||
bool Areal1, bool Areal2,
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename PointOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
Tag1, Tag2, point_tag,
|
||||
Areal1, Areal2, false,
|
||||
Geometry1, Geometry2,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, PointOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
>
|
||||
{
|
||||
static inline OutputIterator apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2, OutputIterator out, Strategy const& strategy)
|
||||
{
|
||||
|
||||
typedef detail::overlay::turn_info<PointOut> turn_info;
|
||||
std::vector<turn_info> turns;
|
||||
|
||||
detail::get_turns::no_interrupt_policy policy;
|
||||
geometry::get_turns
|
||||
<
|
||||
false, false, detail::overlay::assign_null_policy
|
||||
>(geometry1, geometry2, turns, policy);
|
||||
for (typename std::vector<turn_info>::const_iterator it
|
||||
= turns.begin(); it != turns.end(); ++it)
|
||||
{
|
||||
*out++ = it->point;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryTag1, typename GeometryTag2, typename GeometryTag3,
|
||||
bool Areal1, bool Areal2, bool ArealOut,
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_insert_reversed
|
||||
{
|
||||
static inline OutputIterator apply(Geometry1 const& g1,
|
||||
Geometry2 const& g2, OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return intersection_insert
|
||||
<
|
||||
GeometryTag2, GeometryTag1, GeometryTag3,
|
||||
Areal2, Areal1, ArealOut,
|
||||
Geometry2, Geometry1,
|
||||
Reverse2, Reverse1, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
>::apply(g2, g1, out, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace intersection
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryOut,
|
||||
bool ReverseSecond,
|
||||
overlay_type OverlayType,
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename OutputIterator,
|
||||
typename Strategy
|
||||
>
|
||||
inline OutputIterator insert(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::mpl::if_c
|
||||
<
|
||||
geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
|
||||
geometry::dispatch::intersection_insert_reversed
|
||||
<
|
||||
typename geometry::tag<Geometry1>::type,
|
||||
typename geometry::tag<Geometry2>::type,
|
||||
typename geometry::tag<GeometryOut>::type,
|
||||
geometry::is_areal<Geometry1>::value,
|
||||
geometry::is_areal<Geometry2>::value,
|
||||
geometry::is_areal<GeometryOut>::value,
|
||||
Geometry1, Geometry2,
|
||||
overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
|
||||
overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value,
|
||||
overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
>,
|
||||
geometry::dispatch::intersection_insert
|
||||
<
|
||||
typename geometry::tag<Geometry1>::type,
|
||||
typename geometry::tag<Geometry2>::type,
|
||||
typename geometry::tag<GeometryOut>::type,
|
||||
geometry::is_areal<Geometry1>::value,
|
||||
geometry::is_areal<Geometry2>::value,
|
||||
geometry::is_areal<GeometryOut>::value,
|
||||
Geometry1, Geometry2,
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value,
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
>
|
||||
>::type::apply(geometry1, geometry2, out, strategy);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc2{intersection} \brief_strategy
|
||||
\ingroup intersection
|
||||
\details \details_calc2{intersection_insert, spatial set theoretic intersection}
|
||||
\brief_strategy. \details_insert{intersection}
|
||||
\tparam GeometryOut \tparam_geometry{\p_l_or_c}
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam OutputIterator \tparam_out{\p_l_or_c}
|
||||
\tparam Strategy \tparam_strategy_overlay
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param out \param_out{intersection}
|
||||
\param strategy \param_strategy{intersection}
|
||||
\return \return_out
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{[include reference/algorithms/intersection.qbk]}
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename GeometryOut,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename OutputIterator,
|
||||
typename Strategy
|
||||
>
|
||||
inline OutputIterator intersection_insert(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
return detail::intersection::insert
|
||||
<
|
||||
GeometryOut, false, overlay_intersection
|
||||
>(geometry1, geometry2, out, strategy);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc2{intersection}
|
||||
\ingroup intersection
|
||||
\details \details_calc2{intersection_insert, spatial set theoretic intersection}.
|
||||
\details_insert{intersection}
|
||||
\tparam GeometryOut \tparam_geometry{\p_l_or_c}
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam OutputIterator \tparam_out{\p_l_or_c}
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param out \param_out{intersection}
|
||||
\return \return_out
|
||||
|
||||
\qbk{[include reference/algorithms/intersection.qbk]}
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename GeometryOut,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename OutputIterator
|
||||
>
|
||||
inline OutputIterator intersection_insert(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
OutputIterator out)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
typedef strategy_intersection
|
||||
<
|
||||
typename cs_tag<GeometryOut>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
typename geometry::point_type<GeometryOut>::type
|
||||
> strategy;
|
||||
|
||||
return intersection_insert<GeometryOut>(geometry1, geometry2, out,
|
||||
strategy());
|
||||
}
|
||||
|
||||
}} // namespace detail::intersection
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP
|
||||
300
test/external/boost/geometry/algorithms/detail/overlay/overlay.hpp
vendored
Normal file
300
test/external/boost/geometry/algorithms/detail/overlay/overlay.hpp
vendored
Normal file
@@ -0,0 +1,300 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_OVERLAY_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_OVERLAY_HPP
|
||||
|
||||
|
||||
#include <deque>
|
||||
#include <map>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/calculate_distance_policy.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/enrichment_info.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/traverse.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/traversal_info.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
|
||||
|
||||
|
||||
#include <boost/geometry/algorithms/num_points.hpp>
|
||||
#include <boost/geometry/algorithms/reverse.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/add_rings.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/assign_parents.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/ring_properties.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/select_rings.hpp>
|
||||
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
|
||||
# include <boost/geometry/util/write_dsv.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
// Skip for assemble process
|
||||
template <typename TurnInfo>
|
||||
inline bool skip(TurnInfo const& turn_info)
|
||||
{
|
||||
return (turn_info.discarded || turn_info.both(operation_union))
|
||||
&& ! turn_info.any_blocked()
|
||||
&& ! turn_info.both(operation_intersection)
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
template <typename TurnPoints, typename Map>
|
||||
inline void map_turns(Map& map, TurnPoints const& turn_points)
|
||||
{
|
||||
typedef typename boost::range_value<TurnPoints>::type turn_point_type;
|
||||
typedef typename turn_point_type::container_type container_type;
|
||||
|
||||
int index = 0;
|
||||
for (typename boost::range_iterator<TurnPoints const>::type
|
||||
it = boost::begin(turn_points);
|
||||
it != boost::end(turn_points);
|
||||
++it, ++index)
|
||||
{
|
||||
if (! skip(*it))
|
||||
{
|
||||
int op_index = 0;
|
||||
for (typename boost::range_iterator<container_type const>::type
|
||||
op_it = boost::begin(it->operations);
|
||||
op_it != boost::end(it->operations);
|
||||
++op_it, ++op_index)
|
||||
{
|
||||
ring_identifier ring_id
|
||||
(
|
||||
op_it->seg_id.source_index,
|
||||
op_it->seg_id.multi_index,
|
||||
op_it->seg_id.ring_index
|
||||
);
|
||||
map[ring_id]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryOut, overlay_type Direction, bool ReverseOut,
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename OutputIterator
|
||||
>
|
||||
inline OutputIterator return_if_one_input_is_empty(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
OutputIterator out)
|
||||
{
|
||||
typedef std::deque
|
||||
<
|
||||
typename geometry::ring_type<GeometryOut>::type
|
||||
> ring_container_type;
|
||||
|
||||
typedef ring_properties<typename geometry::point_type<Geometry1>::type> properties;
|
||||
|
||||
// Union: return either of them
|
||||
// Intersection: return nothing
|
||||
// Difference: return first of them
|
||||
if (Direction == overlay_intersection
|
||||
|| (Direction == overlay_difference
|
||||
&& geometry::num_points(geometry1) == 0))
|
||||
{
|
||||
return out;
|
||||
}
|
||||
|
||||
std::map<ring_identifier, int> empty;
|
||||
std::map<ring_identifier, properties> all_of_one_of_them;
|
||||
|
||||
select_rings<Direction>(geometry1, geometry2, empty, all_of_one_of_them, false);
|
||||
ring_container_type rings;
|
||||
assign_parents(geometry1, geometry2, rings, all_of_one_of_them);
|
||||
return add_rings<GeometryOut>(all_of_one_of_them, geometry1, geometry2, rings, out);
|
||||
}
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
overlay_type Direction,
|
||||
typename Strategy
|
||||
>
|
||||
struct overlay
|
||||
{
|
||||
static inline OutputIterator apply(
|
||||
Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
OutputIterator out,
|
||||
Strategy const& )
|
||||
{
|
||||
if (geometry::num_points(geometry1) == 0 && geometry::num_points(geometry2) == 0)
|
||||
{
|
||||
return out;
|
||||
}
|
||||
|
||||
typedef typename geometry::point_type<GeometryOut>::type point_type;
|
||||
typedef detail::overlay::traversal_turn_info<point_type> turn_info;
|
||||
typedef std::deque<turn_info> container_type;
|
||||
|
||||
typedef std::deque
|
||||
<
|
||||
typename geometry::ring_type<GeometryOut>::type
|
||||
> ring_container_type;
|
||||
|
||||
if (geometry::num_points(geometry1) == 0
|
||||
|| geometry::num_points(geometry2) == 0)
|
||||
{
|
||||
return return_if_one_input_is_empty
|
||||
<
|
||||
GeometryOut, Direction, ReverseOut
|
||||
>(geometry1, geometry2, out);
|
||||
}
|
||||
|
||||
container_type turn_points;
|
||||
|
||||
#ifdef BOOST_GEOMETRY_TIME_OVERLAY
|
||||
boost::timer timer;
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
|
||||
std::cout << "get turns" << std::endl;
|
||||
#endif
|
||||
detail::get_turns::no_interrupt_policy policy;
|
||||
geometry::get_turns
|
||||
<
|
||||
Reverse1, Reverse2,
|
||||
detail::overlay::calculate_distance_policy
|
||||
>(geometry1, geometry2, turn_points, policy);
|
||||
|
||||
#ifdef BOOST_GEOMETRY_TIME_OVERLAY
|
||||
std::cout << "get_turns: " << timer.elapsed() << std::endl;
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
|
||||
std::cout << "enrich" << std::endl;
|
||||
#endif
|
||||
typename Strategy::side_strategy_type side_strategy;
|
||||
geometry::enrich_intersection_points<Reverse1, Reverse2>(turn_points,
|
||||
Direction == overlay_union
|
||||
? geometry::detail::overlay::operation_union
|
||||
: geometry::detail::overlay::operation_intersection,
|
||||
geometry1, geometry2,
|
||||
side_strategy);
|
||||
|
||||
#ifdef BOOST_GEOMETRY_TIME_OVERLAY
|
||||
std::cout << "enrich_intersection_points: " << timer.elapsed() << std::endl;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
|
||||
std::cout << "traverse" << std::endl;
|
||||
#endif
|
||||
// Traverse through intersection/turn points and create rings of them.
|
||||
// Note that these rings are always in clockwise order, even in CCW polygons,
|
||||
// and are marked as "to be reversed" below
|
||||
ring_container_type rings;
|
||||
traverse<Reverse1, Reverse2, Geometry1, Geometry2>::apply
|
||||
(
|
||||
geometry1, geometry2,
|
||||
Direction == overlay_union
|
||||
? geometry::detail::overlay::operation_union
|
||||
: geometry::detail::overlay::operation_intersection,
|
||||
turn_points, rings
|
||||
);
|
||||
|
||||
#ifdef BOOST_GEOMETRY_TIME_OVERLAY
|
||||
std::cout << "traverse: " << timer.elapsed() << std::endl;
|
||||
#endif
|
||||
|
||||
|
||||
std::map<ring_identifier, int> map;
|
||||
map_turns(map, turn_points);
|
||||
|
||||
#ifdef BOOST_GEOMETRY_TIME_OVERLAY
|
||||
std::cout << "map_turns: " << timer.elapsed() << std::endl;
|
||||
#endif
|
||||
|
||||
typedef ring_properties<typename geometry::point_type<Geometry1>::type> properties;
|
||||
|
||||
std::map<ring_identifier, properties> selected;
|
||||
select_rings<Direction>(geometry1, geometry2, map, selected, ! turn_points.empty());
|
||||
|
||||
#ifdef BOOST_GEOMETRY_TIME_OVERLAY
|
||||
std::cout << "select_rings: " << timer.elapsed() << std::endl;
|
||||
#endif
|
||||
|
||||
|
||||
// Add rings created during traversal
|
||||
{
|
||||
ring_identifier id(2, 0, -1);
|
||||
for (typename boost::range_iterator<ring_container_type>::type
|
||||
it = boost::begin(rings);
|
||||
it != boost::end(rings);
|
||||
++it)
|
||||
{
|
||||
selected[id] = properties(*it, true);
|
||||
selected[id].reversed = ReverseOut;
|
||||
id.multi_index++;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOOST_GEOMETRY_TIME_OVERLAY
|
||||
std::cout << "add traversal rings: " << timer.elapsed() << std::endl;
|
||||
#endif
|
||||
|
||||
|
||||
assign_parents(geometry1, geometry2, rings, selected);
|
||||
|
||||
#ifdef BOOST_GEOMETRY_TIME_OVERLAY
|
||||
std::cout << "assign_parents: " << timer.elapsed() << std::endl;
|
||||
#endif
|
||||
|
||||
return add_rings<GeometryOut>(selected, geometry1, geometry2, rings, out);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Metafunction helper for intersection and union
|
||||
template <order_selector Selector, bool Reverse = false>
|
||||
struct do_reverse {};
|
||||
|
||||
template <>
|
||||
struct do_reverse<clockwise, false> : boost::false_type {};
|
||||
|
||||
template <>
|
||||
struct do_reverse<clockwise, true> : boost::true_type {};
|
||||
|
||||
template <>
|
||||
struct do_reverse<counterclockwise, false> : boost::true_type {};
|
||||
|
||||
template <>
|
||||
struct do_reverse<counterclockwise, true> : boost::false_type {};
|
||||
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_OVERLAY_HPP
|
||||
29
test/external/boost/geometry/algorithms/detail/overlay/overlay_type.hpp
vendored
Normal file
29
test/external/boost/geometry/algorithms/detail/overlay/overlay_type.hpp
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_OVERLAY_TYPE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_OVERLAY_TYPE_HPP
|
||||
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
enum overlay_type
|
||||
{
|
||||
overlay_union,
|
||||
overlay_intersection,
|
||||
overlay_difference,
|
||||
overlay_dissolve
|
||||
};
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_OVERLAY_TYPE_HPP
|
||||
78
test/external/boost/geometry/algorithms/detail/overlay/ring_properties.hpp
vendored
Normal file
78
test/external/boost/geometry/algorithms/detail/overlay/ring_properties.hpp
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_RING_PROPERTIES_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_RING_PROPERTIES_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/algorithms/area.hpp>
|
||||
#include <boost/geometry/algorithms/within.hpp>
|
||||
#include <boost/geometry/algorithms/detail/point_on_border.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
template <typename Point>
|
||||
struct ring_properties
|
||||
{
|
||||
typedef Point point_type;
|
||||
typedef typename default_area_result<Point>::type area_type;
|
||||
|
||||
// Filled by "select_rings"
|
||||
Point point;
|
||||
area_type area;
|
||||
|
||||
// Filled by "update_selection_map"
|
||||
int within_code;
|
||||
bool reversed;
|
||||
|
||||
// Filled/used by "assign_rings"
|
||||
bool discarded;
|
||||
ring_identifier parent;
|
||||
area_type parent_area;
|
||||
std::vector<ring_identifier> children;
|
||||
|
||||
inline ring_properties()
|
||||
: area(area_type())
|
||||
, within_code(-1)
|
||||
, reversed(false)
|
||||
, discarded(false)
|
||||
, parent_area(-1)
|
||||
{}
|
||||
|
||||
template <typename RingOrBox>
|
||||
inline ring_properties(RingOrBox const& ring_or_box, bool midpoint)
|
||||
: within_code(-1)
|
||||
, reversed(false)
|
||||
, discarded(false)
|
||||
, parent_area(-1)
|
||||
{
|
||||
this->area = geometry::area(ring_or_box);
|
||||
geometry::point_on_border(this->point, ring_or_box, midpoint);
|
||||
}
|
||||
|
||||
inline area_type get_area() const
|
||||
{
|
||||
return reversed ? -area : area;
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_RING_PROPERTIES_HPP
|
||||
91
test/external/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp
vendored
Normal file
91
test/external/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SEGMENT_IDENTIFIER_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SEGMENT_IDENTIFIER_HPP
|
||||
|
||||
|
||||
#if defined(BOOST_GEOMETRY_DEBUG_OVERLAY)
|
||||
# define BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER
|
||||
#endif
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
// Internal struct to uniquely identify a segment
|
||||
// on a linestring,ring
|
||||
// or polygon (needs ring_index)
|
||||
// or multi-geometry (needs multi_index)
|
||||
struct segment_identifier
|
||||
{
|
||||
inline segment_identifier()
|
||||
: source_index(-1)
|
||||
, multi_index(-1)
|
||||
, ring_index(-1)
|
||||
, segment_index(-1)
|
||||
{}
|
||||
|
||||
inline segment_identifier(int src, int mul, int rin, int seg)
|
||||
: source_index(src)
|
||||
, multi_index(mul)
|
||||
, ring_index(rin)
|
||||
, segment_index(seg)
|
||||
{}
|
||||
|
||||
inline bool operator<(segment_identifier const& other) const
|
||||
{
|
||||
return source_index != other.source_index ? source_index < other.source_index
|
||||
: multi_index !=other.multi_index ? multi_index < other.multi_index
|
||||
: ring_index != other.ring_index ? ring_index < other.ring_index
|
||||
: segment_index < other.segment_index
|
||||
;
|
||||
}
|
||||
|
||||
inline bool operator==(segment_identifier const& other) const
|
||||
{
|
||||
return source_index == other.source_index
|
||||
&& segment_index == other.segment_index
|
||||
&& ring_index == other.ring_index
|
||||
&& multi_index == other.multi_index
|
||||
;
|
||||
}
|
||||
|
||||
#if defined(BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER)
|
||||
friend std::ostream& operator<<(std::ostream &os, segment_identifier const& seg_id)
|
||||
{
|
||||
std::cout
|
||||
<< "s:" << seg_id.source_index
|
||||
<< ", v:" << seg_id.segment_index // ~vertex
|
||||
;
|
||||
if (seg_id.ring_index >= 0) std::cout << ", r:" << seg_id.ring_index;
|
||||
if (seg_id.multi_index >= 0) std::cout << ", m:" << seg_id.multi_index;
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
|
||||
int source_index;
|
||||
int multi_index;
|
||||
int ring_index;
|
||||
int segment_index;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SEGMENT_IDENTIFIER_HPP
|
||||
295
test/external/boost/geometry/algorithms/detail/overlay/select_rings.hpp
vendored
Normal file
295
test/external/boost/geometry/algorithms/detail/overlay/select_rings.hpp
vendored
Normal file
@@ -0,0 +1,295 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SELECT_RINGS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SELECT_RINGS_HPP
|
||||
|
||||
#include <map>
|
||||
|
||||
|
||||
#include <boost/geometry/algorithms/area.hpp>
|
||||
#include <boost/geometry/algorithms/within.hpp>
|
||||
#include <boost/geometry/algorithms/detail/point_on_border.hpp>
|
||||
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/ring_properties.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template <typename Tag, typename Geometry>
|
||||
struct select_rings
|
||||
{};
|
||||
|
||||
template <typename Box>
|
||||
struct select_rings<box_tag, Box>
|
||||
{
|
||||
template <typename Geometry, typename Map>
|
||||
static inline void apply(Box const& box, Geometry const& geometry,
|
||||
ring_identifier const& id, Map& map, bool midpoint)
|
||||
{
|
||||
map[id] = typename Map::mapped_type(box, midpoint);
|
||||
}
|
||||
|
||||
template <typename Map>
|
||||
static inline void apply(Box const& box,
|
||||
ring_identifier const& id, Map& map, bool midpoint)
|
||||
{
|
||||
map[id] = typename Map::mapped_type(box, midpoint);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Ring>
|
||||
struct select_rings<ring_tag, Ring>
|
||||
{
|
||||
template <typename Geometry, typename Map>
|
||||
static inline void apply(Ring const& ring, Geometry const& geometry,
|
||||
ring_identifier const& id, Map& map, bool midpoint)
|
||||
{
|
||||
if (boost::size(ring) > 0)
|
||||
{
|
||||
map[id] = typename Map::mapped_type(ring, midpoint);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Map>
|
||||
static inline void apply(Ring const& ring,
|
||||
ring_identifier const& id, Map& map, bool midpoint)
|
||||
{
|
||||
if (boost::size(ring) > 0)
|
||||
{
|
||||
map[id] = typename Map::mapped_type(ring, midpoint);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Polygon>
|
||||
struct select_rings<polygon_tag, Polygon>
|
||||
{
|
||||
template <typename Geometry, typename Map>
|
||||
static inline void apply(Polygon const& polygon, Geometry const& geometry,
|
||||
ring_identifier id, Map& map, bool midpoint)
|
||||
{
|
||||
typedef typename geometry::ring_type<Polygon>::type ring_type;
|
||||
typedef select_rings<ring_tag, ring_type> per_ring;
|
||||
|
||||
per_ring::apply(exterior_ring(polygon), geometry, id, map, midpoint);
|
||||
|
||||
typename interior_return_type<Polygon const>::type rings
|
||||
= interior_rings(polygon);
|
||||
for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
|
||||
{
|
||||
id.ring_index++;
|
||||
per_ring::apply(*it, geometry, id, map, midpoint);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Map>
|
||||
static inline void apply(Polygon const& polygon,
|
||||
ring_identifier id, Map& map, bool midpoint)
|
||||
{
|
||||
typedef typename geometry::ring_type<Polygon>::type ring_type;
|
||||
typedef select_rings<ring_tag, ring_type> per_ring;
|
||||
|
||||
per_ring::apply(exterior_ring(polygon), id, map, midpoint);
|
||||
|
||||
typename interior_return_type<Polygon const>::type rings
|
||||
= interior_rings(polygon);
|
||||
for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
|
||||
{
|
||||
id.ring_index++;
|
||||
per_ring::apply(*it, id, map, midpoint);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
template<overlay_type OverlayType>
|
||||
struct decide
|
||||
{};
|
||||
|
||||
template<>
|
||||
struct decide<overlay_union>
|
||||
{
|
||||
template <typename Code>
|
||||
static bool include(ring_identifier const& id, Code const& code)
|
||||
{
|
||||
return code.within_code * -1 == 1;
|
||||
}
|
||||
|
||||
template <typename Code>
|
||||
static bool reversed(ring_identifier const& , Code const& )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct decide<overlay_difference>
|
||||
{
|
||||
template <typename Code>
|
||||
static bool include(ring_identifier const& id, Code const& code)
|
||||
{
|
||||
bool is_first = id.source_index == 0;
|
||||
return code.within_code * -1 * (is_first ? 1 : -1) == 1;
|
||||
}
|
||||
|
||||
template <typename Code>
|
||||
static bool reversed(ring_identifier const& id, Code const& code)
|
||||
{
|
||||
return include(id, code) && id.source_index == 1;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct decide<overlay_intersection>
|
||||
{
|
||||
template <typename Code>
|
||||
static bool include(ring_identifier const& id, Code const& code)
|
||||
{
|
||||
return code.within_code * 1 == 1;
|
||||
}
|
||||
|
||||
template <typename Code>
|
||||
static bool reversed(ring_identifier const& , Code const& )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
overlay_type OverlayType,
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename IntersectionMap, typename SelectionMap
|
||||
>
|
||||
inline void update_selection_map(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
IntersectionMap const& intersection_map,
|
||||
SelectionMap const& map_with_all, SelectionMap& selection_map)
|
||||
{
|
||||
selection_map.clear();
|
||||
|
||||
for (typename SelectionMap::const_iterator it = boost::begin(map_with_all);
|
||||
it != boost::end(map_with_all);
|
||||
++it)
|
||||
{
|
||||
/*
|
||||
int union_code = it->second.within_code * -1;
|
||||
bool is_first = it->first.source_index == 0;
|
||||
std::cout << it->first << " " << it->second.area
|
||||
<< ": " << it->second.within_code
|
||||
<< " union: " << union_code
|
||||
<< " intersection: " << (it->second.within_code * 1)
|
||||
<< " G1-G2: " << (union_code * (is_first ? 1 : -1))
|
||||
<< " G2-G1: " << (union_code * (is_first ? -1 : 1))
|
||||
<< " -> " << (decide<OverlayType>::include(it->first, it->second) ? "INC" : "")
|
||||
<< decide<OverlayType>::reverse(it->first, it->second)
|
||||
<< std::endl;
|
||||
*/
|
||||
|
||||
bool found = intersection_map.find(it->first) != intersection_map.end();
|
||||
if (! found)
|
||||
{
|
||||
ring_identifier const id = it->first;
|
||||
typename SelectionMap::mapped_type properties = it->second; // Copy by value
|
||||
|
||||
// Calculate the "within code" (previously this was done earlier but is
|
||||
// must efficienter here - it can be even more efficient doing it all at once,
|
||||
// using partition, TODO)
|
||||
// So though this is less elegant than before, it avoids many unused point-in-poly calculations
|
||||
switch(id.source_index)
|
||||
{
|
||||
case 0 :
|
||||
properties.within_code
|
||||
= geometry::within(properties.point, geometry2) ? 1 : -1;
|
||||
break;
|
||||
case 1 :
|
||||
properties.within_code
|
||||
= geometry::within(properties.point, geometry1) ? 1 : -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (decide<OverlayType>::include(id, properties))
|
||||
{
|
||||
properties.reversed = decide<OverlayType>::reversed(id, properties);
|
||||
selection_map[id] = properties;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief The function select_rings select rings based on the overlay-type (union,intersection)
|
||||
*/
|
||||
template
|
||||
<
|
||||
overlay_type OverlayType,
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename IntersectionMap, typename SelectionMap
|
||||
>
|
||||
inline void select_rings(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
IntersectionMap const& intersection_map,
|
||||
SelectionMap& selection_map, bool midpoint)
|
||||
{
|
||||
typedef typename geometry::tag<Geometry1>::type tag1;
|
||||
typedef typename geometry::tag<Geometry2>::type tag2;
|
||||
|
||||
SelectionMap map_with_all;
|
||||
dispatch::select_rings<tag1, Geometry1>::apply(geometry1, geometry2,
|
||||
ring_identifier(0, -1, -1), map_with_all, midpoint);
|
||||
dispatch::select_rings<tag2, Geometry2>::apply(geometry2, geometry1,
|
||||
ring_identifier(1, -1, -1), map_with_all, midpoint);
|
||||
|
||||
update_selection_map<OverlayType>(geometry1, geometry2, intersection_map,
|
||||
map_with_all, selection_map);
|
||||
}
|
||||
|
||||
template
|
||||
<
|
||||
overlay_type OverlayType,
|
||||
typename Geometry,
|
||||
typename IntersectionMap, typename SelectionMap
|
||||
>
|
||||
inline void select_rings(Geometry const& geometry,
|
||||
IntersectionMap const& intersection_map,
|
||||
SelectionMap& selection_map, bool midpoint)
|
||||
{
|
||||
typedef typename geometry::tag<Geometry>::type tag;
|
||||
|
||||
SelectionMap map_with_all;
|
||||
dispatch::select_rings<tag, Geometry>::apply(geometry,
|
||||
ring_identifier(0, -1, -1), map_with_all, midpoint);
|
||||
|
||||
update_selection_map<OverlayType>(geometry, geometry, intersection_map,
|
||||
map_with_all, selection_map);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SELECT_RINGS_HPP
|
||||
291
test/external/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp
vendored
Normal file
291
test/external/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp
vendored
Normal file
@@ -0,0 +1,291 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SELF_TURN_POINTS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SELF_TURN_POINTS_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/disjoint.hpp>
|
||||
#include <boost/geometry/algorithms/detail/partition.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/box.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace self_get_turn_points
|
||||
{
|
||||
|
||||
class self_ip_exception : public geometry::exception {};
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Turns,
|
||||
typename TurnPolicy,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
struct self_section_visitor
|
||||
{
|
||||
Geometry const& m_geometry;
|
||||
Turns& m_turns;
|
||||
InterruptPolicy& m_interrupt_policy;
|
||||
|
||||
inline self_section_visitor(Geometry const& g,
|
||||
Turns& turns, InterruptPolicy& ip)
|
||||
: m_geometry(g)
|
||||
, m_turns(turns)
|
||||
, m_interrupt_policy(ip)
|
||||
{}
|
||||
|
||||
template <typename Section>
|
||||
inline bool apply(Section const& sec1, Section const& sec2)
|
||||
{
|
||||
if (! detail::disjoint::disjoint_box_box(sec1.bounding_box, sec2.bounding_box)
|
||||
&& ! sec1.duplicate
|
||||
&& ! sec2.duplicate)
|
||||
{
|
||||
detail::get_turns::get_turns_in_sections
|
||||
<
|
||||
Geometry, Geometry,
|
||||
false, false,
|
||||
Section, Section,
|
||||
Turns, TurnPolicy,
|
||||
InterruptPolicy
|
||||
>::apply(
|
||||
0, m_geometry, sec1,
|
||||
0, m_geometry, sec2,
|
||||
m_turns, m_interrupt_policy);
|
||||
}
|
||||
if (m_interrupt_policy.has_intersections)
|
||||
{
|
||||
// TODO: we should give partition an interrupt policy.
|
||||
// Now we throw, and catch below, to stop the partition loop.
|
||||
throw self_ip_exception();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Turns,
|
||||
typename TurnPolicy,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
struct get_turns
|
||||
{
|
||||
static inline bool apply(
|
||||
Geometry const& geometry,
|
||||
Turns& turns,
|
||||
InterruptPolicy& interrupt_policy)
|
||||
{
|
||||
typedef model::box
|
||||
<
|
||||
typename geometry::point_type<Geometry>::type
|
||||
> box_type;
|
||||
typedef typename geometry::sections
|
||||
<
|
||||
box_type, 1
|
||||
> sections_type;
|
||||
|
||||
sections_type sec;
|
||||
geometry::sectionalize<false>(geometry, sec);
|
||||
|
||||
self_section_visitor
|
||||
<
|
||||
Geometry,
|
||||
Turns, TurnPolicy, InterruptPolicy
|
||||
> visitor(geometry, turns, interrupt_policy);
|
||||
|
||||
try
|
||||
{
|
||||
geometry::partition
|
||||
<
|
||||
box_type,
|
||||
detail::get_turns::get_section_box,
|
||||
detail::get_turns::ovelaps_section_box
|
||||
>::apply(sec, visitor);
|
||||
}
|
||||
catch(self_ip_exception const& )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::self_get_turn_points
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryTag,
|
||||
typename Geometry,
|
||||
typename Turns,
|
||||
typename TurnPolicy,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
struct self_get_turn_points
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Ring,
|
||||
typename Turns,
|
||||
typename TurnPolicy,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
struct self_get_turn_points
|
||||
<
|
||||
ring_tag, Ring,
|
||||
Turns,
|
||||
TurnPolicy,
|
||||
InterruptPolicy
|
||||
>
|
||||
: detail::self_get_turn_points::get_turns
|
||||
<
|
||||
Ring,
|
||||
Turns,
|
||||
TurnPolicy,
|
||||
InterruptPolicy
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Box,
|
||||
typename Turns,
|
||||
typename TurnPolicy,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
struct self_get_turn_points
|
||||
<
|
||||
box_tag, Box,
|
||||
Turns,
|
||||
TurnPolicy,
|
||||
InterruptPolicy
|
||||
>
|
||||
{
|
||||
static inline bool apply(
|
||||
Box const& ,
|
||||
Turns& ,
|
||||
InterruptPolicy& )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Polygon,
|
||||
typename Turns,
|
||||
typename TurnPolicy,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
struct self_get_turn_points
|
||||
<
|
||||
polygon_tag, Polygon,
|
||||
Turns,
|
||||
TurnPolicy,
|
||||
InterruptPolicy
|
||||
>
|
||||
: detail::self_get_turn_points::get_turns
|
||||
<
|
||||
Polygon,
|
||||
Turns,
|
||||
TurnPolicy,
|
||||
InterruptPolicy
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief Calculate self intersections of a geometry
|
||||
\ingroup overlay
|
||||
\tparam Geometry geometry type
|
||||
\tparam Turns type of intersection container
|
||||
(e.g. vector of "intersection/turn point"'s)
|
||||
\param geometry geometry
|
||||
\param turns container which will contain intersection points
|
||||
\param interrupt_policy policy determining if process is stopped
|
||||
when intersection is found
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename AssignPolicy,
|
||||
typename Geometry,
|
||||
typename Turns,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
inline void self_turns(Geometry const& geometry,
|
||||
Turns& turns, InterruptPolicy& interrupt_policy)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
typedef typename strategy_intersection
|
||||
<
|
||||
typename cs_tag<Geometry>::type,
|
||||
Geometry,
|
||||
Geometry,
|
||||
typename boost::range_value<Turns>::type
|
||||
>::segment_intersection_strategy_type strategy_type;
|
||||
|
||||
typedef detail::overlay::get_turn_info
|
||||
<
|
||||
typename point_type<Geometry>::type,
|
||||
typename point_type<Geometry>::type,
|
||||
typename boost::range_value<Turns>::type,
|
||||
detail::overlay::assign_null_policy
|
||||
> TurnPolicy;
|
||||
|
||||
dispatch::self_get_turn_points
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
Turns,
|
||||
TurnPolicy,
|
||||
InterruptPolicy
|
||||
>::apply(geometry, turns, interrupt_policy);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SELF_TURN_POINTS_HPP
|
||||
75
test/external/boost/geometry/algorithms/detail/overlay/stream_info.hpp
vendored
Normal file
75
test/external/boost/geometry/algorithms/detail/overlay/stream_info.hpp
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_STREAM_INFO_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_STREAM_INFO_HPP
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/array.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
|
||||
static inline std::string dir(int d)
|
||||
{
|
||||
return d == 0 ? "-" : (d == 1 ? "L" : d == -1 ? "R" : "#");
|
||||
}
|
||||
static inline std::string how_str(int h)
|
||||
{
|
||||
return h == 0 ? "-" : (h == 1 ? "A" : "D");
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
std::ostream& operator<<(std::ostream &os, turn_info<P> const& info)
|
||||
{
|
||||
typename geometry::coordinate_type<P>::type d = info.distance;
|
||||
os << "\t"
|
||||
<< " src " << info.seg_id.source_index
|
||||
<< " seg " << info.seg_id.segment_index
|
||||
<< " (// " << info.other_id.source_index
|
||||
<< "." << info.other_id.segment_index << ")"
|
||||
<< " how " << info.how
|
||||
<< "[" << how_str(info.arrival)
|
||||
<< " " << dir(info.direction)
|
||||
<< (info.opposite ? " o" : "")
|
||||
<< "]"
|
||||
<< " sd "
|
||||
<< dir(info.sides.get<0,0>())
|
||||
<< dir(info.sides.get<0,1>())
|
||||
<< dir(info.sides.get<1,0>())
|
||||
<< dir(info.sides.get<1,1>())
|
||||
<< " nxt seg " << info.travels_to_vertex_index
|
||||
<< " , ip " << info.travels_to_ip_index
|
||||
<< " , or " << info.next_ip_index
|
||||
<< " dst " << double(d)
|
||||
<< info.visit_state;
|
||||
if (info.flagged)
|
||||
{
|
||||
os << " FLAGGED";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif //DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_STREAM_INFO_HPP
|
||||
47
test/external/boost/geometry/algorithms/detail/overlay/traversal_info.hpp
vendored
Normal file
47
test/external/boost/geometry/algorithms/detail/overlay/traversal_info.hpp
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TRAVERSAL_INFO_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TRAVERSAL_INFO_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/enrichment_info.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/visit_info.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
|
||||
template <typename P>
|
||||
struct traversal_turn_operation : public turn_operation
|
||||
{
|
||||
enrichment_info<P> enriched;
|
||||
visit_info visited;
|
||||
};
|
||||
|
||||
template <typename P>
|
||||
struct traversal_turn_info : public turn_info<P, traversal_turn_operation<P> >
|
||||
{};
|
||||
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif //DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TRAVERSAL_INFO_HPP
|
||||
394
test/external/boost/geometry/algorithms/detail/overlay/traverse.hpp
vendored
Normal file
394
test/external/boost/geometry/algorithms/detail/overlay/traverse.hpp
vendored
Normal file
@@ -0,0 +1,394 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TRAVERSE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TRAVERSE_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
|
||||
#if defined(BOOST_GEOMETRY_DEBUG_INTERSECTION) || defined(BOOST_GEOMETRY_OVERLAY_REPORT_WKT)
|
||||
# include <string>
|
||||
# include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
|
||||
# include <boost/geometry/domains/gis/io/wkt/wkt.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
template <typename Turn, typename Operation>
|
||||
inline void debug_traverse(Turn const& turn, Operation op,
|
||||
std::string const& header)
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_TRAVERSE
|
||||
std::cout << header
|
||||
<< " at " << op.seg_id
|
||||
<< " op: " << operation_char(op.operation)
|
||||
<< " vis: " << visited_char(op.visited)
|
||||
<< " of: " << operation_char(turn.operations[0].operation)
|
||||
<< operation_char(turn.operations[1].operation)
|
||||
<< std::endl;
|
||||
|
||||
if (boost::contains(header, "Finished"))
|
||||
{
|
||||
std::cout << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <typename Info, typename Turn>
|
||||
inline void set_visited_for_continue(Info& info, Turn const& turn)
|
||||
{
|
||||
// On "continue", set "visited" for ALL directions
|
||||
if (turn.operation == detail::overlay::operation_continue)
|
||||
{
|
||||
for (typename boost::range_iterator
|
||||
<
|
||||
typename Info::container_type
|
||||
>::type it = boost::begin(info.operations);
|
||||
it != boost::end(info.operations);
|
||||
++it)
|
||||
{
|
||||
if (it->visited.none())
|
||||
{
|
||||
it->visited.set_visited();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
bool Reverse1, bool Reverse2,
|
||||
typename GeometryOut,
|
||||
typename G1,
|
||||
typename G2,
|
||||
typename Turns,
|
||||
typename IntersectionInfo
|
||||
>
|
||||
inline bool assign_next_ip(G1 const& g1, G2 const& g2,
|
||||
Turns& turns,
|
||||
typename boost::range_iterator<Turns>::type& ip,
|
||||
GeometryOut& current_output,
|
||||
IntersectionInfo& info,
|
||||
segment_identifier& seg_id)
|
||||
{
|
||||
info.visited.set_visited();
|
||||
set_visited_for_continue(*ip, info);
|
||||
|
||||
// If there is no next IP on this segment
|
||||
if (info.enriched.next_ip_index < 0)
|
||||
{
|
||||
if (info.enriched.travels_to_vertex_index < 0
|
||||
|| info.enriched.travels_to_ip_index < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOST_ASSERT(info.enriched.travels_to_vertex_index >= 0);
|
||||
BOOST_ASSERT(info.enriched.travels_to_ip_index >= 0);
|
||||
|
||||
if (info.seg_id.source_index == 0)
|
||||
{
|
||||
geometry::copy_segments<Reverse1>(g1, info.seg_id,
|
||||
info.enriched.travels_to_vertex_index,
|
||||
current_output);
|
||||
}
|
||||
else
|
||||
{
|
||||
geometry::copy_segments<Reverse2>(g2, info.seg_id,
|
||||
info.enriched.travels_to_vertex_index,
|
||||
current_output);
|
||||
}
|
||||
seg_id = info.seg_id;
|
||||
ip = boost::begin(turns) + info.enriched.travels_to_ip_index;
|
||||
}
|
||||
else
|
||||
{
|
||||
ip = boost::begin(turns) + info.enriched.next_ip_index;
|
||||
seg_id = info.seg_id;
|
||||
}
|
||||
|
||||
detail::overlay::append_no_duplicates(current_output, ip->point);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline bool select_source(operation_type operation, int source1, int source2)
|
||||
{
|
||||
return (operation == operation_intersection && source1 != source2)
|
||||
|| (operation == operation_union && source1 == source2)
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Turn,
|
||||
typename Iterator
|
||||
>
|
||||
inline bool select_next_ip(operation_type operation,
|
||||
Turn& turn,
|
||||
segment_identifier const& seg_id,
|
||||
Iterator& selected)
|
||||
{
|
||||
if (turn.discarded)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool has_tp = false;
|
||||
selected = boost::end(turn.operations);
|
||||
for (Iterator it = boost::begin(turn.operations);
|
||||
it != boost::end(turn.operations);
|
||||
++it)
|
||||
{
|
||||
if (it->visited.started())
|
||||
{
|
||||
selected = it;
|
||||
//std::cout << " RETURN";
|
||||
return true;
|
||||
}
|
||||
|
||||
// In some cases there are two alternatives.
|
||||
// For "ii", take the other one (alternate)
|
||||
// UNLESS the other one is already visited
|
||||
// For "uu", take the same one (see above);
|
||||
// For "cc", take either one, but if there is a starting one,
|
||||
// take that one.
|
||||
if ( (it->operation == operation_continue
|
||||
&& (! has_tp || it->visited.started()
|
||||
)
|
||||
)
|
||||
|| (it->operation == operation
|
||||
&& ! it->visited.finished()
|
||||
&& (! has_tp
|
||||
|| select_source(operation,
|
||||
it->seg_id.source_index, seg_id.source_index)
|
||||
)
|
||||
)
|
||||
)
|
||||
{
|
||||
selected = it;
|
||||
debug_traverse(turn, *it, " Candidate");
|
||||
has_tp = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_tp)
|
||||
{
|
||||
debug_traverse(turn, *selected, " Accepted");
|
||||
}
|
||||
|
||||
|
||||
return has_tp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Traverses through intersection points / geometries
|
||||
\ingroup overlay
|
||||
*/
|
||||
template
|
||||
<
|
||||
bool Reverse1, bool Reverse2,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Backtrack = backtrack_check_self_intersections<Geometry1, Geometry2>
|
||||
>
|
||||
class traverse
|
||||
{
|
||||
public :
|
||||
template <typename Turns, typename Rings>
|
||||
static inline void apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
detail::overlay::operation_type operation,
|
||||
Turns& turns, Rings& rings)
|
||||
{
|
||||
typedef typename boost::range_iterator<Turns>::type turn_iterator;
|
||||
typedef typename boost::range_value<Turns>::type turn_type;
|
||||
typedef typename boost::range_iterator
|
||||
<
|
||||
typename turn_type::container_type
|
||||
>::type turn_operation_iterator_type;
|
||||
|
||||
std::size_t size_at_start = boost::size(rings);
|
||||
|
||||
typename Backtrack::state_type state;
|
||||
do
|
||||
{
|
||||
state.reset();
|
||||
|
||||
// Iterate through all unvisited points
|
||||
for (turn_iterator it = boost::begin(turns);
|
||||
state.good() && it != boost::end(turns);
|
||||
++it)
|
||||
{
|
||||
// Skip discarded ones
|
||||
if (! (it->is_discarded() || it->blocked()))
|
||||
{
|
||||
for (turn_operation_iterator_type iit = boost::begin(it->operations);
|
||||
state.good() && iit != boost::end(it->operations);
|
||||
++iit)
|
||||
{
|
||||
if (iit->visited.none()
|
||||
&& ! iit->visited.rejected()
|
||||
&& (iit->operation == operation
|
||||
|| iit->operation == detail::overlay::operation_continue)
|
||||
)
|
||||
{
|
||||
set_visited_for_continue(*it, *iit);
|
||||
|
||||
typename boost::range_value<Rings>::type current_output;
|
||||
detail::overlay::append_no_duplicates(current_output,
|
||||
it->point, true);
|
||||
|
||||
turn_iterator current = it;
|
||||
turn_operation_iterator_type current_iit = iit;
|
||||
segment_identifier current_seg_id;
|
||||
|
||||
if (! detail::overlay::assign_next_ip<Reverse1, Reverse2>(
|
||||
geometry1, geometry2,
|
||||
turns,
|
||||
current, current_output,
|
||||
*iit, current_seg_id))
|
||||
{
|
||||
Backtrack::apply(
|
||||
size_at_start,
|
||||
rings, current_output, turns, *current_iit,
|
||||
"No next IP",
|
||||
geometry1, geometry2, state);
|
||||
}
|
||||
|
||||
if (! detail::overlay::select_next_ip(
|
||||
operation,
|
||||
*current,
|
||||
current_seg_id,
|
||||
current_iit))
|
||||
{
|
||||
Backtrack::apply(
|
||||
size_at_start,
|
||||
rings, current_output, turns, *iit,
|
||||
"Dead end at start",
|
||||
geometry1, geometry2, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
iit->visited.set_started();
|
||||
detail::overlay::debug_traverse(*it, *iit, "-> Started");
|
||||
detail::overlay::debug_traverse(*current, *current_iit, "Selected ");
|
||||
|
||||
|
||||
unsigned int i = 0;
|
||||
|
||||
while (current_iit != iit && state.good())
|
||||
{
|
||||
if (current_iit->visited.visited())
|
||||
{
|
||||
// It visits a visited node again, without passing the start node.
|
||||
// This makes it suspicious for endless loops
|
||||
Backtrack::apply(
|
||||
size_at_start,
|
||||
rings, current_output, turns, *iit,
|
||||
"Visit again",
|
||||
geometry1, geometry2, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
// We assume clockwise polygons only, non self-intersecting, closed.
|
||||
// However, the input might be different, and checking validity
|
||||
// is up to the library user.
|
||||
|
||||
// Therefore we make here some sanity checks. If the input
|
||||
// violates the assumptions, the output polygon will not be correct
|
||||
// but the routine will stop and output the current polygon, and
|
||||
// will continue with the next one.
|
||||
|
||||
// Below three reasons to stop.
|
||||
detail::overlay::assign_next_ip<Reverse1, Reverse2>(
|
||||
geometry1, geometry2,
|
||||
turns, current, current_output,
|
||||
*current_iit, current_seg_id);
|
||||
|
||||
if (! detail::overlay::select_next_ip(
|
||||
operation,
|
||||
*current,
|
||||
current_seg_id,
|
||||
current_iit))
|
||||
{
|
||||
// Should not occur in valid (non-self-intersecting) polygons
|
||||
// Should not occur in self-intersecting polygons without spikes
|
||||
// Might occur in polygons with spikes
|
||||
Backtrack::apply(
|
||||
size_at_start,
|
||||
rings, current_output, turns, *iit,
|
||||
"Dead end",
|
||||
geometry1, geometry2, state);
|
||||
}
|
||||
detail::overlay::debug_traverse(*current, *current_iit, "Selected ");
|
||||
|
||||
if (i++ > 2 + 2 * turns.size())
|
||||
{
|
||||
// Sanity check: there may be never more loops
|
||||
// than turn points.
|
||||
// Turn points marked as "ii" can be visited twice.
|
||||
Backtrack::apply(
|
||||
size_at_start,
|
||||
rings, current_output, turns, *iit,
|
||||
"Endless loop",
|
||||
geometry1, geometry2, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (state.good())
|
||||
{
|
||||
iit->visited.set_finished();
|
||||
detail::overlay::debug_traverse(*current, *iit, "->Finished");
|
||||
rings.push_back(current_output);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (! state.good());
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TRAVERSE_HPP
|
||||
142
test/external/boost/geometry/algorithms/detail/overlay/turn_info.hpp
vendored
Normal file
142
test/external/boost/geometry/algorithms/detail/overlay/turn_info.hpp
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TURN_INFO_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TURN_INFO_HPP
|
||||
|
||||
|
||||
#include <boost/array.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
|
||||
enum operation_type
|
||||
{
|
||||
operation_none,
|
||||
operation_union,
|
||||
operation_intersection,
|
||||
operation_blocked,
|
||||
operation_continue
|
||||
};
|
||||
|
||||
|
||||
enum method_type
|
||||
{
|
||||
method_none,
|
||||
method_disjoint,
|
||||
method_crosses,
|
||||
method_touch,
|
||||
method_touch_interior,
|
||||
method_collinear,
|
||||
method_equal,
|
||||
method_error
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
\brief Turn operation: operation
|
||||
\details Information necessary for traversal phase (a phase
|
||||
of the overlay process). The information is gathered during the
|
||||
get_turns (segment intersection) phase.
|
||||
The class is to be included in the turn_info class, either direct
|
||||
or a derived or similar class with more (e.g. enrichment) information.
|
||||
*/
|
||||
struct turn_operation
|
||||
{
|
||||
operation_type operation;
|
||||
segment_identifier seg_id;
|
||||
segment_identifier other_id;
|
||||
|
||||
inline turn_operation()
|
||||
: operation(operation_none)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
\brief Turn information: intersection point, method, and turn information
|
||||
\details Information necessary for traversal phase (a phase
|
||||
of the overlay process). The information is gathered during the
|
||||
get_turns (segment intersection) phase.
|
||||
\tparam Point point type of intersection point
|
||||
\tparam Operation gives classes opportunity to add additional info
|
||||
\tparam Container gives classes opportunity to define how operations are stored
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename Operation = turn_operation,
|
||||
typename Container = boost::array<Operation, 2>
|
||||
>
|
||||
struct turn_info
|
||||
{
|
||||
typedef Point point_type;
|
||||
typedef Operation turn_operation_type;
|
||||
typedef Container container_type;
|
||||
|
||||
Point point;
|
||||
method_type method;
|
||||
bool discarded;
|
||||
|
||||
|
||||
Container operations;
|
||||
|
||||
inline turn_info()
|
||||
: method(method_none)
|
||||
, discarded(false)
|
||||
{}
|
||||
|
||||
inline bool both(operation_type type) const
|
||||
{
|
||||
return has12(type, type);
|
||||
}
|
||||
|
||||
inline bool combination(operation_type type1, operation_type type2) const
|
||||
{
|
||||
return has12(type1, type2) || has12(type2, type1);
|
||||
}
|
||||
|
||||
|
||||
inline bool is_discarded() const { return discarded; }
|
||||
inline bool blocked() const
|
||||
{
|
||||
return both(operation_blocked);
|
||||
}
|
||||
inline bool any_blocked() const
|
||||
{
|
||||
return this->operations[0].operation == operation_blocked
|
||||
|| this->operations[1].operation == operation_blocked;
|
||||
}
|
||||
|
||||
|
||||
private :
|
||||
inline bool has12(operation_type type1, operation_type type2) const
|
||||
{
|
||||
return this->operations[0].operation == type1
|
||||
&& this->operations[1].operation == type2
|
||||
;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif //DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TURN_INFO_HPP
|
||||
136
test/external/boost/geometry/algorithms/detail/overlay/visit_info.hpp
vendored
Normal file
136
test/external/boost/geometry/algorithms/detail/overlay/visit_info.hpp
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_VISIT_INFO_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_VISIT_INFO_HPP
|
||||
|
||||
|
||||
#ifdef BOOST_GEOMETRY_USE_MSM
|
||||
# include <boost/geometry/algorithms/detail/overlay/msm_state.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
|
||||
#if ! defined(BOOST_GEOMETRY_USE_MSM)
|
||||
|
||||
class visit_info
|
||||
{
|
||||
private :
|
||||
static const int NONE = 0;
|
||||
static const int STARTED = 1;
|
||||
static const int VISITED = 2;
|
||||
static const int FINISHED = 3;
|
||||
static const int REJECTED = 4;
|
||||
|
||||
int m_visit_code;
|
||||
bool m_rejected;
|
||||
|
||||
public:
|
||||
inline visit_info()
|
||||
: m_visit_code(0)
|
||||
, m_rejected(false)
|
||||
{}
|
||||
|
||||
inline void set_visited() { m_visit_code = VISITED; }
|
||||
inline void set_started() { m_visit_code = STARTED; }
|
||||
inline void set_finished() { m_visit_code = FINISHED; }
|
||||
inline void set_rejected()
|
||||
{
|
||||
m_visit_code = REJECTED;
|
||||
m_rejected = true;
|
||||
}
|
||||
|
||||
inline bool none() const { return m_visit_code == NONE; }
|
||||
inline bool visited() const { return m_visit_code == VISITED; }
|
||||
inline bool started() const { return m_visit_code == STARTED; }
|
||||
inline bool finished() const { return m_visit_code == FINISHED; }
|
||||
inline bool rejected() const { return m_rejected; }
|
||||
|
||||
inline void clear()
|
||||
{
|
||||
if (! rejected())
|
||||
{
|
||||
m_visit_code = NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
|
||||
friend std::ostream& operator<<(std::ostream &os, visit_info const& v)
|
||||
{
|
||||
if (v.m_visit_code != 0)
|
||||
{
|
||||
os << " VIS: " << int(v.m_visit_code);
|
||||
}
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
#else
|
||||
|
||||
|
||||
class visit_info
|
||||
{
|
||||
|
||||
private :
|
||||
|
||||
#ifndef USE_MSM_MINI
|
||||
mutable
|
||||
#endif
|
||||
traverse_state state;
|
||||
|
||||
public :
|
||||
inline visit_info()
|
||||
{
|
||||
state.start();
|
||||
}
|
||||
|
||||
inline void set_none() { state.process_event(none()); } // Not Yet Implemented!
|
||||
inline void set_visited() { state.process_event(visit()); }
|
||||
inline void set_started() { state.process_event(starting()); }
|
||||
inline void set_finished() { state.process_event(finish()); }
|
||||
|
||||
#ifdef USE_MSM_MINI
|
||||
inline bool none() const { return state.flag_none(); }
|
||||
inline bool visited() const { return state.flag_visited(); }
|
||||
inline bool started() const { return state.flag_started(); }
|
||||
#else
|
||||
inline bool none() const { return state.is_flag_active<is_init>(); }
|
||||
inline bool visited() const { return state.is_flag_active<is_visited>(); }
|
||||
inline bool started() const { return state.is_flag_active<is_started>(); }
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
|
||||
friend std::ostream& operator<<(std::ostream &os, visit_info const& v)
|
||||
{
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif //DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_VISIT_INFO_HPP
|
||||
389
test/external/boost/geometry/algorithms/detail/partition.hpp
vendored
Normal file
389
test/external/boost/geometry/algorithms/detail/partition.hpp
vendored
Normal file
@@ -0,0 +1,389 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_PARTITION_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_PARTITION_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
#include <boost/range/algorithm/copy.hpp>
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
namespace detail { namespace partition
|
||||
{
|
||||
|
||||
typedef std::vector<std::size_t> index_vector_type;
|
||||
|
||||
template <int Dimension, typename Box>
|
||||
inline void divide_box(Box const& box, Box& lower_box, Box& upper_box)
|
||||
{
|
||||
typedef typename coordinate_type<Box>::type ctype;
|
||||
|
||||
// Divide input box into two parts, e.g. left/right
|
||||
ctype two = 2;
|
||||
ctype mid = (geometry::get<min_corner, Dimension>(box)
|
||||
+ geometry::get<max_corner, Dimension>(box)) / two;
|
||||
|
||||
lower_box = box;
|
||||
upper_box = box;
|
||||
geometry::set<max_corner, Dimension>(lower_box, mid);
|
||||
geometry::set<min_corner, Dimension>(upper_box, mid);
|
||||
}
|
||||
|
||||
// Divide collection into three subsets: lower, upper and oversized (not-fitting)
|
||||
// (lower == left or bottom, upper == right or top)
|
||||
template <typename OverlapsPolicy, typename InputCollection, typename Box>
|
||||
static inline void divide_into_subsets(Box const& lower_box, Box const& upper_box,
|
||||
InputCollection const& collection,
|
||||
index_vector_type const& input,
|
||||
index_vector_type& lower,
|
||||
index_vector_type& upper,
|
||||
index_vector_type& exceeding)
|
||||
{
|
||||
typedef boost::range_iterator<index_vector_type const>::type index_iterator_type;
|
||||
|
||||
for(index_iterator_type it = boost::begin(input);
|
||||
it != boost::end(input);
|
||||
++it)
|
||||
{
|
||||
bool const lower_overlapping = OverlapsPolicy::apply(lower_box, collection[*it]);
|
||||
bool const upper_overlapping = OverlapsPolicy::apply(upper_box, collection[*it]);
|
||||
|
||||
if (lower_overlapping && upper_overlapping)
|
||||
{
|
||||
exceeding.push_back(*it);
|
||||
}
|
||||
else if (lower_overlapping)
|
||||
{
|
||||
lower.push_back(*it);
|
||||
}
|
||||
else if (upper_overlapping)
|
||||
{
|
||||
upper.push_back(*it);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Is nowhere! Should not occur!
|
||||
BOOST_ASSERT(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Match collection with itself
|
||||
template <typename InputCollection, typename Policy>
|
||||
static inline void handle_one(InputCollection const& collection,
|
||||
index_vector_type const& input,
|
||||
Policy& policy)
|
||||
{
|
||||
typedef boost::range_iterator<index_vector_type const>::type index_iterator_type;
|
||||
// Quadratic behaviour at lowest level (lowest quad, or all exceeding)
|
||||
for(index_iterator_type it1 = boost::begin(input); it1 != boost::end(input); ++it1)
|
||||
{
|
||||
index_iterator_type it2 = it1;
|
||||
for(++it2; it2 != boost::end(input); ++it2)
|
||||
{
|
||||
policy.apply(collection[*it1], collection[*it2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Match collection 1 with collection 2
|
||||
template <typename InputCollection, typename Policy>
|
||||
static inline void handle_two(
|
||||
InputCollection const& collection1, index_vector_type const& input1,
|
||||
InputCollection const& collection2, index_vector_type const& input2,
|
||||
Policy& policy)
|
||||
{
|
||||
typedef boost::range_iterator<index_vector_type const>::type index_iterator_type;
|
||||
for(index_iterator_type it1 = boost::begin(input1); it1 != boost::end(input1); ++it1)
|
||||
{
|
||||
for(index_iterator_type it2 = boost::begin(input2); it2 != boost::end(input2); ++it2)
|
||||
{
|
||||
policy.apply(collection1[*it1], collection2[*it2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
int Dimension,
|
||||
typename Box,
|
||||
typename OverlapsPolicy,
|
||||
typename VisitBoxPolicy
|
||||
>
|
||||
class partition_one_collection
|
||||
{
|
||||
typedef std::vector<std::size_t> index_vector_type;
|
||||
typedef typename coordinate_type<Box>::type ctype;
|
||||
typedef partition_one_collection
|
||||
<
|
||||
1 - Dimension,
|
||||
Box,
|
||||
OverlapsPolicy,
|
||||
VisitBoxPolicy
|
||||
> sub_divide;
|
||||
|
||||
template <typename InputCollection, typename Policy>
|
||||
static inline void next_level(Box const& box,
|
||||
InputCollection const& collection,
|
||||
index_vector_type const& input,
|
||||
int level, int min_elements,
|
||||
Policy& policy, VisitBoxPolicy& box_policy)
|
||||
{
|
||||
if (boost::size(input) > 0)
|
||||
{
|
||||
if (boost::size(input) > min_elements && level < 100)
|
||||
{
|
||||
sub_divide::apply(box, collection, input, level + 1, min_elements, policy, box_policy);
|
||||
}
|
||||
else
|
||||
{
|
||||
handle_one(collection, input, policy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public :
|
||||
template <typename InputCollection, typename Policy>
|
||||
static inline void apply(Box const& box,
|
||||
InputCollection const& collection,
|
||||
index_vector_type const& input,
|
||||
int level,
|
||||
int min_elements,
|
||||
Policy& policy, VisitBoxPolicy& box_policy)
|
||||
{
|
||||
box_policy.apply(box, level);
|
||||
|
||||
Box lower_box, upper_box;
|
||||
divide_box<Dimension>(box, lower_box, upper_box);
|
||||
|
||||
index_vector_type lower, upper, exceeding;
|
||||
divide_into_subsets<OverlapsPolicy>(lower_box, upper_box, collection, input, lower, upper, exceeding);
|
||||
|
||||
if (boost::size(exceeding) > 0)
|
||||
{
|
||||
// All what is not fitting a partition should be combined
|
||||
// with each other, and with all which is fitting.
|
||||
handle_one(collection, exceeding, policy);
|
||||
handle_two(collection, exceeding, collection, lower, policy);
|
||||
handle_two(collection, exceeding, collection, upper, policy);
|
||||
}
|
||||
|
||||
// Recursively call operation both parts
|
||||
next_level(lower_box, collection, lower, level, min_elements, policy, box_policy);
|
||||
next_level(upper_box, collection, upper, level, min_elements, policy, box_policy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
int Dimension,
|
||||
typename Box,
|
||||
typename OverlapsPolicy,
|
||||
typename VisitBoxPolicy
|
||||
>
|
||||
class partition_two_collections
|
||||
{
|
||||
typedef std::vector<std::size_t> index_vector_type;
|
||||
typedef typename coordinate_type<Box>::type ctype;
|
||||
typedef partition_two_collections
|
||||
<
|
||||
1 - Dimension,
|
||||
Box,
|
||||
OverlapsPolicy,
|
||||
VisitBoxPolicy
|
||||
> sub_divide;
|
||||
|
||||
template <typename InputCollection, typename Policy>
|
||||
static inline void next_level(Box const& box,
|
||||
InputCollection const& collection1, index_vector_type const& input1,
|
||||
InputCollection const& collection2, index_vector_type const& input2,
|
||||
int level, int min_elements,
|
||||
Policy& policy, VisitBoxPolicy& box_policy)
|
||||
{
|
||||
if (boost::size(input1) > 0 && boost::size(input2) > 0)
|
||||
{
|
||||
if (boost::size(input1) > min_elements
|
||||
&& boost::size(input2) > min_elements
|
||||
&& level < 100)
|
||||
{
|
||||
sub_divide::apply(box, collection1, input1, collection2, input2, level + 1, min_elements, policy, box_policy);
|
||||
}
|
||||
else
|
||||
{
|
||||
box_policy.apply(box, level + 1);
|
||||
handle_two(collection1, input1, collection2, input2, policy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public :
|
||||
template <typename InputCollection, typename Policy>
|
||||
static inline void apply(Box const& box,
|
||||
InputCollection const& collection1, index_vector_type const& input1,
|
||||
InputCollection const& collection2, index_vector_type const& input2,
|
||||
int level,
|
||||
int min_elements,
|
||||
Policy& policy, VisitBoxPolicy& box_policy)
|
||||
{
|
||||
box_policy.apply(box, level);
|
||||
|
||||
Box lower_box, upper_box;
|
||||
divide_box<Dimension>(box, lower_box, upper_box);
|
||||
|
||||
index_vector_type lower1, upper1, exceeding1;
|
||||
index_vector_type lower2, upper2, exceeding2;
|
||||
divide_into_subsets<OverlapsPolicy>(lower_box, upper_box, collection1, input1, lower1, upper1, exceeding1);
|
||||
divide_into_subsets<OverlapsPolicy>(lower_box, upper_box, collection2, input2, lower2, upper2, exceeding2);
|
||||
|
||||
if (boost::size(exceeding1) > 0)
|
||||
{
|
||||
// All exceeding from 1 with 2:
|
||||
handle_two(collection1, exceeding1, collection2, exceeding2, policy);
|
||||
|
||||
// All exceeding from 1 with lower and upper of 2:
|
||||
handle_two(collection1, exceeding1, collection2, lower2, policy);
|
||||
handle_two(collection1, exceeding1, collection2, upper2, policy);
|
||||
}
|
||||
if (boost::size(exceeding2) > 0)
|
||||
{
|
||||
// All exceeding from 2 with lower and upper of 1:
|
||||
handle_two(collection1, lower1, collection2, exceeding2, policy);
|
||||
handle_two(collection1, upper1, collection2, exceeding2, policy);
|
||||
}
|
||||
|
||||
next_level(lower_box, collection1, lower1, collection2, lower2, level, min_elements, policy, box_policy);
|
||||
next_level(upper_box, collection1, upper1, collection2, upper2, level, min_elements, policy, box_policy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
}} // namespace detail::partition
|
||||
|
||||
struct visit_no_policy
|
||||
{
|
||||
template <typename Box>
|
||||
static inline void apply(Box const&, int )
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Box,
|
||||
typename ExpandPolicy,
|
||||
typename OverlapsPolicy,
|
||||
typename VisitBoxPolicy = visit_no_policy
|
||||
>
|
||||
class partition
|
||||
{
|
||||
typedef std::vector<std::size_t> index_vector_type;
|
||||
|
||||
template <typename InputCollection>
|
||||
static inline void expand_to_collection(InputCollection const& collection, Box& total, index_vector_type& index_vector)
|
||||
{
|
||||
std::size_t index = 0;
|
||||
for(typename boost::range_iterator<InputCollection const>::type it
|
||||
= boost::begin(collection);
|
||||
it != boost::end(collection);
|
||||
++it, ++index)
|
||||
{
|
||||
ExpandPolicy::apply(total, *it);
|
||||
index_vector.push_back(index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public :
|
||||
template <typename InputCollection, typename VisitPolicy>
|
||||
static inline void apply(InputCollection const& collection,
|
||||
VisitPolicy& visitor,
|
||||
int min_elements = 16,
|
||||
VisitBoxPolicy box_visitor = visit_no_policy()
|
||||
)
|
||||
{
|
||||
if (boost::size(collection) > min_elements)
|
||||
{
|
||||
index_vector_type index_vector;
|
||||
Box total;
|
||||
assign_inverse(total);
|
||||
expand_to_collection(collection, total, index_vector);
|
||||
|
||||
detail::partition::partition_one_collection
|
||||
<
|
||||
0, Box,
|
||||
OverlapsPolicy,
|
||||
VisitBoxPolicy
|
||||
>::apply(total, collection, index_vector, 0, min_elements, visitor, box_visitor);
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef typename boost::range_iterator<InputCollection const>::type iterator_type;
|
||||
for(iterator_type it1 = boost::begin(collection); it1 != boost::end(collection); ++it1)
|
||||
{
|
||||
iterator_type it2 = it1;
|
||||
for(++it2; it2 != boost::end(collection); ++it2)
|
||||
{
|
||||
visitor.apply(*it1, *it2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename InputCollection, typename VisitPolicy>
|
||||
static inline void apply(InputCollection const& collection1,
|
||||
InputCollection const& collection2,
|
||||
VisitPolicy& visitor,
|
||||
int min_elements = 16,
|
||||
VisitBoxPolicy box_visitor = visit_no_policy()
|
||||
)
|
||||
{
|
||||
if (boost::size(collection1) > min_elements && boost::size(collection2) > min_elements)
|
||||
{
|
||||
index_vector_type index_vector1, index_vector2;
|
||||
Box total;
|
||||
assign_inverse(total);
|
||||
expand_to_collection(collection1, total, index_vector1);
|
||||
expand_to_collection(collection2, total, index_vector2);
|
||||
|
||||
detail::partition::partition_two_collections
|
||||
<
|
||||
0, Box, OverlapsPolicy, VisitBoxPolicy
|
||||
>::apply(total,
|
||||
collection1, index_vector1,
|
||||
collection2, index_vector2,
|
||||
0, min_elements, visitor, box_visitor);
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef typename boost::range_iterator<InputCollection const>::type iterator_type;
|
||||
for(iterator_type it1 = boost::begin(collection1); it1 != boost::end(collection1); ++it1)
|
||||
{
|
||||
for(iterator_type it2 = boost::begin(collection2); it2 != boost::end(collection2); ++it2)
|
||||
{
|
||||
visitor.apply(*it1, *it2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RING_IDENTIFIER_HPP
|
||||
243
test/external/boost/geometry/algorithms/detail/point_on_border.hpp
vendored
Normal file
243
test/external/boost/geometry/algorithms/detail/point_on_border.hpp
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.Dimension. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
#include <boost/geometry/core/ring_type.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace point_on_border
|
||||
{
|
||||
|
||||
|
||||
template<typename Point>
|
||||
struct get_point
|
||||
{
|
||||
static inline bool apply(Point& destination, Point const& source, bool)
|
||||
{
|
||||
destination = source;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Point, std::size_t Dimension, std::size_t DimensionCount>
|
||||
struct midpoint_helper
|
||||
{
|
||||
static inline bool apply(Point& p, Point const& p1, Point const& p2)
|
||||
{
|
||||
typename coordinate_type<Point>::type const two = 2;
|
||||
set<Dimension>(p,
|
||||
(get<Dimension>(p1) + get<Dimension>(p2)) / two);
|
||||
return midpoint_helper<Point, Dimension + 1, DimensionCount>::apply(p, p1, p2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Point, std::size_t DimensionCount>
|
||||
struct midpoint_helper<Point, DimensionCount, DimensionCount>
|
||||
{
|
||||
static inline bool apply(Point& , Point const& , Point const& )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename Point, typename Range>
|
||||
struct point_on_range
|
||||
{
|
||||
static inline bool apply(Point& point, Range const& range, bool midpoint)
|
||||
{
|
||||
const std::size_t n = boost::size(range);
|
||||
if (midpoint && n > 1)
|
||||
{
|
||||
typedef typename boost::range_iterator
|
||||
<
|
||||
Range const
|
||||
>::type iterator;
|
||||
|
||||
iterator it = boost::begin(range);
|
||||
iterator prev = it++;
|
||||
while (it != boost::end(range)
|
||||
&& detail::equals::equals_point_point(*it, *prev))
|
||||
{
|
||||
prev = it++;
|
||||
}
|
||||
if (it != boost::end(range))
|
||||
{
|
||||
return midpoint_helper
|
||||
<
|
||||
Point,
|
||||
0, dimension<Point>::value
|
||||
>::apply(point, *prev, *it);
|
||||
}
|
||||
}
|
||||
|
||||
if (n > 0)
|
||||
{
|
||||
point = *boost::begin(range);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename Point, typename Polygon>
|
||||
struct point_on_polygon
|
||||
{
|
||||
static inline bool apply(Point& point, Polygon const& polygon, bool midpoint)
|
||||
{
|
||||
return point_on_range
|
||||
<
|
||||
Point,
|
||||
typename ring_type<Polygon>::type
|
||||
>::apply(point, exterior_ring(polygon), midpoint);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename Point, typename Box>
|
||||
struct point_on_box
|
||||
{
|
||||
static inline bool apply(Point& point, Box const& box, bool midpoint)
|
||||
{
|
||||
if (midpoint)
|
||||
{
|
||||
Point p1, p2;
|
||||
detail::assign::assign_box_2d_corner<min_corner, min_corner>(box, p1);
|
||||
detail::assign::assign_box_2d_corner<max_corner, min_corner>(box, p2);
|
||||
midpoint_helper
|
||||
<
|
||||
Point,
|
||||
0, dimension<Point>::value
|
||||
>::apply(point, p1, p2);
|
||||
}
|
||||
else
|
||||
{
|
||||
detail::assign::assign_box_2d_corner<min_corner, min_corner>(box, point);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::point_on_border
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryTag,
|
||||
typename Point,
|
||||
typename Geometry
|
||||
|
||||
>
|
||||
struct point_on_border
|
||||
{};
|
||||
|
||||
|
||||
template<typename Point>
|
||||
struct point_on_border<point_tag, Point, Point>
|
||||
: detail::point_on_border::get_point<Point>
|
||||
{};
|
||||
|
||||
|
||||
template<typename Point, typename Linestring>
|
||||
struct point_on_border<linestring_tag, Point, Linestring>
|
||||
: detail::point_on_border::point_on_range<Point, Linestring>
|
||||
{};
|
||||
|
||||
|
||||
template<typename Point, typename Ring>
|
||||
struct point_on_border<ring_tag, Point, Ring>
|
||||
: detail::point_on_border::point_on_range<Point, Ring>
|
||||
{};
|
||||
|
||||
|
||||
template<typename Point, typename Polygon>
|
||||
struct point_on_border<polygon_tag, Point, Polygon>
|
||||
: detail::point_on_border::point_on_polygon<Point, Polygon>
|
||||
{};
|
||||
|
||||
|
||||
template<typename Point, typename Box>
|
||||
struct point_on_border<box_tag, Point, Box>
|
||||
: detail::point_on_border::point_on_box<Point, Box>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief Take point on a border
|
||||
\ingroup overlay
|
||||
\tparam Geometry geometry type. This also defines the type of the output point
|
||||
\param point to assign
|
||||
\param geometry geometry to take point from
|
||||
\param midpoint boolean flag, true if the point should not be a vertex, but some point
|
||||
in between of two vertices
|
||||
\return TRUE if successful, else false.
|
||||
It is only false if polygon/line have no points
|
||||
\note for a polygon, it is always a point on the exterior ring
|
||||
\note for take_midpoint, it is not taken from two consecutive duplicate vertices,
|
||||
(unless there are no other).
|
||||
*/
|
||||
template <typename Point, typename Geometry>
|
||||
inline bool point_on_border(Point& point,
|
||||
Geometry const& geometry,
|
||||
bool midpoint = false)
|
||||
{
|
||||
concept::check<Point>();
|
||||
concept::check<Geometry const>();
|
||||
|
||||
typedef typename point_type<Geometry>::type point_type;
|
||||
|
||||
return dispatch::point_on_border
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Point,
|
||||
Geometry
|
||||
>::apply(point, geometry, midpoint);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP
|
||||
70
test/external/boost/geometry/algorithms/detail/ring_identifier.hpp
vendored
Normal file
70
test/external/boost/geometry/algorithms/detail/ring_identifier.hpp
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RING_IDENTIFIER_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RING_IDENTIFIER_HPP
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
// Ring Identifier. It is currently: source,multi,ring
|
||||
struct ring_identifier
|
||||
{
|
||||
|
||||
inline ring_identifier()
|
||||
: source_index(-1)
|
||||
, multi_index(-1)
|
||||
, ring_index(-1)
|
||||
{}
|
||||
|
||||
inline ring_identifier(int src, int mul, int rin)
|
||||
: source_index(src)
|
||||
, multi_index(mul)
|
||||
, ring_index(rin)
|
||||
{}
|
||||
|
||||
inline bool operator<(ring_identifier const& other) const
|
||||
{
|
||||
return source_index != other.source_index ? source_index < other.source_index
|
||||
: multi_index !=other.multi_index ? multi_index < other.multi_index
|
||||
: ring_index < other.ring_index
|
||||
;
|
||||
}
|
||||
|
||||
inline bool operator==(ring_identifier const& other) const
|
||||
{
|
||||
return source_index == other.source_index
|
||||
&& ring_index == other.ring_index
|
||||
&& multi_index == other.multi_index
|
||||
;
|
||||
}
|
||||
|
||||
#if defined(BOOST_GEOMETRY_DEBUG_IDENTIFIER)
|
||||
friend std::ostream& operator<<(std::ostream &os, ring_identifier const& ring_id)
|
||||
{
|
||||
os << "(s:" << ring_id.source_index;
|
||||
if (ring_id.ring_index >= 0) os << ", r:" << ring_id.ring_index;
|
||||
if (ring_id.multi_index >= 0) os << ", m:" << ring_id.multi_index;
|
||||
os << ")";
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int source_index;
|
||||
int multi_index;
|
||||
int ring_index;
|
||||
};
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RING_IDENTIFIER_HPP
|
||||
131
test/external/boost/geometry/algorithms/detail/sections/range_by_section.hpp
vendored
Normal file
131
test/external/boost/geometry/algorithms/detail/sections/range_by_section.hpp
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP
|
||||
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace section
|
||||
{
|
||||
|
||||
|
||||
template <typename Range, typename Section>
|
||||
struct full_section_range
|
||||
{
|
||||
static inline Range const& apply(Range const& range, Section const& section)
|
||||
{
|
||||
return range;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Polygon, typename Section>
|
||||
struct full_section_polygon
|
||||
{
|
||||
static inline typename ring_return_type<Polygon const>::type apply(Polygon const& polygon, Section const& section)
|
||||
{
|
||||
return section.ring_id.ring_index < 0
|
||||
? geometry::exterior_ring(polygon)
|
||||
: geometry::interior_rings(polygon)[section.ring_id.ring_index];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::section
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag,
|
||||
typename Geometry,
|
||||
typename Section
|
||||
>
|
||||
struct range_by_section
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
|
||||
, (types<Geometry>)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
template <typename LineString, typename Section>
|
||||
struct range_by_section<linestring_tag, LineString, Section>
|
||||
: detail::section::full_section_range<LineString, Section>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Ring, typename Section>
|
||||
struct range_by_section<ring_tag, Ring, Section>
|
||||
: detail::section::full_section_range<Ring, Section>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename Section>
|
||||
struct range_by_section<polygon_tag, Polygon, Section>
|
||||
: detail::section::full_section_polygon<Polygon, Section>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
\brief Get full ring (exterior, one of interiors, one from multi)
|
||||
indicated by the specified section
|
||||
\ingroup sectionalize
|
||||
\tparam Geometry type
|
||||
\tparam Section type of section to get from
|
||||
\param geometry geometry to take section of
|
||||
\param section structure with section
|
||||
*/
|
||||
template <typename Geometry, typename Section>
|
||||
inline typename ring_return_type<Geometry const>::type
|
||||
range_by_section(Geometry const& geometry, Section const& section)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
return dispatch::range_by_section
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
Section
|
||||
>::apply(geometry, section);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP
|
||||
648
test/external/boost/geometry/algorithms/detail/sections/sectionalize.hpp
vendored
Normal file
648
test/external/boost/geometry/algorithms/detail/sections/sectionalize.hpp
vendored
Normal file
@@ -0,0 +1,648 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_SECTIONALIZE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_SECTIONALIZE_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
#include <boost/geometry/algorithms/expand.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/point_order.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
#include <boost/geometry/views/closeable_view.hpp>
|
||||
#include <boost/geometry/views/reversible_view.hpp>
|
||||
#include <boost/geometry/geometries/segment.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
/*!
|
||||
\brief Structure containing section information
|
||||
\details Section information consists of a bounding box, direction
|
||||
information (if it is increasing or decreasing, per dimension),
|
||||
index information (begin-end, ring, multi) and the number of
|
||||
segments in this section
|
||||
|
||||
\tparam Box box-type
|
||||
\tparam DimensionCount number of dimensions for this section
|
||||
\ingroup sectionalize
|
||||
*/
|
||||
template <typename Box, std::size_t DimensionCount>
|
||||
struct section
|
||||
{
|
||||
typedef Box box_type;
|
||||
|
||||
int id; // might be obsolete now, BSG 14-03-2011 TODO decide about this
|
||||
|
||||
int directions[DimensionCount];
|
||||
ring_identifier ring_id;
|
||||
Box bounding_box;
|
||||
|
||||
int begin_index;
|
||||
int end_index;
|
||||
std::size_t count;
|
||||
std::size_t range_count;
|
||||
bool duplicate;
|
||||
int non_duplicate_index;
|
||||
|
||||
inline section()
|
||||
: id(-1)
|
||||
, begin_index(-1)
|
||||
, end_index(-1)
|
||||
, count(0)
|
||||
, range_count(0)
|
||||
, duplicate(false)
|
||||
, non_duplicate_index(-1)
|
||||
{
|
||||
assign_inverse(bounding_box);
|
||||
for (register std::size_t i = 0; i < DimensionCount; i++)
|
||||
{
|
||||
directions[i] = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
\brief Structure containing a collection of sections
|
||||
\note Derived from a vector, proves to be faster than of deque
|
||||
\note vector might be templated in the future
|
||||
\ingroup sectionalize
|
||||
*/
|
||||
template <typename Box, std::size_t DimensionCount>
|
||||
struct sections : std::vector<section<Box, DimensionCount> >
|
||||
{
|
||||
typedef Box box_type;
|
||||
static std::size_t const value = DimensionCount;
|
||||
};
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace sectionalize
|
||||
{
|
||||
|
||||
template <typename Segment, std::size_t Dimension, std::size_t DimensionCount>
|
||||
struct get_direction_loop
|
||||
{
|
||||
typedef typename coordinate_type<Segment>::type coordinate_type;
|
||||
|
||||
static inline void apply(Segment const& seg,
|
||||
int directions[DimensionCount])
|
||||
{
|
||||
coordinate_type const diff =
|
||||
geometry::get<1, Dimension>(seg) - geometry::get<0, Dimension>(seg);
|
||||
|
||||
coordinate_type zero = coordinate_type();
|
||||
directions[Dimension] = diff > zero ? 1 : diff < zero ? -1 : 0;
|
||||
|
||||
get_direction_loop
|
||||
<
|
||||
Segment, Dimension + 1, DimensionCount
|
||||
>::apply(seg, directions);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Segment, std::size_t DimensionCount>
|
||||
struct get_direction_loop<Segment, DimensionCount, DimensionCount>
|
||||
{
|
||||
static inline void apply(Segment const&, int [DimensionCount])
|
||||
{}
|
||||
};
|
||||
|
||||
template <typename T, std::size_t Dimension, std::size_t DimensionCount>
|
||||
struct copy_loop
|
||||
{
|
||||
static inline void apply(T const source[DimensionCount],
|
||||
T target[DimensionCount])
|
||||
{
|
||||
target[Dimension] = source[Dimension];
|
||||
copy_loop<T, Dimension + 1, DimensionCount>::apply(source, target);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, std::size_t DimensionCount>
|
||||
struct copy_loop<T, DimensionCount, DimensionCount>
|
||||
{
|
||||
static inline void apply(T const [DimensionCount], T [DimensionCount])
|
||||
{}
|
||||
};
|
||||
|
||||
template <typename T, std::size_t Dimension, std::size_t DimensionCount>
|
||||
struct compare_loop
|
||||
{
|
||||
static inline bool apply(T const source[DimensionCount],
|
||||
T const target[DimensionCount])
|
||||
{
|
||||
bool const not_equal = target[Dimension] != source[Dimension];
|
||||
|
||||
return not_equal
|
||||
? false
|
||||
: compare_loop
|
||||
<
|
||||
T, Dimension + 1, DimensionCount
|
||||
>::apply(source, target);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, std::size_t DimensionCount>
|
||||
struct compare_loop<T, DimensionCount, DimensionCount>
|
||||
{
|
||||
static inline bool apply(T const [DimensionCount],
|
||||
T const [DimensionCount])
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Segment, std::size_t Dimension, std::size_t DimensionCount>
|
||||
struct check_duplicate_loop
|
||||
{
|
||||
typedef typename coordinate_type<Segment>::type coordinate_type;
|
||||
|
||||
static inline bool apply(Segment const& seg)
|
||||
{
|
||||
if (! geometry::math::equals
|
||||
(
|
||||
geometry::get<0, Dimension>(seg),
|
||||
geometry::get<1, Dimension>(seg)
|
||||
)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return check_duplicate_loop
|
||||
<
|
||||
Segment, Dimension + 1, DimensionCount
|
||||
>::apply(seg);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Segment, std::size_t DimensionCount>
|
||||
struct check_duplicate_loop<Segment, DimensionCount, DimensionCount>
|
||||
{
|
||||
static inline bool apply(Segment const&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, std::size_t Dimension, std::size_t DimensionCount>
|
||||
struct assign_loop
|
||||
{
|
||||
static inline void apply(T dims[DimensionCount], int const value)
|
||||
{
|
||||
dims[Dimension] = value;
|
||||
assign_loop<T, Dimension + 1, DimensionCount>::apply(dims, value);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, std::size_t DimensionCount>
|
||||
struct assign_loop<T, DimensionCount, DimensionCount>
|
||||
{
|
||||
static inline void apply(T [DimensionCount], int const)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/// @brief Helper class to create sections of a part of a range, on the fly
|
||||
template
|
||||
<
|
||||
typename Range, // Can be closeable_view
|
||||
typename Point,
|
||||
typename Sections,
|
||||
std::size_t DimensionCount,
|
||||
std::size_t MaxCount
|
||||
>
|
||||
struct sectionalize_part
|
||||
{
|
||||
typedef model::referring_segment<Point const> segment_type;
|
||||
typedef typename boost::range_value<Sections>::type section_type;
|
||||
|
||||
typedef typename boost::range_iterator<Range const>::type iterator_type;
|
||||
|
||||
static inline void apply(Sections& sections, section_type& section,
|
||||
int& index, int& ndi,
|
||||
Range const& range,
|
||||
ring_identifier ring_id)
|
||||
{
|
||||
if (boost::size(range) <= index)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
ndi = 0;
|
||||
}
|
||||
|
||||
iterator_type it = boost::begin(range);
|
||||
it += index;
|
||||
|
||||
for(iterator_type previous = it++;
|
||||
it != boost::end(range);
|
||||
++previous, ++it, index++)
|
||||
{
|
||||
segment_type segment(*previous, *it);
|
||||
|
||||
int direction_classes[DimensionCount] = {0};
|
||||
get_direction_loop
|
||||
<
|
||||
segment_type, 0, DimensionCount
|
||||
>::apply(segment, direction_classes);
|
||||
|
||||
// if "dir" == 0 for all point-dimensions, it is duplicate.
|
||||
// Those sections might be omitted, if wished, lateron
|
||||
bool duplicate = false;
|
||||
|
||||
if (direction_classes[0] == 0)
|
||||
{
|
||||
// Recheck because ALL dimensions should be checked,
|
||||
// not only first one.
|
||||
// (DimensionCount might be < dimension<P>::value)
|
||||
if (check_duplicate_loop
|
||||
<
|
||||
segment_type, 0, geometry::dimension<Point>::type::value
|
||||
>::apply(segment)
|
||||
)
|
||||
{
|
||||
duplicate = true;
|
||||
|
||||
// Change direction-info to force new section
|
||||
// Note that wo consecutive duplicate segments will generate
|
||||
// only one duplicate-section.
|
||||
// Actual value is not important as long as it is not -1,0,1
|
||||
assign_loop
|
||||
<
|
||||
int, 0, DimensionCount
|
||||
>::apply(direction_classes, -99);
|
||||
}
|
||||
}
|
||||
|
||||
if (section.count > 0
|
||||
&& (!compare_loop
|
||||
<
|
||||
int, 0, DimensionCount
|
||||
>::apply(direction_classes, section.directions)
|
||||
|| section.count > MaxCount
|
||||
)
|
||||
)
|
||||
{
|
||||
sections.push_back(section);
|
||||
section = section_type();
|
||||
}
|
||||
|
||||
if (section.count == 0)
|
||||
{
|
||||
section.begin_index = index;
|
||||
section.ring_id = ring_id;
|
||||
section.duplicate = duplicate;
|
||||
section.non_duplicate_index = ndi;
|
||||
section.range_count = boost::size(range);
|
||||
|
||||
copy_loop
|
||||
<
|
||||
int, 0, DimensionCount
|
||||
>::apply(direction_classes, section.directions);
|
||||
geometry::expand(section.bounding_box, *previous);
|
||||
}
|
||||
|
||||
geometry::expand(section.bounding_box, *it);
|
||||
section.end_index = index + 1;
|
||||
section.count++;
|
||||
if (! duplicate)
|
||||
{
|
||||
ndi++;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Range, closure_selector Closure, bool Reverse,
|
||||
typename Point,
|
||||
typename Sections,
|
||||
std::size_t DimensionCount,
|
||||
std::size_t MaxCount
|
||||
>
|
||||
struct sectionalize_range
|
||||
{
|
||||
typedef typename closeable_view<Range const, Closure>::type cview_type;
|
||||
typedef typename reversible_view
|
||||
<
|
||||
cview_type const,
|
||||
Reverse ? iterate_reverse : iterate_forward
|
||||
>::type view_type;
|
||||
|
||||
static inline void apply(Range const& range, Sections& sections,
|
||||
ring_identifier ring_id)
|
||||
{
|
||||
typedef model::referring_segment<Point const> segment_type;
|
||||
|
||||
cview_type cview(range);
|
||||
view_type view(cview);
|
||||
|
||||
std::size_t const n = boost::size(view);
|
||||
if (n == 0)
|
||||
{
|
||||
// Zero points, no section
|
||||
return;
|
||||
}
|
||||
|
||||
if (n == 1)
|
||||
{
|
||||
// Line with one point ==> no sections
|
||||
return;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
int ndi = 0; // non duplicate index
|
||||
|
||||
typedef typename boost::range_value<Sections>::type section_type;
|
||||
section_type section;
|
||||
|
||||
sectionalize_part
|
||||
<
|
||||
view_type, Point, Sections,
|
||||
DimensionCount, MaxCount
|
||||
>::apply(sections, section, index, ndi,
|
||||
view, ring_id);
|
||||
|
||||
// Add last section if applicable
|
||||
if (section.count > 0)
|
||||
{
|
||||
sections.push_back(section);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Polygon,
|
||||
bool Reverse,
|
||||
typename Sections,
|
||||
std::size_t DimensionCount,
|
||||
std::size_t MaxCount
|
||||
>
|
||||
struct sectionalize_polygon
|
||||
{
|
||||
static inline void apply(Polygon const& poly, Sections& sections,
|
||||
ring_identifier ring_id)
|
||||
{
|
||||
typedef typename point_type<Polygon>::type point_type;
|
||||
typedef typename ring_type<Polygon>::type ring_type;
|
||||
typedef sectionalize_range
|
||||
<
|
||||
ring_type, closure<Polygon>::value, Reverse,
|
||||
point_type, Sections, DimensionCount, MaxCount
|
||||
> sectionalizer_type;
|
||||
|
||||
ring_id.ring_index = -1;
|
||||
sectionalizer_type::apply(exterior_ring(poly), sections, ring_id);//-1, multi_index);
|
||||
|
||||
ring_id.ring_index++;
|
||||
typename interior_return_type<Polygon const>::type rings
|
||||
= interior_rings(poly);
|
||||
for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings);
|
||||
++it, ++ring_id.ring_index)
|
||||
{
|
||||
sectionalizer_type::apply(*it, sections, ring_id);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Box,
|
||||
typename Sections,
|
||||
std::size_t DimensionCount,
|
||||
std::size_t MaxCount
|
||||
>
|
||||
struct sectionalize_box
|
||||
{
|
||||
static inline void apply(Box const& box, Sections& sections, ring_identifier const& ring_id)
|
||||
{
|
||||
typedef typename point_type<Box>::type point_type;
|
||||
|
||||
assert_dimension<Box, 2>();
|
||||
|
||||
// Add all four sides of the 2D-box as separate section.
|
||||
// Easiest is to convert it to a polygon.
|
||||
// However, we don't have the polygon type
|
||||
// (or polygon would be a helper-type).
|
||||
// Therefore we mimic a linestring/std::vector of 5 points
|
||||
|
||||
// TODO: might be replaced by assign_box_corners_oriented
|
||||
// or just "convert"
|
||||
point_type ll, lr, ul, ur;
|
||||
geometry::detail::assign_box_corners(box, ll, lr, ul, ur);
|
||||
|
||||
std::vector<point_type> points;
|
||||
points.push_back(ll);
|
||||
points.push_back(ul);
|
||||
points.push_back(ur);
|
||||
points.push_back(lr);
|
||||
points.push_back(ll);
|
||||
|
||||
sectionalize_range
|
||||
<
|
||||
std::vector<point_type>, closed, false,
|
||||
point_type,
|
||||
Sections,
|
||||
DimensionCount,
|
||||
MaxCount
|
||||
>::apply(points, sections, ring_id);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Sections>
|
||||
inline void set_section_unique_ids(Sections& sections)
|
||||
{
|
||||
// Set ID's.
|
||||
int index = 0;
|
||||
for (typename boost::range_iterator<Sections>::type it = boost::begin(sections);
|
||||
it != boost::end(sections);
|
||||
++it)
|
||||
{
|
||||
it->id = index++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}} // namespace detail::sectionalize
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag,
|
||||
typename Geometry,
|
||||
bool Reverse,
|
||||
typename Sections,
|
||||
std::size_t DimensionCount,
|
||||
std::size_t MaxCount
|
||||
>
|
||||
struct sectionalize
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
|
||||
, (types<Geometry>)
|
||||
);
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Box,
|
||||
bool Reverse,
|
||||
typename Sections,
|
||||
std::size_t DimensionCount,
|
||||
std::size_t MaxCount
|
||||
>
|
||||
struct sectionalize<box_tag, Box, Reverse, Sections, DimensionCount, MaxCount>
|
||||
: detail::sectionalize::sectionalize_box
|
||||
<
|
||||
Box,
|
||||
Sections,
|
||||
DimensionCount,
|
||||
MaxCount
|
||||
>
|
||||
{};
|
||||
|
||||
template
|
||||
<
|
||||
typename LineString,
|
||||
typename Sections,
|
||||
std::size_t DimensionCount,
|
||||
std::size_t MaxCount
|
||||
>
|
||||
struct sectionalize
|
||||
<
|
||||
linestring_tag,
|
||||
LineString,
|
||||
false,
|
||||
Sections,
|
||||
DimensionCount,
|
||||
MaxCount
|
||||
>
|
||||
: detail::sectionalize::sectionalize_range
|
||||
<
|
||||
LineString, closed, false,
|
||||
typename point_type<LineString>::type,
|
||||
Sections,
|
||||
DimensionCount,
|
||||
MaxCount
|
||||
>
|
||||
{};
|
||||
|
||||
template
|
||||
<
|
||||
typename Ring,
|
||||
bool Reverse,
|
||||
typename Sections,
|
||||
std::size_t DimensionCount,
|
||||
std::size_t MaxCount
|
||||
>
|
||||
struct sectionalize<ring_tag, Ring, Reverse, Sections, DimensionCount, MaxCount>
|
||||
: detail::sectionalize::sectionalize_range
|
||||
<
|
||||
Ring, geometry::closure<Ring>::value, Reverse,
|
||||
typename point_type<Ring>::type,
|
||||
Sections,
|
||||
DimensionCount,
|
||||
MaxCount
|
||||
>
|
||||
{};
|
||||
|
||||
template
|
||||
<
|
||||
typename Polygon,
|
||||
bool Reverse,
|
||||
typename Sections,
|
||||
std::size_t DimensionCount,
|
||||
std::size_t MaxCount
|
||||
>
|
||||
struct sectionalize<polygon_tag, Polygon, Reverse, Sections, DimensionCount, MaxCount>
|
||||
: detail::sectionalize::sectionalize_polygon
|
||||
<
|
||||
Polygon, Reverse, Sections, DimensionCount, MaxCount
|
||||
>
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
\brief Split a geometry into monotonic sections
|
||||
\ingroup sectionalize
|
||||
\tparam Geometry type of geometry to check
|
||||
\tparam Sections type of sections to create
|
||||
\param geometry geometry to create sections from
|
||||
\param sections structure with sections
|
||||
\param source_index index to assign to the ring_identifiers
|
||||
*/
|
||||
template<bool Reverse, typename Geometry, typename Sections>
|
||||
inline void sectionalize(Geometry const& geometry, Sections& sections, int source_index = 0)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
// TODO: review use of this constant (see below) as causing problems with GCC 4.6 --mloskot
|
||||
// A maximum of 10 segments per section seems to give the fastest results
|
||||
//static std::size_t const max_segments_per_section = 10;
|
||||
typedef dispatch::sectionalize
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
Reverse,
|
||||
Sections,
|
||||
Sections::value,
|
||||
10 // TODO: max_segments_per_section
|
||||
> sectionalizer_type;
|
||||
|
||||
sections.clear();
|
||||
ring_identifier ring_id;
|
||||
ring_id.source_index = source_index;
|
||||
sectionalizer_type::apply(geometry, sections, ring_id);
|
||||
detail::sectionalize::set_section_unique_ids(sections);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_SECTIONALIZE_HPP
|
||||
148
test/external/boost/geometry/algorithms/difference.hpp
vendored
Normal file
148
test/external/boost/geometry/algorithms/difference.hpp
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/intersection_insert.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace difference
|
||||
{
|
||||
|
||||
/*!
|
||||
\brief_calc2{difference} \brief_strategy
|
||||
\ingroup difference
|
||||
\details \details_calc2{difference_insert, spatial set theoretic difference}
|
||||
\brief_strategy. \details_inserter{difference}
|
||||
\tparam GeometryOut output geometry type, must be specified
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam OutputIterator output iterator
|
||||
\tparam Strategy \tparam_strategy_overlay
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param out \param_out{difference}
|
||||
\param strategy \param_strategy{difference}
|
||||
\return \return_out
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename GeometryOut,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename OutputIterator,
|
||||
typename Strategy
|
||||
>
|
||||
inline OutputIterator difference_insert(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2, OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
concept::check<GeometryOut>();
|
||||
|
||||
return detail::intersection::insert<GeometryOut, true, overlay_difference>(
|
||||
geometry1, geometry2,
|
||||
out,
|
||||
strategy);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief_calc2{difference}
|
||||
\ingroup difference
|
||||
\details \details_calc2{difference_insert, spatial set theoretic difference}.
|
||||
\details_insert{difference}
|
||||
\tparam GeometryOut output geometry type, must be specified
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam OutputIterator output iterator
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param out \param_out{difference}
|
||||
\return \return_out
|
||||
|
||||
\qbk{[include reference/algorithms/difference_insert.qbk]}
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename GeometryOut,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename OutputIterator
|
||||
>
|
||||
inline OutputIterator difference_insert(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2, OutputIterator out)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
concept::check<GeometryOut>();
|
||||
|
||||
typedef strategy_intersection
|
||||
<
|
||||
typename cs_tag<GeometryOut>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
typename geometry::point_type<GeometryOut>::type
|
||||
> strategy;
|
||||
|
||||
return difference_insert<GeometryOut>(geometry1, geometry2,
|
||||
out, strategy());
|
||||
}
|
||||
|
||||
|
||||
}} // namespace detail::difference
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief_calc2{difference}
|
||||
\ingroup difference
|
||||
\details \details_calc2{difference, spatial set theoretic difference}.
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam Collection \tparam_output_collection
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param output_collection the output collection
|
||||
|
||||
\qbk{[include reference/algorithms/difference.qbk]}
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Collection
|
||||
>
|
||||
inline void difference(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2, Collection& output_collection)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
typedef typename boost::range_value<Collection>::type geometry_out;
|
||||
concept::check<geometry_out>();
|
||||
|
||||
detail::difference::difference_insert<geometry_out>(
|
||||
geometry1, geometry2,
|
||||
std::back_inserter(output_collection));
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP
|
||||
253
test/external/boost/geometry/algorithms/disjoint.hpp
vendored
Normal file
253
test/external/boost/geometry/algorithms/disjoint.hpp
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DISJOINT_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DISJOINT_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <deque>
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/reverse_dispatch.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/disjoint.hpp>
|
||||
#include <boost/geometry/algorithms/detail/point_on_border.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
|
||||
#include <boost/geometry/algorithms/within.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace disjoint
|
||||
{
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct disjoint_linear
|
||||
{
|
||||
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
typedef typename geometry::point_type<Geometry1>::type point_type;
|
||||
|
||||
typedef overlay::turn_info<point_type> turn_info;
|
||||
std::deque<turn_info> turns;
|
||||
|
||||
// Get (and stop on) any intersection
|
||||
disjoint_interrupt_policy policy;
|
||||
geometry::get_turns
|
||||
<
|
||||
false, false,
|
||||
overlay::assign_null_policy
|
||||
>(geometry1, geometry2, turns, policy);
|
||||
if (policy.has_intersections)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Segment1, typename Segment2>
|
||||
struct disjoint_segment
|
||||
{
|
||||
static inline bool apply(Segment1 const& segment1, Segment2 const& segment2)
|
||||
{
|
||||
typedef typename point_type<Segment1>::type point_type;
|
||||
|
||||
segment_intersection_points<point_type> is
|
||||
= strategy::intersection::relate_cartesian_segments
|
||||
<
|
||||
policies::relate::segments_intersection_points
|
||||
<
|
||||
Segment1,
|
||||
Segment2,
|
||||
segment_intersection_points<point_type>
|
||||
>
|
||||
>::apply(segment1, segment2);
|
||||
|
||||
return is.count == 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct general_areal
|
||||
{
|
||||
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
if (! disjoint_linear<Geometry1, Geometry2>::apply(geometry1, geometry2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef typename geometry::point_type<Geometry1>::type point_type;
|
||||
|
||||
// If there is no intersection of segments, they might located
|
||||
// inside each other
|
||||
point_type p1;
|
||||
geometry::point_on_border(p1, geometry1);
|
||||
if (geometry::within(p1, geometry2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
typename geometry::point_type<Geometry1>::type p2;
|
||||
geometry::point_on_border(p2, geometry2);
|
||||
if (geometry::within(p2, geometry1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::disjoint
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryTag1, typename GeometryTag2,
|
||||
typename Geometry1, typename Geometry2,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct disjoint
|
||||
: detail::disjoint::general_areal<Geometry1, Geometry2>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Point1, typename Point2, std::size_t DimensionCount>
|
||||
struct disjoint<point_tag, point_tag, Point1, Point2, DimensionCount>
|
||||
: detail::disjoint::point_point<Point1, Point2, 0, DimensionCount>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Box1, typename Box2, std::size_t DimensionCount>
|
||||
struct disjoint<box_tag, box_tag, Box1, Box2, DimensionCount>
|
||||
: detail::disjoint::box_box<Box1, Box2, 0, DimensionCount>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Point, typename Box, std::size_t DimensionCount>
|
||||
struct disjoint<point_tag, box_tag, Point, Box, DimensionCount>
|
||||
: detail::disjoint::point_box<Point, Box, 0, DimensionCount>
|
||||
{};
|
||||
|
||||
template <typename Linestring1, typename Linestring2>
|
||||
struct disjoint<linestring_tag, linestring_tag, Linestring1, Linestring2, 2>
|
||||
: detail::disjoint::disjoint_linear<Linestring1, Linestring2>
|
||||
{};
|
||||
|
||||
template <typename Linestring1, typename Linestring2>
|
||||
struct disjoint<segment_tag, segment_tag, Linestring1, Linestring2, 2>
|
||||
: detail::disjoint::disjoint_segment<Linestring1, Linestring2>
|
||||
{};
|
||||
|
||||
template <typename Linestring, typename Segment>
|
||||
struct disjoint<linestring_tag, segment_tag, Linestring, Segment, 2>
|
||||
: detail::disjoint::disjoint_linear<Linestring, Segment>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryTag1, typename GeometryTag2,
|
||||
typename Geometry1, typename Geometry2,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct disjoint_reversed
|
||||
{
|
||||
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
|
||||
{
|
||||
return disjoint
|
||||
<
|
||||
GeometryTag2, GeometryTag1,
|
||||
Geometry2, Geometry1,
|
||||
DimensionCount
|
||||
>::apply(g2, g1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check2{are disjoint}
|
||||
\ingroup disjoint
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\return \return_check2{are disjoint}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline bool disjoint(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2)
|
||||
{
|
||||
concept::check_concepts_and_equal_dimensions
|
||||
<
|
||||
Geometry1 const,
|
||||
Geometry2 const
|
||||
>();
|
||||
|
||||
return boost::mpl::if_c
|
||||
<
|
||||
reverse_dispatch<Geometry1, Geometry2>::type::value,
|
||||
dispatch::disjoint_reversed
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
dimension<Geometry1>::type::value
|
||||
>,
|
||||
dispatch::disjoint
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
dimension<Geometry1>::type::value
|
||||
>
|
||||
>::type::apply(geometry1, geometry2);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DISJOINT_HPP
|
||||
569
test/external/boost/geometry/algorithms/distance.hpp
vendored
Normal file
569
test/external/boost/geometry/algorithms/distance.hpp
vendored
Normal file
@@ -0,0 +1,569 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DISTANCE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DISTANCE_HPP
|
||||
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/reverse_dispatch.hpp>
|
||||
#include <boost/geometry/core/tag_cast.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/segment.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/distance.hpp>
|
||||
#include <boost/geometry/strategies/default_distance_result.hpp>
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
#include <boost/geometry/algorithms/within.hpp>
|
||||
|
||||
#include <boost/geometry/views/closeable_view.hpp>
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace distance
|
||||
{
|
||||
|
||||
// To avoid spurious namespaces here:
|
||||
using strategy::distance::services::return_type;
|
||||
|
||||
template <typename P1, typename P2, typename Strategy>
|
||||
struct point_to_point
|
||||
{
|
||||
static inline typename return_type<Strategy>::type apply(P1 const& p1,
|
||||
P2 const& p2, Strategy const& strategy)
|
||||
{
|
||||
return strategy.apply(p1, p2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename Point, typename Segment, typename Strategy>
|
||||
struct point_to_segment
|
||||
{
|
||||
static inline typename return_type<Strategy>::type apply(Point const& point,
|
||||
Segment const& segment, Strategy const& strategy)
|
||||
{
|
||||
typename strategy::distance::services::default_strategy
|
||||
<
|
||||
segment_tag,
|
||||
Point,
|
||||
typename point_type<Segment>::type,
|
||||
typename cs_tag<Point>::type,
|
||||
typename cs_tag<typename point_type<Segment>::type>::type,
|
||||
Strategy
|
||||
>::type segment_strategy;
|
||||
|
||||
typename point_type<Segment>::type p[2];
|
||||
geometry::detail::assign_point_from_index<0>(segment, p[0]);
|
||||
geometry::detail::assign_point_from_index<1>(segment, p[1]);
|
||||
return segment_strategy.apply(point, p[0], p[1]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename Range,
|
||||
closure_selector Closure,
|
||||
typename PPStrategy,
|
||||
typename PSStrategy
|
||||
>
|
||||
struct point_to_range
|
||||
{
|
||||
typedef typename return_type<PSStrategy>::type return_type;
|
||||
|
||||
static inline return_type apply(Point const& point, Range const& range,
|
||||
PPStrategy const& pp_strategy, PSStrategy const& ps_strategy)
|
||||
{
|
||||
return_type const zero = return_type(0);
|
||||
|
||||
if (boost::size(range) == 0)
|
||||
{
|
||||
return zero;
|
||||
}
|
||||
|
||||
typedef typename closeable_view<Range const, Closure>::type view_type;
|
||||
|
||||
view_type view(range);
|
||||
|
||||
// line of one point: return point distance
|
||||
typedef typename boost::range_iterator<view_type const>::type iterator_type;
|
||||
iterator_type it = boost::begin(view);
|
||||
iterator_type prev = it++;
|
||||
if (it == boost::end(view))
|
||||
{
|
||||
return pp_strategy.apply(point, *boost::begin(view));
|
||||
}
|
||||
|
||||
// Create comparable (more efficient) strategy
|
||||
typedef typename strategy::distance::services::comparable_type<PSStrategy>::type eps_strategy_type;
|
||||
eps_strategy_type eps_strategy = strategy::distance::services::get_comparable<PSStrategy>::apply(ps_strategy);
|
||||
|
||||
// start with first segment distance
|
||||
return_type d = eps_strategy.apply(point, *prev, *it);
|
||||
return_type rd = ps_strategy.apply(point, *prev, *it);
|
||||
|
||||
// check if other segments are closer
|
||||
for (++prev, ++it; it != boost::end(view); ++prev, ++it)
|
||||
{
|
||||
return_type const ds = ps_strategy.apply(point, *prev, *it);
|
||||
if (geometry::math::equals(ds, zero))
|
||||
{
|
||||
return ds;
|
||||
}
|
||||
else if (ds < d)
|
||||
{
|
||||
d = ds;
|
||||
rd = ps_strategy.apply(point, *prev, *it);
|
||||
}
|
||||
}
|
||||
|
||||
return rd;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename Ring,
|
||||
closure_selector Closure,
|
||||
typename PPStrategy,
|
||||
typename PSStrategy
|
||||
>
|
||||
struct point_to_ring
|
||||
{
|
||||
typedef std::pair
|
||||
<
|
||||
typename return_type<PPStrategy>::type, bool
|
||||
> distance_containment;
|
||||
|
||||
static inline distance_containment apply(Point const& point,
|
||||
Ring const& ring,
|
||||
PPStrategy const& pp_strategy, PSStrategy const& ps_strategy)
|
||||
{
|
||||
return distance_containment
|
||||
(
|
||||
point_to_range
|
||||
<
|
||||
Point,
|
||||
Ring,
|
||||
Closure,
|
||||
PPStrategy,
|
||||
PSStrategy
|
||||
>::apply(point, ring, pp_strategy, ps_strategy),
|
||||
geometry::within(point, ring)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename Polygon,
|
||||
closure_selector Closure,
|
||||
typename PPStrategy,
|
||||
typename PSStrategy
|
||||
>
|
||||
struct point_to_polygon
|
||||
{
|
||||
typedef typename return_type<PPStrategy>::type return_type;
|
||||
typedef std::pair<return_type, bool> distance_containment;
|
||||
|
||||
static inline distance_containment apply(Point const& point,
|
||||
Polygon const& polygon,
|
||||
PPStrategy const& pp_strategy, PSStrategy const& ps_strategy)
|
||||
{
|
||||
// Check distance to all rings
|
||||
typedef point_to_ring
|
||||
<
|
||||
Point,
|
||||
typename ring_type<Polygon>::type,
|
||||
Closure,
|
||||
PPStrategy,
|
||||
PSStrategy
|
||||
> per_ring;
|
||||
|
||||
distance_containment dc = per_ring::apply(point,
|
||||
exterior_ring(polygon), pp_strategy, ps_strategy);
|
||||
|
||||
typename interior_return_type<Polygon const>::type rings
|
||||
= interior_rings(polygon);
|
||||
for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
|
||||
{
|
||||
distance_containment dcr = per_ring::apply(point,
|
||||
*it, pp_strategy, ps_strategy);
|
||||
if (dcr.first < dc.first)
|
||||
{
|
||||
dc.first = dcr.first;
|
||||
}
|
||||
// If it was inside, and also inside inner ring,
|
||||
// turn off the inside-flag, it is outside the polygon
|
||||
if (dc.second && dcr.second)
|
||||
{
|
||||
dc.second = false;
|
||||
}
|
||||
}
|
||||
return dc;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::distance
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
using strategy::distance::services::return_type;
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryTag1, typename GeometryTag2,
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename StrategyTag, typename Strategy
|
||||
>
|
||||
struct distance
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
|
||||
, (types<Geometry1, Geometry2>)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
template <typename P1, typename P2, typename Strategy>
|
||||
struct distance
|
||||
<
|
||||
point_tag, point_tag,
|
||||
P1, P2,
|
||||
strategy_tag_distance_point_point, Strategy
|
||||
>
|
||||
: detail::distance::point_to_point<P1, P2, Strategy>
|
||||
{};
|
||||
|
||||
|
||||
// Point-line version 1, where point-point strategy is specified
|
||||
template <typename Point, typename Linestring, typename Strategy>
|
||||
struct distance
|
||||
<
|
||||
point_tag, linestring_tag,
|
||||
Point, Linestring,
|
||||
strategy_tag_distance_point_point, Strategy
|
||||
>
|
||||
{
|
||||
|
||||
static inline typename return_type<Strategy>::type apply(Point const& point,
|
||||
Linestring const& linestring,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename strategy::distance::services::default_strategy
|
||||
<
|
||||
segment_tag,
|
||||
Point,
|
||||
typename point_type<Linestring>::type
|
||||
>::type ps_strategy_type;
|
||||
|
||||
return detail::distance::point_to_range
|
||||
<
|
||||
Point, Linestring, closed, Strategy, ps_strategy_type
|
||||
>::apply(point, linestring, strategy, ps_strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Point-line version 2, where point-segment strategy is specified
|
||||
template <typename Point, typename Linestring, typename Strategy>
|
||||
struct distance
|
||||
<
|
||||
point_tag, linestring_tag,
|
||||
Point, Linestring,
|
||||
strategy_tag_distance_point_segment, Strategy
|
||||
>
|
||||
{
|
||||
static inline typename return_type<Strategy>::type apply(Point const& point,
|
||||
Linestring const& linestring,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename Strategy::point_strategy_type pp_strategy_type;
|
||||
return detail::distance::point_to_range
|
||||
<
|
||||
Point, Linestring, closed, pp_strategy_type, Strategy
|
||||
>::apply(point, linestring, pp_strategy_type(), strategy);
|
||||
}
|
||||
};
|
||||
|
||||
// Point-ring , where point-segment strategy is specified
|
||||
template <typename Point, typename Ring, typename Strategy>
|
||||
struct distance
|
||||
<
|
||||
point_tag, ring_tag,
|
||||
Point, Ring,
|
||||
strategy_tag_distance_point_point, Strategy
|
||||
>
|
||||
{
|
||||
typedef typename return_type<Strategy>::type return_type;
|
||||
|
||||
static inline return_type apply(Point const& point,
|
||||
Ring const& ring,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename strategy::distance::services::default_strategy
|
||||
<
|
||||
segment_tag,
|
||||
Point,
|
||||
typename point_type<Ring>::type
|
||||
>::type ps_strategy_type;
|
||||
|
||||
std::pair<return_type, bool>
|
||||
dc = detail::distance::point_to_ring
|
||||
<
|
||||
Point, Ring,
|
||||
geometry::closure<Ring>::value,
|
||||
Strategy, ps_strategy_type
|
||||
>::apply(point, ring, strategy, ps_strategy_type());
|
||||
|
||||
return dc.second ? return_type(0) : dc.first;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Point-polygon , where point-segment strategy is specified
|
||||
template <typename Point, typename Polygon, typename Strategy>
|
||||
struct distance
|
||||
<
|
||||
point_tag, polygon_tag,
|
||||
Point, Polygon,
|
||||
strategy_tag_distance_point_point, Strategy
|
||||
>
|
||||
{
|
||||
typedef typename return_type<Strategy>::type return_type;
|
||||
|
||||
static inline return_type apply(Point const& point,
|
||||
Polygon const& polygon,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename strategy::distance::services::default_strategy
|
||||
<
|
||||
segment_tag,
|
||||
Point,
|
||||
typename point_type<Polygon>::type
|
||||
>::type ps_strategy_type;
|
||||
|
||||
std::pair<return_type, bool>
|
||||
dc = detail::distance::point_to_polygon
|
||||
<
|
||||
Point, Polygon,
|
||||
geometry::closure<Polygon>::value,
|
||||
Strategy, ps_strategy_type
|
||||
>::apply(point, polygon, strategy, ps_strategy_type());
|
||||
|
||||
return dc.second ? return_type(0) : dc.first;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Point-segment version 1, with point-point strategy
|
||||
template <typename Point, typename Segment, typename Strategy>
|
||||
struct distance
|
||||
<
|
||||
point_tag, segment_tag,
|
||||
Point, Segment,
|
||||
strategy_tag_distance_point_point, Strategy
|
||||
> : detail::distance::point_to_segment<Point, Segment, Strategy>
|
||||
{};
|
||||
|
||||
// Point-segment version 2, with point-segment strategy
|
||||
template <typename Point, typename Segment, typename Strategy>
|
||||
struct distance
|
||||
<
|
||||
point_tag, segment_tag,
|
||||
Point, Segment,
|
||||
strategy_tag_distance_point_segment, Strategy
|
||||
>
|
||||
{
|
||||
static inline typename return_type<Strategy>::type apply(Point const& point,
|
||||
Segment const& segment, Strategy const& strategy)
|
||||
{
|
||||
|
||||
typename point_type<Segment>::type p[2];
|
||||
geometry::detail::assign_point_from_index<0>(segment, p[0]);
|
||||
geometry::detail::assign_point_from_index<1>(segment, p[1]);
|
||||
return strategy.apply(point, p[0], p[1]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Strictly spoken this might be in namespace <impl> again
|
||||
template
|
||||
<
|
||||
typename GeometryTag1, typename GeometryTag2,
|
||||
typename G1, typename G2,
|
||||
typename StrategyTag, typename Strategy
|
||||
>
|
||||
struct distance_reversed
|
||||
{
|
||||
static inline typename return_type<Strategy>::type apply(G1 const& g1,
|
||||
G2 const& g2, Strategy const& strategy)
|
||||
{
|
||||
return distance
|
||||
<
|
||||
GeometryTag2, GeometryTag1,
|
||||
G2, G1,
|
||||
StrategyTag, Strategy
|
||||
>::apply(g2, g1, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
/*!
|
||||
\brief \brief_calc2{distance} \brief_strategy
|
||||
\ingroup distance
|
||||
\details
|
||||
\details \details_calc{area}. \brief_strategy. \details_strategy_reasons
|
||||
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam Strategy \tparam_strategy{Distance}
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param strategy \param_strategy{distance}
|
||||
\return \return_calc{distance}
|
||||
\note The strategy can be a point-point strategy. In case of distance point-line/point-polygon
|
||||
it may also be a point-segment strategy.
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
|
||||
\qbk{
|
||||
[heading Available Strategies]
|
||||
\* [link geometry.reference.strategies.strategy_distance_pythagoras Pythagoras (cartesian)]
|
||||
\* [link geometry.reference.strategies.strategy_distance_haversine Haversine (spherical)]
|
||||
\* [link geometry.reference.strategies.strategy_distance_cross_track Cross track (spherical\, point-to-segment)]
|
||||
\* [link geometry.reference.strategies.strategy_distance_projected_point Projected point (cartesian\, point-to-segment)]
|
||||
\* more (currently extensions): Vincenty\, Andoyer (geographic)
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
Note, in case of a Compilation Error:
|
||||
if you get:
|
||||
- "Failed to specialize function template ..."
|
||||
- "error: no matching function for call to ..."
|
||||
for distance, it is probably so that there is no specialization
|
||||
for return_type<...> for your strategy.
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
inline typename strategy::distance::services::return_type<Strategy>::type distance(
|
||||
Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2, Strategy const& strategy)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
return boost::mpl::if_
|
||||
<
|
||||
typename geometry::reverse_dispatch<Geometry1, Geometry2>::type,
|
||||
dispatch::distance_reversed
|
||||
<
|
||||
typename tag_cast<typename tag<Geometry1>::type, multi_tag>::type,
|
||||
typename tag_cast<typename tag<Geometry2>::type, multi_tag>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
typename strategy::distance::services::tag<Strategy>::type,
|
||||
Strategy
|
||||
>,
|
||||
dispatch::distance
|
||||
<
|
||||
typename tag_cast<typename tag<Geometry1>::type, multi_tag>::type,
|
||||
typename tag_cast<typename tag<Geometry2>::type, multi_tag>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
typename strategy::distance::services::tag<Strategy>::type,
|
||||
Strategy
|
||||
>
|
||||
>::type::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc2{distance}
|
||||
\ingroup distance
|
||||
\details The default strategy is used, corresponding to the coordinate system of the geometries
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\return \return_calc{distance}
|
||||
|
||||
\qbk{[include reference/algorithms/distance.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline typename default_distance_result<Geometry1, Geometry2>::type distance(
|
||||
Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
typedef typename point_type<Geometry1>::type point1_type;
|
||||
typedef typename point_type<Geometry2>::type point2_type;
|
||||
|
||||
// Define a point-point-distance-strategy
|
||||
// for either the normal case, either the reversed case
|
||||
typedef typename boost::mpl::if_c
|
||||
<
|
||||
geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
|
||||
typename strategy::distance::services::default_strategy
|
||||
<
|
||||
point_tag,
|
||||
point2_type,
|
||||
point1_type
|
||||
>::type,
|
||||
typename strategy::distance::services::default_strategy
|
||||
<
|
||||
point_tag,
|
||||
point1_type,
|
||||
point2_type
|
||||
>::type
|
||||
>::type strategy;
|
||||
|
||||
return distance(geometry1, geometry2, strategy());
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DISTANCE_HPP
|
||||
279
test/external/boost/geometry/algorithms/envelope.hpp
vendored
Normal file
279
test/external/boost/geometry/algorithms/envelope.hpp
vendored
Normal file
@@ -0,0 +1,279 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_ENVELOPE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_ENVELOPE_HPP
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
#include <boost/geometry/algorithms/expand.hpp>
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace envelope
|
||||
{
|
||||
|
||||
|
||||
/// Calculate envelope of an 2D or 3D segment
|
||||
template<typename Geometry, typename Box>
|
||||
struct envelope_expand_one
|
||||
{
|
||||
static inline void apply(Geometry const& geometry, Box& mbr)
|
||||
{
|
||||
assign_inverse(mbr);
|
||||
geometry::expand(mbr, geometry);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// Iterate through range (also used in multi*)
|
||||
template<typename Range, typename Box>
|
||||
inline void envelope_range_additional(Range const& range, Box& mbr)
|
||||
{
|
||||
typedef typename boost::range_iterator<Range const>::type iterator_type;
|
||||
|
||||
for (iterator_type it = boost::begin(range);
|
||||
it != boost::end(range);
|
||||
++it)
|
||||
{
|
||||
geometry::expand(mbr, *it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Generic range dispatching struct
|
||||
template <typename Range, typename Box>
|
||||
struct envelope_range
|
||||
{
|
||||
/// Calculate envelope of range using a strategy
|
||||
static inline void apply(Range const& range, Box& mbr)
|
||||
{
|
||||
assign_inverse(mbr);
|
||||
envelope_range_additional(range, mbr);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::envelope
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
// Note, the strategy is for future use (less/greater -> compare spherical
|
||||
// using other methods), defaults are OK for now.
|
||||
// However, they are already in the template methods
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag1, typename Tag2,
|
||||
typename Geometry, typename Box,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct envelope
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
|
||||
, (types<Geometry>)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Point, typename Box,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct envelope
|
||||
<
|
||||
point_tag, box_tag,
|
||||
Point, Box,
|
||||
StrategyLess, StrategyGreater
|
||||
>
|
||||
: detail::envelope::envelope_expand_one<Point, Box>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename BoxIn, typename BoxOut,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct envelope
|
||||
<
|
||||
box_tag, box_tag,
|
||||
BoxIn, BoxOut,
|
||||
StrategyLess, StrategyGreater
|
||||
>
|
||||
: detail::envelope::envelope_expand_one<BoxIn, BoxOut>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Segment, typename Box,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct envelope
|
||||
<
|
||||
segment_tag, box_tag,
|
||||
Segment, Box,
|
||||
StrategyLess, StrategyGreater
|
||||
>
|
||||
: detail::envelope::envelope_expand_one<Segment, Box>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Linestring, typename Box,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct envelope
|
||||
<
|
||||
linestring_tag, box_tag,
|
||||
Linestring, Box,
|
||||
StrategyLess, StrategyGreater
|
||||
>
|
||||
: detail::envelope::envelope_range<Linestring, Box>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Ring, typename Box,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct envelope
|
||||
<
|
||||
ring_tag, box_tag,
|
||||
Ring, Box,
|
||||
StrategyLess, StrategyGreater
|
||||
>
|
||||
: detail::envelope::envelope_range<Ring, Box>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Polygon, typename Box,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct envelope
|
||||
<
|
||||
polygon_tag, box_tag,
|
||||
Polygon, Box,
|
||||
StrategyLess, StrategyGreater
|
||||
>
|
||||
{
|
||||
static inline void apply(Polygon const& poly, Box& mbr)
|
||||
{
|
||||
// For polygon, inspecting outer ring is sufficient
|
||||
|
||||
detail::envelope::envelope_range
|
||||
<
|
||||
typename ring_type<Polygon>::type,
|
||||
Box
|
||||
>::apply(exterior_ring(poly), mbr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc{envelope}
|
||||
\ingroup envelope
|
||||
\details \details_calc{envelope,\det_envelope}.
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Box \tparam_box
|
||||
\param geometry \param_geometry
|
||||
\param mbr \param_box \param_set{envelope}
|
||||
|
||||
\par Example:
|
||||
Example showing envelope calculation, using point_ll latlong points
|
||||
\dontinclude doxygen_1.cpp
|
||||
\skip example_envelope_polygon
|
||||
\line {
|
||||
\until }
|
||||
|
||||
|
||||
\qbk{
|
||||
[heading Example]
|
||||
[envelope] [envelope_output]
|
||||
}
|
||||
*/
|
||||
template<typename Geometry, typename Box>
|
||||
inline void envelope(Geometry const& geometry, Box& mbr)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
concept::check<Box>();
|
||||
|
||||
dispatch::envelope
|
||||
<
|
||||
typename tag<Geometry>::type, typename tag<Box>::type,
|
||||
Geometry, Box,
|
||||
void, void
|
||||
>::apply(geometry, mbr);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc{envelope}
|
||||
\ingroup envelope
|
||||
\details \details_calc{return_envelope,\det_envelope}. \details_return{envelope}
|
||||
\tparam Box \tparam_box
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry
|
||||
\return \return_calc{envelope}
|
||||
|
||||
\qbk{
|
||||
[heading Example]
|
||||
[return_envelope] [return_envelope_output]
|
||||
}
|
||||
*/
|
||||
template<typename Box, typename Geometry>
|
||||
inline Box return_envelope(Geometry const& geometry)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
concept::check<Box>();
|
||||
|
||||
Box mbr;
|
||||
dispatch::envelope
|
||||
<
|
||||
typename tag<Geometry>::type, typename tag<Box>::type,
|
||||
Geometry, Box,
|
||||
void, void
|
||||
>::apply(geometry, mbr);
|
||||
return mbr;
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_ENVELOPE_HPP
|
||||
319
test/external/boost/geometry/algorithms/equals.hpp
vendored
Normal file
319
test/external/boost/geometry/algorithms/equals.hpp
vendored
Normal file
@@ -0,0 +1,319 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_EQUALS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_EQUALS_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/reverse_dispatch.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/disjoint.hpp>
|
||||
#include <boost/geometry/algorithms/detail/not.hpp>
|
||||
|
||||
// For trivial checks
|
||||
#include <boost/geometry/algorithms/area.hpp>
|
||||
#include <boost/geometry/algorithms/length.hpp>
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
#include <boost/geometry/util/select_coordinate_type.hpp>
|
||||
#include <boost/geometry/util/select_most_precise.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/equals/collect_vectors.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace equals
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1,
|
||||
typename Box2,
|
||||
std::size_t Dimension,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct box_box
|
||||
{
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2)
|
||||
{
|
||||
if (!geometry::math::equals(get<min_corner, Dimension>(box1), get<min_corner, Dimension>(box2))
|
||||
|| !geometry::math::equals(get<max_corner, Dimension>(box1), get<max_corner, Dimension>(box2)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return box_box<Box1, Box2, Dimension + 1, DimensionCount>::apply(box1, box2);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box1, typename Box2, std::size_t DimensionCount>
|
||||
struct box_box<Box1, Box2, DimensionCount, DimensionCount>
|
||||
{
|
||||
static inline bool apply(Box1 const& , Box2 const& )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct area_check
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
return geometry::math::equals(
|
||||
geometry::area(geometry1),
|
||||
geometry::area(geometry2));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct length_check
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
return geometry::math::equals(
|
||||
geometry::length(geometry1),
|
||||
geometry::length(geometry2));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename TrivialCheck>
|
||||
struct equals_by_collection
|
||||
{
|
||||
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
if (! TrivialCheck::apply(geometry1, geometry2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef typename geometry::select_most_precise
|
||||
<
|
||||
typename select_coordinate_type
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::type,
|
||||
double
|
||||
>::type calculation_type;
|
||||
|
||||
typedef std::vector<collected_vector<calculation_type> > v;
|
||||
v c1, c2;
|
||||
|
||||
geometry::collect_vectors(c1, geometry1);
|
||||
geometry::collect_vectors(c2, geometry2);
|
||||
|
||||
if (boost::size(c1) != boost::size(c2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::sort(c1.begin(), c1.end());
|
||||
std::sort(c2.begin(), c2.end());
|
||||
|
||||
// Just check if these vectors are equal.
|
||||
return std::equal(c1.begin(), c1.end(), c2.begin());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::equals
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag1, typename Tag2,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct equals
|
||||
{};
|
||||
|
||||
|
||||
template <typename P1, typename P2, std::size_t DimensionCount>
|
||||
struct equals<point_tag, point_tag, P1, P2, DimensionCount>
|
||||
: geometry::detail::not_
|
||||
<
|
||||
P1,
|
||||
P2,
|
||||
detail::disjoint::point_point<P1, P2, 0, DimensionCount>
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Box1, typename Box2, std::size_t DimensionCount>
|
||||
struct equals<box_tag, box_tag, Box1, Box2, DimensionCount>
|
||||
: detail::equals::box_box<Box1, Box2, 0, DimensionCount>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Ring1, typename Ring2>
|
||||
struct equals<ring_tag, ring_tag, Ring1, Ring2, 2>
|
||||
: detail::equals::equals_by_collection
|
||||
<
|
||||
Ring1, Ring2,
|
||||
detail::equals::area_check
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon1, typename Polygon2>
|
||||
struct equals<polygon_tag, polygon_tag, Polygon1, Polygon2, 2>
|
||||
: detail::equals::equals_by_collection
|
||||
<
|
||||
Polygon1, Polygon2,
|
||||
detail::equals::area_check
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template <typename LineString1, typename LineString2>
|
||||
struct equals<linestring_tag, linestring_tag, LineString1, LineString2, 2>
|
||||
: detail::equals::equals_by_collection
|
||||
<
|
||||
LineString1, LineString2,
|
||||
detail::equals::length_check
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename Ring>
|
||||
struct equals<polygon_tag, ring_tag, Polygon, Ring, 2>
|
||||
: detail::equals::equals_by_collection
|
||||
<
|
||||
Polygon, Ring,
|
||||
detail::equals::area_check
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Ring, typename Box>
|
||||
struct equals<ring_tag, box_tag, Ring, Box, 2>
|
||||
: detail::equals::equals_by_collection
|
||||
<
|
||||
Ring, Box,
|
||||
detail::equals::area_check
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename Box>
|
||||
struct equals<polygon_tag, box_tag, Polygon, Box, 2>
|
||||
: detail::equals::equals_by_collection
|
||||
<
|
||||
Polygon, Box,
|
||||
detail::equals::area_check
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag1, typename Tag2,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct equals_reversed
|
||||
{
|
||||
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
|
||||
{
|
||||
return equals
|
||||
<
|
||||
Tag2, Tag1,
|
||||
Geometry2, Geometry1,
|
||||
DimensionCount
|
||||
>::apply(g2, g1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check{are spatially equal}
|
||||
\details \details_check12{equals, is spatially equal}. Spatially equal means
|
||||
that the same point set is included. A box can therefore be spatially equal
|
||||
to a ring or a polygon, or a linestring can be spatially equal to a
|
||||
multi-linestring or a segment. This only theoretically, not all combinations
|
||||
are implemented yet.
|
||||
\ingroup equals
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\return \return_check2{are spatially equal}
|
||||
|
||||
\qbk{[include reference/algorithms/equals.qbk]}
|
||||
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline bool equals(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
concept::check_concepts_and_equal_dimensions
|
||||
<
|
||||
Geometry1 const,
|
||||
Geometry2 const
|
||||
>();
|
||||
|
||||
return boost::mpl::if_c
|
||||
<
|
||||
reverse_dispatch<Geometry1, Geometry2>::type::value,
|
||||
dispatch::equals_reversed
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
dimension<Geometry1>::type::value
|
||||
>,
|
||||
dispatch::equals
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
dimension<Geometry1>::type::value
|
||||
>
|
||||
>::type::apply(geometry1, geometry2);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_EQUALS_HPP
|
||||
|
||||
319
test/external/boost/geometry/algorithms/expand.hpp
vendored
Normal file
319
test/external/boost/geometry/algorithms/expand.hpp
vendored
Normal file
@@ -0,0 +1,319 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/util/select_coordinate_type.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/compare.hpp>
|
||||
#include <boost/geometry/policies/compare.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace expand
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Box, typename Point,
|
||||
typename StrategyLess, typename StrategyGreater,
|
||||
std::size_t Dimension, std::size_t DimensionCount
|
||||
>
|
||||
struct point_loop
|
||||
{
|
||||
typedef typename strategy::compare::detail::select_strategy
|
||||
<
|
||||
StrategyLess, 1, Point, Dimension
|
||||
>::type less_type;
|
||||
|
||||
typedef typename strategy::compare::detail::select_strategy
|
||||
<
|
||||
StrategyGreater, -1, Point, Dimension
|
||||
>::type greater_type;
|
||||
|
||||
typedef typename select_coordinate_type<Point, Box>::type coordinate_type;
|
||||
|
||||
static inline void apply(Box& box, Point const& source)
|
||||
{
|
||||
less_type less;
|
||||
greater_type greater;
|
||||
|
||||
coordinate_type const coord = get<Dimension>(source);
|
||||
|
||||
if (less(coord, get<min_corner, Dimension>(box)))
|
||||
{
|
||||
set<min_corner, Dimension>(box, coord);
|
||||
}
|
||||
|
||||
if (greater(coord, get<max_corner, Dimension>(box)))
|
||||
{
|
||||
set<max_corner, Dimension>(box, coord);
|
||||
}
|
||||
|
||||
point_loop
|
||||
<
|
||||
Box, Point,
|
||||
StrategyLess, StrategyGreater,
|
||||
Dimension + 1, DimensionCount
|
||||
>::apply(box, source);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Box, typename Point,
|
||||
typename StrategyLess, typename StrategyGreater,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct point_loop
|
||||
<
|
||||
Box, Point,
|
||||
StrategyLess, StrategyGreater,
|
||||
DimensionCount, DimensionCount
|
||||
>
|
||||
{
|
||||
static inline void apply(Box&, Point const&) {}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Box, typename Geometry,
|
||||
typename StrategyLess, typename StrategyGreater,
|
||||
std::size_t Index,
|
||||
std::size_t Dimension, std::size_t DimensionCount
|
||||
>
|
||||
struct indexed_loop
|
||||
{
|
||||
typedef typename strategy::compare::detail::select_strategy
|
||||
<
|
||||
StrategyLess, 1, Box, Dimension
|
||||
>::type less_type;
|
||||
|
||||
typedef typename strategy::compare::detail::select_strategy
|
||||
<
|
||||
StrategyGreater, -1, Box, Dimension
|
||||
>::type greater_type;
|
||||
|
||||
typedef typename select_coordinate_type
|
||||
<
|
||||
Box,
|
||||
Geometry
|
||||
>::type coordinate_type;
|
||||
|
||||
|
||||
static inline void apply(Box& box, Geometry const& source)
|
||||
{
|
||||
less_type less;
|
||||
greater_type greater;
|
||||
|
||||
coordinate_type const coord = get<Index, Dimension>(source);
|
||||
|
||||
if (less(coord, get<min_corner, Dimension>(box)))
|
||||
{
|
||||
set<min_corner, Dimension>(box, coord);
|
||||
}
|
||||
|
||||
if (greater(coord, get<max_corner, Dimension>(box)))
|
||||
{
|
||||
set<max_corner, Dimension>(box, coord);
|
||||
}
|
||||
|
||||
indexed_loop
|
||||
<
|
||||
Box, Geometry,
|
||||
StrategyLess, StrategyGreater,
|
||||
Index, Dimension + 1, DimensionCount
|
||||
>::apply(box, source);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Box, typename Geometry,
|
||||
typename StrategyLess, typename StrategyGreater,
|
||||
std::size_t Index, std::size_t DimensionCount
|
||||
>
|
||||
struct indexed_loop
|
||||
<
|
||||
Box, Geometry,
|
||||
StrategyLess, StrategyGreater,
|
||||
Index, DimensionCount, DimensionCount
|
||||
>
|
||||
{
|
||||
static inline void apply(Box&, Geometry const&) {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Changes a box such that the other box is also contained by the box
|
||||
template
|
||||
<
|
||||
typename Box, typename Geometry,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct expand_indexed
|
||||
{
|
||||
static inline void apply(Box& box, Geometry const& geometry)
|
||||
{
|
||||
indexed_loop
|
||||
<
|
||||
Box, Geometry,
|
||||
StrategyLess, StrategyGreater,
|
||||
0, 0, dimension<Geometry>::type::value
|
||||
>::apply(box, geometry);
|
||||
|
||||
indexed_loop
|
||||
<
|
||||
Box, Geometry,
|
||||
StrategyLess, StrategyGreater,
|
||||
1, 0, dimension<Geometry>::type::value
|
||||
>::apply(box, geometry);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::expand
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag,
|
||||
typename BoxOut, typename Geometry,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct expand
|
||||
{};
|
||||
|
||||
|
||||
// Box + point -> new box containing also point
|
||||
template
|
||||
<
|
||||
typename BoxOut, typename Point,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct expand<point_tag, BoxOut, Point, StrategyLess, StrategyGreater>
|
||||
: detail::expand::point_loop
|
||||
<
|
||||
BoxOut, Point,
|
||||
StrategyLess, StrategyGreater,
|
||||
0, dimension<Point>::type::value
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
// Box + box -> new box containing two input boxes
|
||||
template
|
||||
<
|
||||
typename BoxOut, typename BoxIn,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct expand<box_tag, BoxOut, BoxIn, StrategyLess, StrategyGreater>
|
||||
: detail::expand::expand_indexed
|
||||
<BoxOut, BoxIn, StrategyLess, StrategyGreater>
|
||||
{};
|
||||
|
||||
template
|
||||
<
|
||||
typename Box, typename Segment,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct expand<segment_tag, Box, Segment, StrategyLess, StrategyGreater>
|
||||
: detail::expand::expand_indexed
|
||||
<Box, Segment, StrategyLess, StrategyGreater>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/***
|
||||
*!
|
||||
\brief Expands a box using the extend (envelope) of another geometry (box, point)
|
||||
\ingroup expand
|
||||
\tparam Box type of the box
|
||||
\tparam Geometry of second geometry, to be expanded with the box
|
||||
\param box box to expand another geometry with, might be changed
|
||||
\param geometry other geometry
|
||||
\param strategy_less
|
||||
\param strategy_greater
|
||||
\note Strategy is currently ignored
|
||||
*
|
||||
template
|
||||
<
|
||||
typename Box, typename Geometry,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
inline void expand(Box& box, Geometry const& geometry,
|
||||
StrategyLess const& strategy_less,
|
||||
StrategyGreater const& strategy_greater)
|
||||
{
|
||||
concept::check_concepts_and_equal_dimensions<Box, Geometry const>();
|
||||
|
||||
dispatch::expand
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Box,
|
||||
Geometry,
|
||||
StrategyLess, StrategyGreater
|
||||
>::apply(box, geometry);
|
||||
}
|
||||
***/
|
||||
|
||||
|
||||
/*!
|
||||
\brief Expands a box using the bounding box (envelope) of another geometry (box, point)
|
||||
\ingroup expand
|
||||
\tparam Box type of the box
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param box box to be expanded using another geometry, mutable
|
||||
\param geometry \param_geometry geometry which envelope (bounding box) will be added to the box
|
||||
|
||||
\qbk{[include reference/algorithms/expand.qbk]}
|
||||
*/
|
||||
template <typename Box, typename Geometry>
|
||||
inline void expand(Box& box, Geometry const& geometry)
|
||||
{
|
||||
concept::check_concepts_and_equal_dimensions<Box, Geometry const>();
|
||||
|
||||
dispatch::expand
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Box, Geometry,
|
||||
strategy::compare::default_strategy,
|
||||
strategy::compare::default_strategy
|
||||
>::apply(box, geometry);
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP
|
||||
351
test/external/boost/geometry/algorithms/for_each.hpp
vendored
Normal file
351
test/external/boost/geometry/algorithms/for_each.hpp
vendored
Normal file
@@ -0,0 +1,351 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_FOR_EACH_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_FOR_EACH_HPP
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/tag_cast.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/segment.hpp>
|
||||
|
||||
#include <boost/geometry/util/add_const_if_c.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace for_each
|
||||
{
|
||||
|
||||
|
||||
template <typename Point, typename Functor, bool IsConst>
|
||||
struct fe_point_per_point
|
||||
{
|
||||
static inline Functor apply(
|
||||
typename add_const_if_c<IsConst, Point>::type& point, Functor f)
|
||||
{
|
||||
f(point);
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Point, typename Functor, bool IsConst>
|
||||
struct fe_point_per_segment
|
||||
{
|
||||
static inline Functor apply(
|
||||
typename add_const_if_c<IsConst, Point>::type& point, Functor f)
|
||||
{
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Range, typename Functor, bool IsConst>
|
||||
struct fe_range_per_point
|
||||
{
|
||||
static inline Functor apply(
|
||||
typename add_const_if_c<IsConst, Range>::type& range,
|
||||
Functor f)
|
||||
{
|
||||
return (std::for_each(boost::begin(range), boost::end(range), f));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Range, typename Functor, bool IsConst>
|
||||
struct fe_range_per_segment
|
||||
{
|
||||
static inline Functor apply(
|
||||
typename add_const_if_c<IsConst, Range>::type& range,
|
||||
Functor f)
|
||||
{
|
||||
typedef typename add_const_if_c
|
||||
<
|
||||
IsConst,
|
||||
typename point_type<Range>::type
|
||||
>::type point_type;
|
||||
|
||||
BOOST_AUTO_TPL(it, boost::begin(range));
|
||||
BOOST_AUTO_TPL(previous, it++);
|
||||
while(it != boost::end(range))
|
||||
{
|
||||
model::referring_segment<point_type> s(*previous, *it);
|
||||
f(s);
|
||||
previous = it++;
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Polygon, typename Functor, bool IsConst>
|
||||
struct fe_polygon_per_point
|
||||
{
|
||||
typedef typename add_const_if_c<IsConst, Polygon>::type poly_type;
|
||||
|
||||
static inline Functor apply(poly_type& poly, Functor f)
|
||||
{
|
||||
typedef fe_range_per_point
|
||||
<
|
||||
typename ring_type<Polygon>::type,
|
||||
Functor,
|
||||
IsConst
|
||||
> per_ring;
|
||||
|
||||
f = per_ring::apply(exterior_ring(poly), f);
|
||||
|
||||
typename interior_return_type<poly_type>::type rings
|
||||
= interior_rings(poly);
|
||||
for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
|
||||
{
|
||||
f = per_ring::apply(*it, f);
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <typename Polygon, typename Functor, bool IsConst>
|
||||
struct fe_polygon_per_segment
|
||||
{
|
||||
typedef typename add_const_if_c<IsConst, Polygon>::type poly_type;
|
||||
|
||||
static inline Functor apply(poly_type& poly, Functor f)
|
||||
{
|
||||
typedef fe_range_per_segment
|
||||
<
|
||||
typename ring_type<Polygon>::type,
|
||||
Functor,
|
||||
IsConst
|
||||
> per_ring;
|
||||
|
||||
f = per_ring::apply(exterior_ring(poly), f);
|
||||
|
||||
typename interior_return_type<poly_type>::type rings
|
||||
= interior_rings(poly);
|
||||
for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
|
||||
{
|
||||
f = per_ring::apply(*it, f);
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::for_each
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag,
|
||||
typename Geometry,
|
||||
typename Functor,
|
||||
bool IsConst
|
||||
>
|
||||
struct for_each_point {};
|
||||
|
||||
|
||||
template <typename Point, typename Functor, bool IsConst>
|
||||
struct for_each_point<point_tag, Point, Functor, IsConst>
|
||||
: detail::for_each::fe_point_per_point<Point, Functor, IsConst>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Linestring, typename Functor, bool IsConst>
|
||||
struct for_each_point<linestring_tag, Linestring, Functor, IsConst>
|
||||
: detail::for_each::fe_range_per_point<Linestring, Functor, IsConst>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Ring, typename Functor, bool IsConst>
|
||||
struct for_each_point<ring_tag, Ring, Functor, IsConst>
|
||||
: detail::for_each::fe_range_per_point<Ring, Functor, IsConst>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename Functor, bool IsConst>
|
||||
struct for_each_point<polygon_tag, Polygon, Functor, IsConst>
|
||||
: detail::for_each::fe_polygon_per_point<Polygon, Functor, IsConst>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag,
|
||||
typename Geometry,
|
||||
typename Functor,
|
||||
bool IsConst
|
||||
>
|
||||
struct for_each_segment {};
|
||||
|
||||
template <typename Point, typename Functor, bool IsConst>
|
||||
struct for_each_segment<point_tag, Point, Functor, IsConst>
|
||||
: detail::for_each::fe_point_per_segment<Point, Functor, IsConst>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Linestring, typename Functor, bool IsConst>
|
||||
struct for_each_segment<linestring_tag, Linestring, Functor, IsConst>
|
||||
: detail::for_each::fe_range_per_segment<Linestring, Functor, IsConst>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Ring, typename Functor, bool IsConst>
|
||||
struct for_each_segment<ring_tag, Ring, Functor, IsConst>
|
||||
: detail::for_each::fe_range_per_segment<Ring, Functor, IsConst>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename Functor, bool IsConst>
|
||||
struct for_each_segment<polygon_tag, Polygon, Functor, IsConst>
|
||||
: detail::for_each::fe_polygon_per_segment<Polygon, Functor, IsConst>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brf_for_each{point}
|
||||
\details \det_for_each{point}
|
||||
\ingroup for_each
|
||||
\param geometry \param_geometry
|
||||
\param f \par_for_each_f{const point}
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Functor \tparam_functor
|
||||
|
||||
\qbk{distinguish,const version}
|
||||
\qbk{[heading Example]}
|
||||
\qbk{[for_each_point_const] [for_each_point_const_output]}
|
||||
*/
|
||||
template<typename Geometry, typename Functor>
|
||||
inline Functor for_each_point(Geometry const& geometry, Functor f)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
return dispatch::for_each_point
|
||||
<
|
||||
typename tag_cast<typename tag<Geometry>::type, multi_tag>::type,
|
||||
Geometry,
|
||||
Functor,
|
||||
true
|
||||
>::apply(geometry, f);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brf_for_each{point}
|
||||
\details \det_for_each{point}
|
||||
\ingroup for_each
|
||||
\param geometry \param_geometry
|
||||
\param f \par_for_each_f{point}
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Functor \tparam_functor
|
||||
|
||||
\qbk{[heading Example]}
|
||||
\qbk{[for_each_point] [for_each_point_output]}
|
||||
*/
|
||||
template<typename Geometry, typename Functor>
|
||||
inline Functor for_each_point(Geometry& geometry, Functor f)
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
return dispatch::for_each_point
|
||||
<
|
||||
typename tag_cast<typename tag<Geometry>::type, multi_tag>::type,
|
||||
Geometry,
|
||||
Functor,
|
||||
false
|
||||
>::apply(geometry, f);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brf_for_each{segment}
|
||||
\details \det_for_each{segment}
|
||||
\ingroup for_each
|
||||
\param geometry \param_geometry
|
||||
\param f \par_for_each_f{const segment}
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Functor \tparam_functor
|
||||
|
||||
\qbk{distinguish,const version}
|
||||
\qbk{[heading Example]}
|
||||
\qbk{[for_each_segment_const] [for_each_segment_const_output]}
|
||||
*/
|
||||
template<typename Geometry, typename Functor>
|
||||
inline Functor for_each_segment(Geometry const& geometry, Functor f)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
return dispatch::for_each_segment
|
||||
<
|
||||
typename tag_cast<typename tag<Geometry>::type, multi_tag>::type,
|
||||
Geometry,
|
||||
Functor,
|
||||
true
|
||||
>::apply(geometry, f);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brf_for_each{segment}
|
||||
\details \det_for_each{segment}
|
||||
\ingroup for_each
|
||||
\param geometry \param_geometry
|
||||
\param f \par_for_each_f{segment}
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Functor \tparam_functor
|
||||
*/
|
||||
template<typename Geometry, typename Functor>
|
||||
inline Functor for_each_segment(Geometry& geometry, Functor f)
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
return dispatch::for_each_segment
|
||||
<
|
||||
typename tag_cast<typename tag<Geometry>::type, multi_tag>::type,
|
||||
Geometry,
|
||||
Functor,
|
||||
false
|
||||
>::apply(geometry, f);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_FOR_EACH_HPP
|
||||
237
test/external/boost/geometry/algorithms/intersection.hpp
vendored
Normal file
237
test/external/boost/geometry/algorithms/intersection.hpp
vendored
Normal file
@@ -0,0 +1,237 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_INTERSECTION_HPP
|
||||
#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/intersects.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace intersection
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1, typename Box2,
|
||||
typename BoxOut,
|
||||
typename Strategy,
|
||||
std::size_t Dimension, std::size_t DimensionCount
|
||||
>
|
||||
struct intersection_box_box
|
||||
{
|
||||
static inline bool apply(Box1 const& box1,
|
||||
Box2 const& box2, BoxOut& box_out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename coordinate_type<BoxOut>::type ct;
|
||||
|
||||
ct min1 = get<min_corner, Dimension>(box1);
|
||||
ct min2 = get<min_corner, Dimension>(box2);
|
||||
ct max1 = get<max_corner, Dimension>(box1);
|
||||
ct max2 = get<max_corner, Dimension>(box2);
|
||||
|
||||
if (max1 < min2 || max2 < min1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Set dimensions of output coordinate
|
||||
set<min_corner, Dimension>(box_out, min1 < min2 ? min2 : min1);
|
||||
set<max_corner, Dimension>(box_out, max1 > max2 ? max2 : max1);
|
||||
|
||||
return intersection_box_box
|
||||
<
|
||||
Box1, Box2, BoxOut, Strategy,
|
||||
Dimension + 1, DimensionCount
|
||||
>::apply(box1, box2, box_out, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1, typename Box2,
|
||||
typename BoxOut,
|
||||
typename Strategy,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct intersection_box_box<Box1, Box2, BoxOut, Strategy, DimensionCount, DimensionCount>
|
||||
{
|
||||
static inline bool apply(Box1 const&, Box2 const&, BoxOut&, Strategy const&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::intersection
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
// By default, all is forwarded to the intersection_insert-dispatcher
|
||||
template
|
||||
<
|
||||
typename Tag1, typename Tag2, typename TagOut,
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename GeometryOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection
|
||||
{
|
||||
typedef std::back_insert_iterator<GeometryOut> output_iterator;
|
||||
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
GeometryOut& geometry_out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename boost::range_value<GeometryOut>::type OneOut;
|
||||
|
||||
intersection_insert
|
||||
<
|
||||
Tag1, Tag2, typename geometry::tag<OneOut>::type,
|
||||
geometry::is_areal<Geometry1>::value,
|
||||
geometry::is_areal<Geometry2>::value,
|
||||
geometry::is_areal<OneOut>::value,
|
||||
Geometry1, Geometry2,
|
||||
detail::overlay::do_reverse<geometry::point_order<Geometry1>::value, false>::value,
|
||||
detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, false>::value,
|
||||
detail::overlay::do_reverse<geometry::point_order<OneOut>::value>::value,
|
||||
output_iterator, OneOut,
|
||||
overlay_intersection,
|
||||
Strategy
|
||||
>::apply(geometry1, geometry2, std::back_inserter(geometry_out), strategy);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1, typename Box2,
|
||||
typename BoxOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection
|
||||
<
|
||||
box_tag, box_tag, box_tag,
|
||||
Box1, Box2, BoxOut,
|
||||
Strategy
|
||||
> : public detail::intersection::intersection_box_box
|
||||
<
|
||||
Box1, Box2, BoxOut,
|
||||
Strategy,
|
||||
0, geometry::dimension<Box1>::value
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag1, typename Tag2, typename TagOut,
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename GeometryOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_reversed
|
||||
{
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
GeometryOut& geometry_out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return intersection
|
||||
<
|
||||
Tag2, Tag1, TagOut,
|
||||
Geometry2, Geometry1,
|
||||
GeometryOut, Strategy
|
||||
>::apply(geometry2, geometry1, geometry_out, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\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)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
typedef strategy_intersection
|
||||
<
|
||||
typename cs_tag<Geometry1>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
typename geometry::point_type<Geometry1>::type
|
||||
> strategy;
|
||||
|
||||
|
||||
return boost::mpl::if_c
|
||||
<
|
||||
geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
|
||||
dispatch::intersection_reversed
|
||||
<
|
||||
typename geometry::tag<Geometry1>::type,
|
||||
typename geometry::tag<Geometry2>::type,
|
||||
typename geometry::tag<GeometryOut>::type,
|
||||
Geometry1, Geometry2, GeometryOut, strategy
|
||||
>,
|
||||
dispatch::intersection
|
||||
<
|
||||
typename geometry::tag<Geometry1>::type,
|
||||
typename geometry::tag<Geometry2>::type,
|
||||
typename geometry::tag<GeometryOut>::type,
|
||||
Geometry1, Geometry2, GeometryOut, strategy
|
||||
>
|
||||
>::type::apply(geometry1, geometry2, geometry_out, strategy());
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_INTERSECTION_HPP
|
||||
105
test/external/boost/geometry/algorithms/intersects.hpp
vendored
Normal file
105
test/external/boost/geometry/algorithms/intersects.hpp
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_INTERSECTS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_INTERSECTS_HPP
|
||||
|
||||
|
||||
#include <deque>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
|
||||
#include <boost/geometry/algorithms/disjoint.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
/*!
|
||||
\brief \brief_check{has at least one intersection (crossing or self-tangency)}
|
||||
\note This function can be called for one geometry (self-intersection) and
|
||||
also for two geometries (intersection)
|
||||
\ingroup intersects
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry
|
||||
\return \return_check{is self-intersecting}
|
||||
|
||||
\qbk{distinguish,one geometry}
|
||||
\qbk{[include reference/algorithms/intersects.qbk]}
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline bool intersects(Geometry const& geometry)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
|
||||
typedef detail::overlay::turn_info
|
||||
<
|
||||
typename geometry::point_type<Geometry>::type
|
||||
> turn_info;
|
||||
std::deque<turn_info> turns;
|
||||
|
||||
typedef typename strategy_intersection
|
||||
<
|
||||
typename cs_tag<Geometry>::type,
|
||||
Geometry,
|
||||
Geometry,
|
||||
typename geometry::point_type<Geometry>::type
|
||||
>::segment_intersection_strategy_type segment_intersection_strategy_type;
|
||||
|
||||
typedef detail::overlay::get_turn_info
|
||||
<
|
||||
typename point_type<Geometry>::type,
|
||||
typename point_type<Geometry>::type,
|
||||
turn_info,
|
||||
detail::overlay::assign_null_policy
|
||||
> TurnPolicy;
|
||||
|
||||
detail::disjoint::disjoint_interrupt_policy policy;
|
||||
detail::self_get_turn_points::get_turns
|
||||
<
|
||||
Geometry,
|
||||
std::deque<turn_info>,
|
||||
TurnPolicy,
|
||||
detail::disjoint::disjoint_interrupt_policy
|
||||
>::apply(geometry, turns, policy);
|
||||
return policy.has_intersections;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check2{have at least one intersection}
|
||||
\ingroup intersects
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\return \return_check2{intersect each other}
|
||||
|
||||
\qbk{distinguish,two geometries}
|
||||
\qbk{[include reference/algorithms/intersects.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline bool intersects(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
return ! geometry::disjoint(geometry1, geometry2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_INTERSECTS_HPP
|
||||
199
test/external/boost/geometry/algorithms/length.hpp
vendored
Normal file
199
test/external/boost/geometry/algorithms/length.hpp
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_LENGTH_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_LENGTH_HPP
|
||||
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
#include <boost/geometry/algorithms/detail/calculate_null.hpp>
|
||||
#include <boost/geometry/views/closeable_view.hpp>
|
||||
#include <boost/geometry/strategies/distance.hpp>
|
||||
#include <boost/geometry/strategies/default_length_result.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace length
|
||||
{
|
||||
|
||||
|
||||
template<typename Segment, typename Strategy>
|
||||
struct segment_length
|
||||
{
|
||||
static inline typename default_length_result<Segment>::type apply(
|
||||
Segment const& segment, Strategy const& strategy)
|
||||
{
|
||||
typedef typename point_type<Segment>::type point_type;
|
||||
point_type p1, p2;
|
||||
geometry::detail::assign_point_from_index<0>(segment, p1);
|
||||
geometry::detail::assign_point_from_index<1>(segment, p2);
|
||||
return strategy.apply(p1, p2);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief Internal, calculates length of a linestring using iterator pairs and
|
||||
specified strategy
|
||||
\note for_each could be used here, now that point_type is changed by boost
|
||||
range iterator
|
||||
*/
|
||||
template<typename Range, typename Strategy, closure_selector Closure>
|
||||
struct range_length
|
||||
{
|
||||
typedef typename default_length_result<Range>::type return_type;
|
||||
|
||||
static inline return_type apply(
|
||||
Range const& range, Strategy const& strategy)
|
||||
{
|
||||
typedef typename closeable_view<Range const, Closure>::type view_type;
|
||||
typedef typename boost::range_iterator
|
||||
<
|
||||
view_type const
|
||||
>::type iterator_type;
|
||||
|
||||
return_type sum = return_type();
|
||||
view_type view(range);
|
||||
iterator_type it = boost::begin(view), end = boost::end(view);
|
||||
if(it != end)
|
||||
{
|
||||
for(iterator_type previous = it++;
|
||||
it != end;
|
||||
++previous, ++it)
|
||||
{
|
||||
// Add point-point distance using the return type belonging
|
||||
// to strategy
|
||||
sum += strategy.apply(*previous, *it);
|
||||
}
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::length
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename Tag, typename Geometry, typename Strategy>
|
||||
struct length : detail::calculate_null
|
||||
<
|
||||
typename default_length_result<Geometry>::type,
|
||||
Geometry,
|
||||
Strategy
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Geometry, typename Strategy>
|
||||
struct length<linestring_tag, Geometry, Strategy>
|
||||
: detail::length::range_length<Geometry, Strategy, closed>
|
||||
{};
|
||||
|
||||
|
||||
// RING: length is currently 0; it might be argued that it is the "perimeter"
|
||||
|
||||
|
||||
template <typename Geometry, typename Strategy>
|
||||
struct length<segment_tag, Geometry, Strategy>
|
||||
: detail::length::segment_length<Geometry, Strategy>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc{length}
|
||||
\ingroup length
|
||||
\details \details_calc{length, length (the sum of distances between consecutive points)}. \details_default_strategy
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry
|
||||
\return \return_calc{length}
|
||||
|
||||
\qbk{[include reference/algorithms/length.qbk]}
|
||||
\qbk{[length] [length_output]}
|
||||
*/
|
||||
template<typename Geometry>
|
||||
inline typename default_length_result<Geometry>::type length(
|
||||
Geometry const& geometry)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
typedef typename strategy::distance::services::default_strategy
|
||||
<
|
||||
point_tag, typename point_type<Geometry>::type
|
||||
>::type strategy_type;
|
||||
|
||||
return dispatch::length
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
strategy_type
|
||||
>::apply(geometry, strategy_type());
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc{length} \brief_strategy
|
||||
\ingroup length
|
||||
\details \details_calc{length, length (the sum of distances between consecutive points)} \brief_strategy. \details_strategy_reasons
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Strategy \tparam_strategy{distance}
|
||||
\param geometry \param_geometry
|
||||
\param strategy \param_strategy{distance}
|
||||
\return \return_calc{length}
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{[include reference/algorithms/length.qbk]}
|
||||
\qbk{[length_with_strategy] [length_with_strategy_output]}
|
||||
*/
|
||||
template<typename Geometry, typename Strategy>
|
||||
inline typename default_length_result<Geometry>::type length(
|
||||
Geometry const& geometry, Strategy const& strategy)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
return dispatch::length
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
Strategy
|
||||
>::apply(geometry, strategy);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_LENGTH_HPP
|
||||
200
test/external/boost/geometry/algorithms/make.hpp
vendored
Normal file
200
test/external/boost/geometry/algorithms/make.hpp
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_MAKE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_MAKE_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace make
|
||||
{
|
||||
|
||||
/*!
|
||||
\brief Construct a geometry
|
||||
\ingroup make
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Range \tparam_range_point
|
||||
\param range \param_range_point
|
||||
\return The constructed geometry, here: a linestring or a ring
|
||||
|
||||
\qbk{distinguish, with a range}
|
||||
\qbk{
|
||||
[heading Example]
|
||||
[make_with_range] [make_with_range_output]
|
||||
|
||||
[heading See also]
|
||||
\* [link geometry.reference.algorithms.assign.assign_points assign]
|
||||
}
|
||||
*/
|
||||
template <typename Geometry, typename Range>
|
||||
inline Geometry make_points(Range const& range)
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
Geometry geometry;
|
||||
geometry::append(geometry, range);
|
||||
return geometry;
|
||||
}
|
||||
|
||||
}} // namespace detail::make
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
/*!
|
||||
\brief Construct a geometry
|
||||
\ingroup make
|
||||
\details
|
||||
\note It does not work with array-point types, like int[2]
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Type \tparam_numeric to specify the coordinates
|
||||
\param c1 \param_x
|
||||
\param c2 \param_y
|
||||
\return The constructed geometry, here: a 2D point
|
||||
|
||||
\qbk{distinguish, 2 coordinate values}
|
||||
\qbk{
|
||||
[heading Example]
|
||||
[make_2d_point] [make_2d_point_output]
|
||||
|
||||
[heading See also]
|
||||
\* [link geometry.reference.algorithms.assign.assign_values_3_2_coordinate_values assign]
|
||||
}
|
||||
*/
|
||||
template <typename Geometry, typename Type>
|
||||
inline Geometry make(Type const& c1, Type const& c2)
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
Geometry geometry;
|
||||
dispatch::assign
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
geometry::dimension<Geometry>::type::value
|
||||
>::apply(geometry, c1, c2);
|
||||
return geometry;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Construct a geometry
|
||||
\ingroup make
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Type \tparam_numeric to specify the coordinates
|
||||
\param c1 \param_x
|
||||
\param c2 \param_y
|
||||
\param c3 \param_z
|
||||
\return The constructed geometry, here: a 3D point
|
||||
|
||||
\qbk{distinguish, 3 coordinate values}
|
||||
\qbk{
|
||||
[heading Example]
|
||||
[make_3d_point] [make_3d_point_output]
|
||||
|
||||
[heading See also]
|
||||
\* [link geometry.reference.algorithms.assign.assign_values_4_3_coordinate_values assign]
|
||||
}
|
||||
*/
|
||||
template <typename Geometry, typename Type>
|
||||
inline Geometry make(Type const& c1, Type const& c2, Type const& c3)
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
Geometry geometry;
|
||||
dispatch::assign
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
geometry::dimension<Geometry>::type::value
|
||||
>::apply(geometry, c1, c2, c3);
|
||||
return geometry;
|
||||
}
|
||||
|
||||
template <typename Geometry, typename Type>
|
||||
inline Geometry make(Type const& c1, Type const& c2, Type const& c3, Type const& c4)
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
Geometry geometry;
|
||||
dispatch::assign
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
geometry::dimension<Geometry>::type::value
|
||||
>::apply(geometry, c1, c2, c3, c4);
|
||||
return geometry;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Construct a box with inverse infinite coordinates
|
||||
\ingroup make
|
||||
\details The make_inverse function initializes a 2D or 3D box with large coordinates, the
|
||||
min corner is very large, the max corner is very small. This is useful e.g. in combination
|
||||
with the expand function, to determine the bounding box of a series of geometries.
|
||||
\tparam Geometry \tparam_geometry
|
||||
\return The constructed geometry, here: a box
|
||||
|
||||
\qbk{
|
||||
[heading Example]
|
||||
[make_inverse] [make_inverse_output]
|
||||
|
||||
[heading See also]
|
||||
\* [link geometry.reference.algorithms.assign.assign_inverse assign_inverse]
|
||||
}
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline Geometry make_inverse()
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
Geometry geometry;
|
||||
dispatch::assign_inverse
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry
|
||||
>::apply(geometry);
|
||||
return geometry;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Construct a geometry with its coordinates initialized to zero
|
||||
\ingroup make
|
||||
\details The make_zero function initializes a 2D or 3D point or box with coordinates of zero
|
||||
\tparam Geometry \tparam_geometry
|
||||
\return The constructed and zero-initialized geometry
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline Geometry make_zero()
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
Geometry geometry;
|
||||
dispatch::assign_zero
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry
|
||||
>::apply(geometry);
|
||||
return geometry;
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_MAKE_HPP
|
||||
95
test/external/boost/geometry/algorithms/num_geometries.hpp
vendored
Normal file
95
test/external/boost/geometry/algorithms/num_geometries.hpp
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_NUM_GEOMETRIES_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_NUM_GEOMETRIES_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/core/tag_cast.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename Tag, typename Geometry>
|
||||
struct num_geometries
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
|
||||
, (types<Geometry>)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_geometries<single_tag, Geometry>
|
||||
{
|
||||
static inline std::size_t apply(Geometry const&)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc{number of geometries}
|
||||
\ingroup num_geometries
|
||||
\details \details_calc{num_geometries, number of geometries}.
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry
|
||||
\return \return_calc{number of geometries}
|
||||
|
||||
\qbk{[include reference/algorithms/num_geometries.qbk]}
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline std::size_t num_geometries(Geometry const& geometry)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
return dispatch::num_geometries
|
||||
<
|
||||
typename tag_cast
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
single_tag,
|
||||
multi_tag
|
||||
>::type,
|
||||
Geometry
|
||||
>::apply(geometry);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_NUM_GEOMETRIES_HPP
|
||||
88
test/external/boost/geometry/algorithms/num_interior_rings.hpp
vendored
Normal file
88
test/external/boost/geometry/algorithms/num_interior_rings.hpp
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_NUM_INTERIOR_RINGS_HPP
|
||||
#define BOOST_GEOMETRY_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/core/interior_rings.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename Tag, typename Geometry>
|
||||
struct num_interior_rings
|
||||
{
|
||||
static inline std::size_t apply(Geometry const& )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename Polygon>
|
||||
struct num_interior_rings<polygon_tag, Polygon>
|
||||
{
|
||||
static inline std::size_t apply(Polygon const& polygon)
|
||||
{
|
||||
return boost::size(geometry::interior_rings(polygon));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc{number of interior rings}
|
||||
\ingroup num_interior_rings
|
||||
\details \details_calc{num_interior_rings, number of interior rings}.
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry
|
||||
\return \return_calc{number of interior rings}
|
||||
|
||||
\qbk{[include reference/algorithms/num_interior_rings.qbk]}
|
||||
|
||||
\note Defined by OGC as "numInteriorRing". To be consistent with "numPoints"
|
||||
letter "s" is appended
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline std::size_t num_interior_rings(Geometry const& geometry)
|
||||
{
|
||||
return dispatch::num_interior_rings
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry
|
||||
>::apply(geometry);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_NUM_INTERIOR_RINGS_HPP
|
||||
171
test/external/boost/geometry/algorithms/num_points.hpp
vendored
Normal file
171
test/external/boost/geometry/algorithms/num_points.hpp
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_NUM_POINTS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_NUM_POINTS_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/typeof/typeof.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/ring_type.hpp>
|
||||
#include <boost/geometry/core/tag_cast.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/disjoint.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace num_points
|
||||
{
|
||||
|
||||
|
||||
template <typename Range>
|
||||
struct range_count
|
||||
{
|
||||
static inline std::size_t apply(Range const& range, bool add_for_open)
|
||||
{
|
||||
std::size_t n = boost::size(range);
|
||||
if (add_for_open && n > 0)
|
||||
{
|
||||
closure_selector const s = geometry::closure<Range>::value;
|
||||
|
||||
if (s == open)
|
||||
{
|
||||
if (geometry::disjoint(*boost::begin(range), *(boost::begin(range) + n - 1)))
|
||||
{
|
||||
return n + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry, std::size_t D>
|
||||
struct other_count
|
||||
{
|
||||
static inline std::size_t apply(Geometry const&, bool)
|
||||
{
|
||||
return D;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Polygon>
|
||||
struct polygon_count
|
||||
{
|
||||
static inline std::size_t apply(Polygon const& poly, bool add_for_open)
|
||||
{
|
||||
typedef typename geometry::ring_type<Polygon>::type ring_type;
|
||||
|
||||
std::size_t n = range_count<ring_type>::apply(
|
||||
exterior_ring(poly), add_for_open);
|
||||
|
||||
typename interior_return_type<Polygon const>::type rings
|
||||
= interior_rings(poly);
|
||||
for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
|
||||
{
|
||||
n += range_count<ring_type>::apply(*it, add_for_open);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::num_points
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template <typename GeometryTag, typename Geometry>
|
||||
struct num_points
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
|
||||
, (types<Geometry>)
|
||||
);
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_points<point_tag, Geometry>
|
||||
: detail::num_points::other_count<Geometry, 1>
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_points<box_tag, Geometry>
|
||||
: detail::num_points::other_count<Geometry, 4>
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_points<segment_tag, Geometry>
|
||||
: detail::num_points::other_count<Geometry, 2>
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_points<linestring_tag, Geometry>
|
||||
: detail::num_points::range_count<Geometry>
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_points<ring_tag, Geometry>
|
||||
: detail::num_points::range_count<Geometry>
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_points<polygon_tag, Geometry>
|
||||
: detail::num_points::polygon_count<Geometry>
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc{number of points}
|
||||
\ingroup num_points
|
||||
\details \details_calc{num_points, number of points}.
|
||||
\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 points}
|
||||
|
||||
\qbk{[include reference/algorithms/num_points.qbk]}
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline std::size_t num_points(Geometry const& geometry, bool add_for_open = false)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
return dispatch::num_points
|
||||
<
|
||||
typename tag_cast<typename tag<Geometry>::type, multi_tag>::type,
|
||||
Geometry
|
||||
>::apply(geometry, add_for_open);
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_NUM_POINTS_HPP
|
||||
200
test/external/boost/geometry/algorithms/overlaps.hpp
vendored
Normal file
200
test/external/boost/geometry/algorithms/overlaps.hpp
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_OVERLAPS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_OVERLAPS_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlaps
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1,
|
||||
typename Box2,
|
||||
std::size_t Dimension,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct box_box_loop
|
||||
{
|
||||
static inline void apply(Box1 const& b1, Box2 const& b2,
|
||||
bool& overlaps, bool& one_in_two, bool& two_in_one)
|
||||
{
|
||||
assert_dimension_equal<Box1, Box2>();
|
||||
|
||||
typedef typename coordinate_type<Box1>::type coordinate_type1;
|
||||
typedef typename coordinate_type<Box2>::type coordinate_type2;
|
||||
|
||||
coordinate_type1 const& min1 = get<min_corner, Dimension>(b1);
|
||||
coordinate_type1 const& max1 = get<max_corner, Dimension>(b1);
|
||||
coordinate_type2 const& min2 = get<min_corner, Dimension>(b2);
|
||||
coordinate_type2 const& max2 = get<max_corner, Dimension>(b2);
|
||||
|
||||
// We might use the (not yet accepted) Boost.Interval
|
||||
// submission in the future
|
||||
|
||||
// If:
|
||||
// B1: |-------|
|
||||
// B2: |------|
|
||||
// in any dimension -> no overlap
|
||||
if (max1 <= min2 || min1 >= max2)
|
||||
{
|
||||
overlaps = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// If:
|
||||
// B1: |--------------------|
|
||||
// B2: |-------------|
|
||||
// in all dimensions -> within, then no overlap
|
||||
// B1: |--------------------|
|
||||
// B2: |-------------|
|
||||
// this is "within-touch" -> then no overlap. So use < and >
|
||||
if (min1 < min2 || max1 > max2)
|
||||
{
|
||||
one_in_two = false;
|
||||
}
|
||||
// Same other way round
|
||||
if (min2 < min1 || max2 > max1)
|
||||
{
|
||||
two_in_one = false;
|
||||
}
|
||||
|
||||
box_box_loop
|
||||
<
|
||||
Box1,
|
||||
Box2,
|
||||
Dimension + 1,
|
||||
DimensionCount
|
||||
>::apply(b1, b2, overlaps, one_in_two, two_in_one);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1,
|
||||
typename Box2,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct box_box_loop<Box1, Box2, DimensionCount, DimensionCount>
|
||||
{
|
||||
static inline void apply(Box1 const& , Box2 const&, bool&, bool&, bool&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1,
|
||||
typename Box2
|
||||
>
|
||||
struct box_box
|
||||
{
|
||||
static inline bool apply(Box1 const& b1, Box2 const& b2)
|
||||
{
|
||||
bool overlaps = true;
|
||||
bool within1 = true;
|
||||
bool within2 = true;
|
||||
box_box_loop
|
||||
<
|
||||
Box1,
|
||||
Box2,
|
||||
0,
|
||||
dimension<Box1>::type::value
|
||||
>::apply(b1, b2, overlaps, within1, within2);
|
||||
|
||||
/*
|
||||
\see http://docs.codehaus.org/display/GEOTDOC/02+Geometry+Relationships#02GeometryRelationships-Overlaps
|
||||
where is stated that "inside" is not an "overlap",
|
||||
this is true and is implemented as such.
|
||||
*/
|
||||
return overlaps && ! within1 && ! within2;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
}} // namespace detail::overlaps
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
//struct not_implemented_for_this_geometry_type : public boost::false_type {};
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag1,
|
||||
typename Tag2,
|
||||
typename Geometry1,
|
||||
typename Geometry2
|
||||
>
|
||||
struct overlaps
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
|
||||
, (types<Geometry1, Geometry2>)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
template <typename Box1, typename Box2>
|
||||
struct overlaps<box_tag, box_tag, Box1, Box2>
|
||||
: detail::overlaps::box_box<Box1, Box2>
|
||||
{};
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check2{overlap}
|
||||
\ingroup overlaps
|
||||
\return \return_check2{overlap}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline bool overlaps(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
return dispatch::overlaps
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply(geometry1, geometry2);
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_OVERLAPS_HPP
|
||||
139
test/external/boost/geometry/algorithms/perimeter.hpp
vendored
Normal file
139
test/external/boost/geometry/algorithms/perimeter.hpp
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_PERIMETER_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_PERIMETER_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/strategies/default_length_result.hpp>
|
||||
#include <boost/geometry/algorithms/length.hpp>
|
||||
#include <boost/geometry/algorithms/detail/calculate_null.hpp>
|
||||
#include <boost/geometry/algorithms/detail/calculate_sum.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
// Default perimeter is 0.0, specializations implement calculated values
|
||||
template <typename Tag, typename Geometry, typename Strategy>
|
||||
struct perimeter : detail::calculate_null
|
||||
<
|
||||
typename default_length_result<Geometry>::type,
|
||||
Geometry,
|
||||
Strategy
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename Geometry, typename Strategy>
|
||||
struct perimeter<ring_tag, Geometry, Strategy>
|
||||
: detail::length::range_length
|
||||
<
|
||||
Geometry,
|
||||
Strategy,
|
||||
closure<Geometry>::value
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename Polygon, typename Strategy>
|
||||
struct perimeter<polygon_tag, Polygon, Strategy>
|
||||
: detail::calculate_polygon_sum
|
||||
<
|
||||
typename default_length_result<Polygon>::type,
|
||||
Polygon,
|
||||
Strategy,
|
||||
detail::length::range_length
|
||||
<
|
||||
typename ring_type<Polygon>::type,
|
||||
Strategy,
|
||||
closure<Polygon>::value
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
// box,n-sphere: to be implemented
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc{perimeter}
|
||||
\ingroup perimeter
|
||||
\details The function perimeter returns the perimeter of a geometry,
|
||||
using the default distance-calculation-strategy
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry
|
||||
\return \return_calc{perimeter}
|
||||
|
||||
\qbk{[include reference/algorithms/perimeter.qbk]}
|
||||
*/
|
||||
template<typename Geometry>
|
||||
inline typename default_length_result<Geometry>::type perimeter(
|
||||
Geometry const& geometry)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
typedef typename point_type<Geometry>::type point_type;
|
||||
typedef typename strategy::distance::services::default_strategy
|
||||
<
|
||||
point_tag, point_type
|
||||
>::type strategy_type;
|
||||
|
||||
return dispatch::perimeter
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
strategy_type
|
||||
>::apply(geometry, strategy_type());
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief \brief_calc{perimeter} \brief_strategy
|
||||
\ingroup perimeter
|
||||
\details The function perimeter returns the perimeter of a geometry,
|
||||
using specified strategy
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Strategy \tparam_strategy{distance}
|
||||
\param geometry \param_geometry
|
||||
\param strategy strategy to be used for distance calculations.
|
||||
\return \return_calc{perimeter}
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{[include reference/algorithms/perimeter.qbk]}
|
||||
*/
|
||||
template<typename Geometry, typename Strategy>
|
||||
inline typename default_length_result<Geometry>::type perimeter(
|
||||
Geometry const& geometry, Strategy const& strategy)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
return dispatch::perimeter
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
Strategy
|
||||
>::apply(geometry, strategy);
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_PERIMETER_HPP
|
||||
|
||||
134
test/external/boost/geometry/algorithms/reverse.hpp
vendored
Normal file
134
test/external/boost/geometry/algorithms/reverse.hpp
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_REVERSE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_REVERSE_HPP
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace reverse
|
||||
{
|
||||
|
||||
|
||||
template <typename Range>
|
||||
struct range_reverse
|
||||
{
|
||||
static inline void apply(Range& range)
|
||||
{
|
||||
std::reverse(boost::begin(range), boost::end(range));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Polygon>
|
||||
struct polygon_reverse
|
||||
{
|
||||
static inline void apply(Polygon& polygon)
|
||||
{
|
||||
typedef typename geometry::ring_type<Polygon>::type ring_type;
|
||||
|
||||
typedef range_reverse<ring_type> per_range;
|
||||
per_range::apply(exterior_ring(polygon));
|
||||
|
||||
typename interior_return_type<Polygon>::type rings
|
||||
= interior_rings(polygon);
|
||||
for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
|
||||
{
|
||||
per_range::apply(*it);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::reverse
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag,
|
||||
typename Geometry
|
||||
>
|
||||
struct reverse
|
||||
{
|
||||
static inline void apply(Geometry&)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
template <typename Ring>
|
||||
struct reverse<ring_tag, Ring>
|
||||
: detail::reverse::range_reverse<Ring>
|
||||
{};
|
||||
|
||||
|
||||
template <typename LineString>
|
||||
struct reverse<linestring_tag, LineString>
|
||||
: detail::reverse::range_reverse<LineString>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon>
|
||||
struct reverse<polygon_tag, Polygon>
|
||||
: detail::reverse::polygon_reverse<Polygon>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
\brief Reverses the points within a geometry
|
||||
\details Generic function to reverse a geometry. It resembles the std::reverse
|
||||
functionality, but it takes the geometry type into account. Only for a ring
|
||||
or for a linestring it is the same as the std::reverse.
|
||||
\ingroup reverse
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry which will be reversed
|
||||
|
||||
\qbk{[include reference/algorithms/reverse.qbk]}
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline void reverse(Geometry& geometry)
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
dispatch::reverse
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry
|
||||
>::apply(geometry);
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_REVERSE_HPP
|
||||
405
test/external/boost/geometry/algorithms/simplify.hpp
vendored
Normal file
405
test/external/boost/geometry/algorithms/simplify.hpp
vendored
Normal file
@@ -0,0 +1,405 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_SIMPLIFY_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_SIMPLIFY_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/ring_type.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/mutable_range.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/strategies/agnostic/simplify_douglas_peucker.hpp>
|
||||
#include <boost/geometry/strategies/concepts/simplify_concept.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/clear.hpp>
|
||||
#include <boost/geometry/algorithms/convert.hpp>
|
||||
#include <boost/geometry/algorithms/num_interior_rings.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace simplify
|
||||
{
|
||||
|
||||
template<typename Range, typename Strategy>
|
||||
struct simplify_range_insert
|
||||
{
|
||||
template <typename OutputIterator, typename Distance>
|
||||
static inline void apply(Range const& range, OutputIterator out,
|
||||
Distance const& max_distance, Strategy const& strategy)
|
||||
{
|
||||
if (boost::size(range) <= 2 || max_distance < 0)
|
||||
{
|
||||
std::copy(boost::begin(range), boost::end(range), out);
|
||||
}
|
||||
else
|
||||
{
|
||||
strategy.apply(range, out, max_distance);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename Range, typename Strategy>
|
||||
struct simplify_copy
|
||||
{
|
||||
template <typename Distance>
|
||||
static inline void apply(Range const& range, Range& out,
|
||||
Distance const& max_distance, Strategy const& strategy)
|
||||
{
|
||||
std::copy
|
||||
(
|
||||
boost::begin(range), boost::end(range), std::back_inserter(out)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename Range, typename Strategy, std::size_t Minimum>
|
||||
struct simplify_range
|
||||
{
|
||||
template <typename Distance>
|
||||
static inline void apply(Range const& range, Range& out,
|
||||
Distance const& max_distance, Strategy const& strategy)
|
||||
{
|
||||
// Call do_container for a linestring / ring
|
||||
|
||||
/* For a RING:
|
||||
The first/last point (the closing point of the ring) should maybe
|
||||
be excluded because it lies on a line with second/one but last.
|
||||
Here it is never excluded.
|
||||
|
||||
Note also that, especially if max_distance is too large,
|
||||
the output ring might be self intersecting while the input ring is
|
||||
not, although chances are low in normal polygons
|
||||
|
||||
Finally the inputring might have 3 (open) or 4 (closed) points (=correct),
|
||||
the output < 3 or 4(=wrong)
|
||||
*/
|
||||
|
||||
if (boost::size(range) <= int(Minimum) || max_distance < 0.0)
|
||||
{
|
||||
simplify_copy<Range, Strategy>::apply
|
||||
(
|
||||
range, out, max_distance, strategy
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
simplify_range_insert<Range, Strategy>::apply
|
||||
(
|
||||
range, std::back_inserter(out), max_distance, strategy
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Polygon, typename Strategy>
|
||||
struct simplify_polygon
|
||||
{
|
||||
template <typename Distance>
|
||||
static inline void apply(Polygon const& poly_in, Polygon& poly_out,
|
||||
Distance const& max_distance, Strategy const& strategy)
|
||||
{
|
||||
typedef typename ring_type<Polygon>::type ring_type;
|
||||
|
||||
int const Minimum = core_detail::closure::minimum_ring_size
|
||||
<
|
||||
geometry::closure<Polygon>::value
|
||||
>::value;
|
||||
|
||||
// Note that if there are inner rings, and distance is too large,
|
||||
// they might intersect with the outer ring in the output,
|
||||
// while it didn't in the input.
|
||||
simplify_range<ring_type, Strategy, Minimum>::apply(exterior_ring(poly_in),
|
||||
exterior_ring(poly_out),
|
||||
max_distance, strategy);
|
||||
|
||||
traits::resize
|
||||
<
|
||||
typename boost::remove_reference
|
||||
<
|
||||
typename traits::interior_mutable_type<Polygon>::type
|
||||
>::type
|
||||
>::apply(interior_rings(poly_out), num_interior_rings(poly_in));
|
||||
|
||||
typename interior_return_type<Polygon const>::type rings_in
|
||||
= interior_rings(poly_in);
|
||||
typename interior_return_type<Polygon>::type rings_out
|
||||
= interior_rings(poly_out);
|
||||
BOOST_AUTO_TPL(it_out, boost::begin(rings_out));
|
||||
for (BOOST_AUTO_TPL(it_in, boost::begin(rings_in));
|
||||
it_in != boost::end(rings_in);
|
||||
++it_in, ++it_out)
|
||||
{
|
||||
simplify_range<ring_type, Strategy, Minimum>::apply(*it_in,
|
||||
*it_out, max_distance, strategy);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::simplify
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template <typename Tag, typename Geometry, typename Strategy>
|
||||
struct simplify
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Point, typename Strategy>
|
||||
struct simplify<point_tag, Point, Strategy>
|
||||
{
|
||||
template <typename Distance>
|
||||
static inline void apply(Point const& point, Point& out,
|
||||
Distance const& max_distance, Strategy const& strategy)
|
||||
{
|
||||
geometry::convert(point, out);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Linestring, typename Strategy>
|
||||
struct simplify<linestring_tag, Linestring, Strategy>
|
||||
: detail::simplify::simplify_range
|
||||
<
|
||||
Linestring,
|
||||
Strategy,
|
||||
2
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename Ring, typename Strategy>
|
||||
struct simplify<ring_tag, Ring, Strategy>
|
||||
: detail::simplify::simplify_range
|
||||
<
|
||||
Ring,
|
||||
Strategy,
|
||||
core_detail::closure::minimum_ring_size
|
||||
<
|
||||
geometry::closure<Ring>::value
|
||||
>::value
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename Polygon, typename Strategy>
|
||||
struct simplify<polygon_tag, Polygon, Strategy>
|
||||
: detail::simplify::simplify_polygon
|
||||
<
|
||||
Polygon,
|
||||
Strategy
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Tag, typename Geometry, typename Strategy>
|
||||
struct simplify_insert
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
template <typename Linestring, typename Strategy>
|
||||
struct simplify_insert<linestring_tag, Linestring, Strategy>
|
||||
: detail::simplify::simplify_range_insert
|
||||
<
|
||||
Linestring,
|
||||
Strategy
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename Ring, typename Strategy>
|
||||
struct simplify_insert<ring_tag, Ring, Strategy>
|
||||
: detail::simplify::simplify_range_insert
|
||||
<
|
||||
Ring,
|
||||
Strategy
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief Simplify a geometry using a specified strategy
|
||||
\ingroup simplify
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Distance A numerical distance measure
|
||||
\tparam Strategy A type fulfilling a SimplifyStrategy concept
|
||||
\param strategy A strategy to calculate simplification
|
||||
\param geometry input geometry, to be simplified
|
||||
\param out output geometry, simplified version of the input geometry
|
||||
\param max_distance distance (in units of input coordinates) of a vertex
|
||||
to other segments to be removed
|
||||
\param strategy simplify strategy to be used for simplification, might
|
||||
include point-distance strategy
|
||||
|
||||
\image html svg_simplify_country.png "The image below presents the simplified country"
|
||||
\qbk{distinguish,with strategy}
|
||||
*/
|
||||
template<typename Geometry, typename Distance, typename Strategy>
|
||||
inline void simplify(Geometry const& geometry, Geometry& out,
|
||||
Distance const& max_distance, Strategy const& strategy)
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
BOOST_CONCEPT_ASSERT( (geometry::concept::SimplifyStrategy<Strategy>) );
|
||||
|
||||
geometry::clear(out);
|
||||
|
||||
dispatch::simplify
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
Strategy
|
||||
>::apply(geometry, out, max_distance, strategy);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Simplify a geometry
|
||||
\ingroup simplify
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Distance \tparam_numeric
|
||||
\note This version of simplify simplifies a geometry using the default
|
||||
strategy (Douglas Peucker),
|
||||
\param geometry input geometry, to be simplified
|
||||
\param out output geometry, simplified version of the input geometry
|
||||
\param max_distance distance (in units of input coordinates) of a vertex
|
||||
to other segments to be removed
|
||||
|
||||
\qbk{[include reference/algorithms/simplify.qbk]}
|
||||
*/
|
||||
template<typename Geometry, typename Distance>
|
||||
inline void simplify(Geometry const& geometry, Geometry& out,
|
||||
Distance const& max_distance)
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
typedef typename point_type<Geometry>::type point_type;
|
||||
typedef typename strategy::distance::services::default_strategy
|
||||
<
|
||||
segment_tag, point_type
|
||||
>::type ds_strategy_type;
|
||||
|
||||
typedef strategy::simplify::douglas_peucker
|
||||
<
|
||||
point_type, ds_strategy_type
|
||||
> strategy_type;
|
||||
|
||||
simplify(geometry, out, max_distance, strategy_type());
|
||||
}
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace simplify
|
||||
{
|
||||
|
||||
|
||||
/*!
|
||||
\brief Simplify a geometry, using an output iterator
|
||||
and a specified strategy
|
||||
\ingroup simplify
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry input geometry, to be simplified
|
||||
\param out output iterator, outputs all simplified points
|
||||
\param max_distance distance (in units of input coordinates) of a vertex
|
||||
to other segments to be removed
|
||||
\param strategy simplify strategy to be used for simplification,
|
||||
might include point-distance strategy
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{[include reference/algorithms/simplify.qbk]}
|
||||
*/
|
||||
template<typename Geometry, typename OutputIterator, typename Distance, typename Strategy>
|
||||
inline void simplify_insert(Geometry const& geometry, OutputIterator out,
|
||||
Distance const& max_distance, Strategy const& strategy)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
BOOST_CONCEPT_ASSERT( (geometry::concept::SimplifyStrategy<Strategy>) );
|
||||
|
||||
dispatch::simplify_insert
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
Strategy
|
||||
>::apply(geometry, out, max_distance, strategy);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Simplify a geometry, using an output iterator
|
||||
\ingroup simplify
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry input geometry, to be simplified
|
||||
\param out output iterator, outputs all simplified points
|
||||
\param max_distance distance (in units of input coordinates) of a vertex
|
||||
to other segments to be removed
|
||||
|
||||
\qbk{[include reference/algorithms/simplify_insert.qbk]}
|
||||
*/
|
||||
template<typename Geometry, typename OutputIterator, typename Distance>
|
||||
inline void simplify_insert(Geometry const& geometry, OutputIterator out,
|
||||
Distance const& max_distance)
|
||||
{
|
||||
typedef typename point_type<Geometry>::type point_type;
|
||||
|
||||
// Concept: output point type = point type of input geometry
|
||||
concept::check<Geometry const>();
|
||||
concept::check<point_type>();
|
||||
|
||||
typedef typename strategy::distance::services::default_strategy
|
||||
<
|
||||
segment_tag, point_type
|
||||
>::type ds_strategy_type;
|
||||
|
||||
typedef strategy::simplify::douglas_peucker
|
||||
<
|
||||
point_type, ds_strategy_type
|
||||
> strategy_type;
|
||||
|
||||
dispatch::simplify_insert
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
strategy_type
|
||||
>::apply(geometry, out, max_distance, strategy_type());
|
||||
}
|
||||
|
||||
}} // namespace detail::simplify
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_SIMPLIFY_HPP
|
||||
149
test/external/boost/geometry/algorithms/sym_difference.hpp
vendored
Normal file
149
test/external/boost/geometry/algorithms/sym_difference.hpp
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
#include <boost/geometry/algorithms/intersection.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace sym_difference
|
||||
{
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc2{symmetric difference} \brief_strategy
|
||||
\ingroup sym_difference
|
||||
\details \details_calc2{symmetric difference, spatial set theoretic symmetric difference (XOR)}
|
||||
\brief_strategy. \details_insert{sym_difference}
|
||||
\tparam GeometryOut output geometry type, must be specified
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam Strategy \tparam_strategy_overlay
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param out \param_out{difference}
|
||||
\param strategy \param_strategy{difference}
|
||||
\return \return_out
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename GeometryOut,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename OutputIterator,
|
||||
typename Strategy
|
||||
>
|
||||
inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2, OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
concept::check<GeometryOut>();
|
||||
|
||||
out = detail::intersection::insert<GeometryOut, true, overlay_difference>(
|
||||
geometry1, geometry2, out, strategy);
|
||||
out = detail::intersection::insert<GeometryOut, true, overlay_difference>(
|
||||
geometry2, geometry1, out, strategy);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc2{symmetric difference}
|
||||
\ingroup sym_difference
|
||||
\details \details_calc2{symmetric difference, spatial set theoretic symmetric difference (XOR)}
|
||||
\details_insert{sym_difference}
|
||||
\tparam GeometryOut output geometry type, must be specified
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param out \param_out{difference}
|
||||
\return \return_out
|
||||
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename GeometryOut,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename OutputIterator
|
||||
>
|
||||
inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2, OutputIterator out)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
concept::check<GeometryOut>();
|
||||
|
||||
typedef strategy_intersection
|
||||
<
|
||||
typename cs_tag<GeometryOut>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
typename geometry::point_type<GeometryOut>::type
|
||||
> strategy_type;
|
||||
|
||||
return sym_difference_insert<GeometryOut>(geometry1, geometry2, out, strategy_type());
|
||||
}
|
||||
|
||||
}} // namespace detail::sym_difference
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc2{symmetric difference}
|
||||
\ingroup sym_difference
|
||||
\details \details_calc2{symmetric difference, spatial set theoretic symmetric difference (XOR)}.
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam Collection output collection, either a multi-geometry,
|
||||
or a std::vector<Geometry> / std::deque<Geometry> etc
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param output_collection the output collection
|
||||
|
||||
\qbk{[include reference/algorithms/sym_difference.qbk]}
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Collection
|
||||
>
|
||||
inline void sym_difference(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2, Collection& output_collection)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
typedef typename boost::range_value<Collection>::type geometry_out;
|
||||
concept::check<geometry_out>();
|
||||
|
||||
detail::sym_difference::sym_difference_insert<geometry_out>(
|
||||
geometry1, geometry2,
|
||||
std::back_inserter(output_collection));
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP
|
||||
351
test/external/boost/geometry/algorithms/transform.hpp
vendored
Normal file
351
test/external/boost/geometry/algorithms/transform.hpp
vendored
Normal file
@@ -0,0 +1,351 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_TRANSFORM_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_TRANSFORM_HPP
|
||||
|
||||
#include <cmath>
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
#include <boost/geometry/algorithms/clear.hpp>
|
||||
#include <boost/geometry/algorithms/num_interior_rings.hpp>
|
||||
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/mutable_range.hpp>
|
||||
#include <boost/geometry/core/ring_type.hpp>
|
||||
#include <boost/geometry/core/tag_cast.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/strategies/transform.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace transform
|
||||
{
|
||||
|
||||
template <typename Point1, typename Point2, typename Strategy>
|
||||
struct transform_point
|
||||
{
|
||||
static inline bool apply(Point1 const& p1, Point2& p2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return strategy.apply(p1, p2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Box1, typename Box2, typename Strategy>
|
||||
struct transform_box
|
||||
{
|
||||
static inline bool apply(Box1 const& b1, Box2& b2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename point_type<Box1>::type point_type1;
|
||||
typedef typename point_type<Box2>::type point_type2;
|
||||
|
||||
point_type1 lower_left, upper_right;
|
||||
detail::assign::assign_box_2d_corner<min_corner, min_corner>(
|
||||
b1, lower_left);
|
||||
detail::assign::assign_box_2d_corner<max_corner, max_corner>(
|
||||
b1, upper_right);
|
||||
|
||||
point_type2 p1, p2;
|
||||
if (strategy.apply(lower_left, p1) && strategy.apply(upper_right, p2))
|
||||
{
|
||||
// Create a valid box and therefore swap if necessary
|
||||
typedef typename coordinate_type<point_type2>::type coordinate_type;
|
||||
coordinate_type x1 = geometry::get<0>(p1)
|
||||
, y1 = geometry::get<1>(p1)
|
||||
, x2 = geometry::get<0>(p2)
|
||||
, y2 = geometry::get<1>(p2);
|
||||
|
||||
if (x1 > x2) { std::swap(x1, x2); }
|
||||
if (y1 > y2) { std::swap(y1, y2); }
|
||||
|
||||
set<min_corner, 0>(b2, x1);
|
||||
set<min_corner, 1>(b2, y1);
|
||||
set<max_corner, 0>(b2, x2);
|
||||
set<max_corner, 1>(b2, y2);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
struct transform_box_or_segment
|
||||
{
|
||||
static inline bool apply(Geometry1 const& source, Geometry2& target,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename point_type<Geometry1>::type point_type1;
|
||||
typedef typename point_type<Geometry2>::type point_type2;
|
||||
|
||||
point_type1 source_point[2];
|
||||
geometry::detail::assign_point_from_index<0>(source, source_point[0]);
|
||||
geometry::detail::assign_point_from_index<1>(source, source_point[1]);
|
||||
|
||||
point_type2 target_point[2];
|
||||
if (strategy.apply(source_point[0], target_point[0])
|
||||
&& strategy.apply(source_point[1], target_point[1]))
|
||||
{
|
||||
geometry::detail::assign_point_to_index<0>(target_point[0], target);
|
||||
geometry::detail::assign_point_to_index<1>(target_point[1], target);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename PointOut,
|
||||
typename OutputIterator,
|
||||
typename Range,
|
||||
typename Strategy
|
||||
>
|
||||
inline bool transform_range_out(Range const& range,
|
||||
OutputIterator out, Strategy const& strategy)
|
||||
{
|
||||
PointOut point_out;
|
||||
for(typename boost::range_iterator<Range const>::type
|
||||
it = boost::begin(range);
|
||||
it != boost::end(range);
|
||||
++it)
|
||||
{
|
||||
if (! transform_point
|
||||
<
|
||||
typename point_type<Range>::type,
|
||||
PointOut,
|
||||
Strategy
|
||||
>::apply(*it, point_out, strategy))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*out++ = point_out;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template <typename Polygon1, typename Polygon2, typename Strategy>
|
||||
struct transform_polygon
|
||||
{
|
||||
static inline bool apply(Polygon1 const& poly1, Polygon2& poly2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename ring_type<Polygon1>::type ring1_type;
|
||||
typedef typename ring_type<Polygon2>::type ring2_type;
|
||||
typedef typename point_type<Polygon2>::type point2_type;
|
||||
|
||||
geometry::clear(poly2);
|
||||
|
||||
if (!transform_range_out<point2_type>(exterior_ring(poly1),
|
||||
std::back_inserter(exterior_ring(poly2)), strategy))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Note: here a resizeable container is assumed.
|
||||
traits::resize
|
||||
<
|
||||
typename boost::remove_reference
|
||||
<
|
||||
typename traits::interior_mutable_type<Polygon2>::type
|
||||
>::type
|
||||
>::apply(interior_rings(poly2), num_interior_rings(poly1));
|
||||
|
||||
typename interior_return_type<Polygon1 const>::type rings1
|
||||
= interior_rings(poly1);
|
||||
typename interior_return_type<Polygon2>::type rings2
|
||||
= interior_rings(poly2);
|
||||
BOOST_AUTO_TPL(it1, boost::begin(rings1));
|
||||
BOOST_AUTO_TPL(it2, boost::begin(rings2));
|
||||
for ( ; it1 != boost::end(interior_rings(poly1)); ++it1, ++it2)
|
||||
{
|
||||
if (!transform_range_out<point2_type>(*it1,
|
||||
std::back_inserter(*it2), strategy))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Point1, typename Point2>
|
||||
struct select_strategy
|
||||
{
|
||||
typedef typename strategy::transform::services::default_strategy
|
||||
<
|
||||
typename cs_tag<Point1>::type,
|
||||
typename cs_tag<Point2>::type,
|
||||
typename coordinate_system<Point1>::type,
|
||||
typename coordinate_system<Point2>::type,
|
||||
dimension<Point1>::type::value,
|
||||
dimension<Point2>::type::value,
|
||||
typename point_type<Point1>::type,
|
||||
typename point_type<Point2>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename Range1, typename Range2, typename Strategy>
|
||||
struct transform_range
|
||||
{
|
||||
static inline bool apply(Range1 const& range1,
|
||||
Range2& range2, Strategy const& strategy)
|
||||
{
|
||||
typedef typename point_type<Range2>::type point_type;
|
||||
|
||||
// Should NOT be done here!
|
||||
// geometry::clear(range2);
|
||||
return transform_range_out<point_type>(range1,
|
||||
std::back_inserter(range2), strategy);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::transform
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag1, typename Tag2,
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Strategy
|
||||
>
|
||||
struct transform {};
|
||||
|
||||
template <typename Point1, typename Point2, typename Strategy>
|
||||
struct transform<point_tag, point_tag, Point1, Point2, Strategy>
|
||||
: detail::transform::transform_point<Point1, Point2, Strategy>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
template <typename Linestring1, typename Linestring2, typename Strategy>
|
||||
struct transform
|
||||
<
|
||||
linestring_tag, linestring_tag,
|
||||
Linestring1, Linestring2, Strategy
|
||||
>
|
||||
: detail::transform::transform_range<Linestring1, Linestring2, Strategy>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Range1, typename Range2, typename Strategy>
|
||||
struct transform<ring_tag, ring_tag, Range1, Range2, Strategy>
|
||||
: detail::transform::transform_range<Range1, Range2, Strategy>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Polygon1, typename Polygon2, typename Strategy>
|
||||
struct transform<polygon_tag, polygon_tag, Polygon1, Polygon2, Strategy>
|
||||
: detail::transform::transform_polygon<Polygon1, Polygon2, Strategy>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Box1, typename Box2, typename Strategy>
|
||||
struct transform<box_tag, box_tag, Box1, Box2, Strategy>
|
||||
: detail::transform::transform_box<Box1, Box2, Strategy>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Segment1, typename Segment2, typename Strategy>
|
||||
struct transform<segment_tag, segment_tag, Segment1, Segment2, Strategy>
|
||||
: detail::transform::transform_box_or_segment<Segment1, Segment2, Strategy>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief Transforms from one geometry to another geometry \brief_strategy
|
||||
\ingroup transform
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam Strategy strategy
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param strategy The strategy to be used for transformation
|
||||
\return True if the transformation could be done
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
|
||||
\qbk{[include reference/algorithms/transform_with_strategy.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
inline bool transform(Geometry1 const& geometry1, Geometry2& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2>();
|
||||
|
||||
typedef dispatch::transform
|
||||
<
|
||||
typename tag_cast<typename tag<Geometry1>::type, multi_tag>::type,
|
||||
typename tag_cast<typename tag<Geometry2>::type, multi_tag>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
Strategy
|
||||
> transform_type;
|
||||
|
||||
return transform_type::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Transforms from one geometry to another geometry using a strategy
|
||||
\ingroup transform
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\return True if the transformation could be done
|
||||
|
||||
\qbk{[include reference/algorithms/transform.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline bool transform(Geometry1 const& geometry1, Geometry2& geometry2)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2>();
|
||||
|
||||
typename detail::transform::select_strategy<Geometry1, Geometry2>::type strategy;
|
||||
return transform(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_TRANSFORM_HPP
|
||||
284
test/external/boost/geometry/algorithms/union.hpp
vendored
Normal file
284
test/external/boost/geometry/algorithms/union.hpp
vendored
Normal file
@@ -0,0 +1,284 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_UNION_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_UNION_HPP
|
||||
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
#include <boost/range/metafunctions.hpp>
|
||||
|
||||
#include <boost/geometry/core/is_areal.hpp>
|
||||
#include <boost/geometry/core/point_order.hpp>
|
||||
#include <boost/geometry/core/reverse_dispatch.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
// tag dispatching:
|
||||
typename TagIn1, typename TagIn2, typename TagOut,
|
||||
// metafunction finetuning helpers:
|
||||
bool Areal1, bool Areal2, bool ArealOut,
|
||||
// real types
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator,
|
||||
typename GeometryOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct union_insert
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPES
|
||||
, (types<Geometry1, Geometry2, GeometryOut>)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename TagIn1, typename TagIn2, typename TagOut,
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator,
|
||||
typename GeometryOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct union_insert
|
||||
<
|
||||
TagIn1, TagIn2, TagOut,
|
||||
true, true, true,
|
||||
Geometry1, Geometry2,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
> : detail::overlay::overlay
|
||||
<Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, overlay_union, Strategy>
|
||||
{};
|
||||
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryTag1, typename GeometryTag2, typename GeometryTag3,
|
||||
bool Areal1, bool Areal2, bool ArealOut,
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct union_insert_reversed
|
||||
{
|
||||
static inline OutputIterator apply(Geometry1 const& g1,
|
||||
Geometry2 const& g2, OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return union_insert
|
||||
<
|
||||
GeometryTag2, GeometryTag1, GeometryTag3,
|
||||
Areal2, Areal1, ArealOut,
|
||||
Geometry2, Geometry1,
|
||||
Reverse2, Reverse1, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>::apply(g2, g1, out, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace union_
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryOut,
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename OutputIterator,
|
||||
typename Strategy
|
||||
>
|
||||
inline OutputIterator insert(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::mpl::if_c
|
||||
<
|
||||
geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
|
||||
dispatch::union_insert_reversed
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
typename tag<GeometryOut>::type,
|
||||
geometry::is_areal<Geometry1>::value,
|
||||
geometry::is_areal<Geometry2>::value,
|
||||
geometry::is_areal<GeometryOut>::value,
|
||||
Geometry1, Geometry2,
|
||||
overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
|
||||
overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
|
||||
overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>,
|
||||
dispatch::union_insert
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
typename tag<GeometryOut>::type,
|
||||
geometry::is_areal<Geometry1>::value,
|
||||
geometry::is_areal<Geometry2>::value,
|
||||
geometry::is_areal<GeometryOut>::value,
|
||||
Geometry1, Geometry2,
|
||||
overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
|
||||
overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
|
||||
overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>
|
||||
>::type::apply(geometry1, geometry2, out, strategy);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief_calc2{union} \brief_strategy
|
||||
\ingroup union
|
||||
\details \details_calc2{union_insert, spatial set theoretic union}
|
||||
\brief_strategy. details_insert{union}
|
||||
\tparam GeometryOut output geometry type, must be specified
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam OutputIterator output iterator
|
||||
\tparam Strategy \tparam_strategy_overlay
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param out \param_out{union}
|
||||
\param strategy \param_strategy{union}
|
||||
\return \return_out
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename GeometryOut,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename OutputIterator,
|
||||
typename Strategy
|
||||
>
|
||||
inline OutputIterator union_insert(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
concept::check<GeometryOut>();
|
||||
|
||||
return detail::union_::insert<GeometryOut>(geometry1, geometry2, out, strategy);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief_calc2{union}
|
||||
\ingroup union
|
||||
\details \details_calc2{union_insert, spatial set theoretic union}.
|
||||
\details_insert{union}
|
||||
\tparam GeometryOut output geometry type, must be specified
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam OutputIterator output iterator
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param out \param_out{union}
|
||||
\return \return_out
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename GeometryOut,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename OutputIterator
|
||||
>
|
||||
inline OutputIterator union_insert(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
OutputIterator out)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
concept::check<GeometryOut>();
|
||||
|
||||
typedef strategy_intersection
|
||||
<
|
||||
typename cs_tag<GeometryOut>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
typename geometry::point_type<GeometryOut>::type
|
||||
> strategy;
|
||||
|
||||
return union_insert<GeometryOut>(geometry1, geometry2, out, strategy());
|
||||
}
|
||||
|
||||
|
||||
}} // namespace detail::union_
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Combines two geometries which each other
|
||||
\ingroup union
|
||||
\details \details_calc2{union, spatial set theoretic union}.
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam Collection output collection, either a multi-geometry,
|
||||
or a std::vector<Geometry> / std::deque<Geometry> etc
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param output_collection the output collection
|
||||
\note Called union_ because union is a reserved word.
|
||||
|
||||
\qbk{[include reference/algorithms/union.qbk]}
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Collection
|
||||
>
|
||||
inline void union_(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Collection& output_collection)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
typedef typename boost::range_value<Collection>::type geometry_out;
|
||||
concept::check<geometry_out>();
|
||||
|
||||
detail::union_::union_insert<geometry_out>(geometry1, geometry2,
|
||||
std::back_inserter(output_collection));
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_UNION_HPP
|
||||
153
test/external/boost/geometry/algorithms/unique.hpp
vendored
Normal file
153
test/external/boost/geometry/algorithms/unique.hpp
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_UNIQUE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_UNIQUE_HPP
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/mutable_range.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/policies/compare.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace unique
|
||||
{
|
||||
|
||||
|
||||
template <typename Range, typename ComparePolicy>
|
||||
struct range_unique
|
||||
{
|
||||
static inline void apply(Range& range, ComparePolicy const& policy)
|
||||
{
|
||||
typename boost::range_iterator<Range>::type it
|
||||
= std::unique
|
||||
(
|
||||
boost::begin(range),
|
||||
boost::end(range),
|
||||
policy
|
||||
);
|
||||
|
||||
traits::resize<Range>::apply(range, it - boost::begin(range));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Polygon, typename ComparePolicy>
|
||||
struct polygon_unique
|
||||
{
|
||||
static inline void apply(Polygon& polygon, ComparePolicy const& policy)
|
||||
{
|
||||
typedef typename geometry::ring_type<Polygon>::type ring_type;
|
||||
|
||||
typedef range_unique<ring_type, ComparePolicy> per_range;
|
||||
per_range::apply(exterior_ring(polygon), policy);
|
||||
|
||||
typename interior_return_type<Polygon>::type rings
|
||||
= interior_rings(polygon);
|
||||
for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
|
||||
{
|
||||
per_range::apply(*it, policy);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
}} // namespace detail::unique
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag,
|
||||
typename Geometry,
|
||||
typename ComparePolicy
|
||||
>
|
||||
struct unique
|
||||
{
|
||||
static inline void apply(Geometry&, ComparePolicy const& )
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
template <typename Ring, typename ComparePolicy>
|
||||
struct unique<ring_tag, Ring, ComparePolicy>
|
||||
: detail::unique::range_unique<Ring, ComparePolicy>
|
||||
{};
|
||||
|
||||
|
||||
template <typename LineString, typename ComparePolicy>
|
||||
struct unique<linestring_tag, LineString, ComparePolicy>
|
||||
: detail::unique::range_unique<LineString, ComparePolicy>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename ComparePolicy>
|
||||
struct unique<polygon_tag, Polygon, ComparePolicy>
|
||||
: detail::unique::polygon_unique<Polygon, ComparePolicy>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc{minimal set}
|
||||
\ingroup unique
|
||||
\details \details_calc{unique,minimal set (where duplicate consecutive points are removed)}.
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry which will be made unique
|
||||
|
||||
\qbk{[include reference/algorithms/unique.qbk]}
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline void unique(Geometry& geometry)
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
// Default strategy is the default point-comparison policy
|
||||
typedef geometry::equal_to
|
||||
<
|
||||
typename geometry::point_type<Geometry>::type
|
||||
> policy;
|
||||
|
||||
|
||||
dispatch::unique
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
policy
|
||||
>::apply(geometry, policy());
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_UNIQUE_HPP
|
||||
357
test/external/boost/geometry/algorithms/within.hpp
vendored
Normal file
357
test/external/boost/geometry/algorithms/within.hpp
vendored
Normal file
@@ -0,0 +1,357 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_WITHIN_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_WITHIN_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/make.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/point_order.hpp>
|
||||
#include <boost/geometry/core/ring_type.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/strategies/within.hpp>
|
||||
#include <boost/geometry/strategies/concepts/within_concept.hpp>
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
#include <boost/geometry/util/order_as_direction.hpp>
|
||||
#include <boost/geometry/views/closeable_view.hpp>
|
||||
#include <boost/geometry/views/reversible_view.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace within
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename Ring,
|
||||
iterate_direction Direction,
|
||||
closure_selector Closure,
|
||||
typename Strategy
|
||||
>
|
||||
struct point_in_ring
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategyPolygonal<Strategy>) );
|
||||
|
||||
static inline int apply(Point const& point, Ring const& ring,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
if (boost::size(ring)
|
||||
< core_detail::closure::minimum_ring_size<Closure>::value)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
typedef typename reversible_view<Ring const, Direction>::type rev_view_type;
|
||||
typedef typename closeable_view
|
||||
<
|
||||
rev_view_type const, Closure
|
||||
>::type cl_view_type;
|
||||
typedef typename boost::range_iterator<cl_view_type const>::type iterator_type;
|
||||
|
||||
rev_view_type rev_view(ring);
|
||||
cl_view_type view(rev_view);
|
||||
typename Strategy::state_type state;
|
||||
iterator_type it = boost::begin(view);
|
||||
iterator_type end = boost::end(view);
|
||||
|
||||
bool stop = false;
|
||||
for (iterator_type previous = it++;
|
||||
it != end && ! stop;
|
||||
++previous, ++it)
|
||||
{
|
||||
if (! strategy.apply(point, *previous, *it, state))
|
||||
{
|
||||
stop = true;
|
||||
}
|
||||
}
|
||||
|
||||
return strategy.result(state);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Polygon: in exterior ring, and if so, not within interior ring(s)
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename Polygon,
|
||||
iterate_direction Direction,
|
||||
closure_selector Closure,
|
||||
typename Strategy
|
||||
>
|
||||
struct point_in_polygon
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategyPolygonal<Strategy>) );
|
||||
|
||||
static inline int apply(Point const& point, Polygon const& poly,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
int const code = point_in_ring
|
||||
<
|
||||
Point,
|
||||
typename ring_type<Polygon>::type,
|
||||
Direction,
|
||||
Closure,
|
||||
Strategy
|
||||
>::apply(point, exterior_ring(poly), strategy);
|
||||
|
||||
if (code == 1)
|
||||
{
|
||||
typename interior_return_type<Polygon const>::type rings
|
||||
= interior_rings(poly);
|
||||
for (BOOST_AUTO_TPL(it, boost::begin(rings));
|
||||
it != boost::end(rings);
|
||||
++it)
|
||||
{
|
||||
int const interior_code = point_in_ring
|
||||
<
|
||||
Point,
|
||||
typename ring_type<Polygon>::type,
|
||||
Direction,
|
||||
Closure,
|
||||
Strategy
|
||||
>::apply(point, *it, strategy);
|
||||
|
||||
if (interior_code != -1)
|
||||
{
|
||||
// If 0, return 0 (touch)
|
||||
// If 1 (inside hole) return -1 (outside polygon)
|
||||
// If -1 (outside hole) check other holes if any
|
||||
return -interior_code;
|
||||
}
|
||||
}
|
||||
}
|
||||
return code;
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::within
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag1,
|
||||
typename Tag2,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Strategy
|
||||
>
|
||||
struct within
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
|
||||
, (types<Geometry1, Geometry2>)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
template <typename Point, typename Box, typename Strategy>
|
||||
struct within<point_tag, box_tag, Point, Box, Strategy>
|
||||
{
|
||||
static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
|
||||
{
|
||||
return strategy.apply(point, box);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box1, typename Box2, typename Strategy>
|
||||
struct within<box_tag, box_tag, Box1, Box2, Strategy>
|
||||
{
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
|
||||
{
|
||||
assert_dimension_equal<Box1, Box2>();
|
||||
return strategy.apply(box1, box2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename Point, typename Ring, typename Strategy>
|
||||
struct within<point_tag, ring_tag, Point, Ring, Strategy>
|
||||
{
|
||||
static inline bool apply(Point const& point, Ring const& ring, Strategy const& strategy)
|
||||
{
|
||||
return detail::within::point_in_ring
|
||||
<
|
||||
Point,
|
||||
Ring,
|
||||
order_as_direction<geometry::point_order<Ring>::value>::value,
|
||||
geometry::closure<Ring>::value,
|
||||
Strategy
|
||||
>::apply(point, ring, strategy) == 1;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Point, typename Polygon, typename Strategy>
|
||||
struct within<point_tag, polygon_tag, Point, Polygon, Strategy>
|
||||
{
|
||||
static inline bool apply(Point const& point, Polygon const& polygon, Strategy const& strategy)
|
||||
{
|
||||
return detail::within::point_in_polygon
|
||||
<
|
||||
Point,
|
||||
Polygon,
|
||||
order_as_direction<geometry::point_order<Polygon>::value>::value,
|
||||
geometry::closure<Polygon>::value,
|
||||
Strategy
|
||||
>::apply(point, polygon, strategy) == 1;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check12{is completely inside}
|
||||
\ingroup within
|
||||
\details \details_check12{within, is completely inside}.
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param geometry1 geometry which might be within the second geometry
|
||||
\param geometry2 geometry which might contain the first geometry
|
||||
\return true if geometry1 is completely contained within geometry2,
|
||||
else false
|
||||
\note The default strategy is used for within detection
|
||||
|
||||
|
||||
\qbk{[include reference/algorithms/within.qbk]}
|
||||
|
||||
\qbk{
|
||||
[heading Example]
|
||||
[within]
|
||||
[within_output]
|
||||
}
|
||||
*/
|
||||
template<typename Geometry1, typename Geometry2>
|
||||
inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
assert_dimension_equal<Geometry1, Geometry2>();
|
||||
|
||||
typedef typename point_type<Geometry1>::type point_type1;
|
||||
typedef typename point_type<Geometry2>::type point_type2;
|
||||
|
||||
typedef typename strategy::within::services::default_strategy
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
|
||||
typename tag_cast
|
||||
<
|
||||
typename cs_tag<point_type1>::type, spherical_tag
|
||||
>::type,
|
||||
typename tag_cast
|
||||
<
|
||||
typename cs_tag<point_type2>::type, spherical_tag
|
||||
>::type,
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
return dispatch::within
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
strategy_type
|
||||
>::apply(geometry1, geometry2, strategy_type());
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief \brief_check12{is completely inside} \brief_strategy
|
||||
\ingroup within
|
||||
\details \details_check12{within, is completely inside}, \brief_strategy. \details_strategy_reasons
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param geometry1 \param_geometry geometry which might be within the second geometry
|
||||
\param geometry2 \param_geometry which might contain the first geometry
|
||||
\param strategy strategy to be used
|
||||
\return true if geometry1 is completely contained within geometry2,
|
||||
else false
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{[include reference/algorithms/within.qbk]}
|
||||
\qbk{
|
||||
[heading Available Strategies]
|
||||
\* [link geometry.reference.strategies.strategy_within_winding Winding (coordinate system agnostic)]
|
||||
\* [link geometry.reference.strategies.strategy_within_franklin Franklin (cartesian)]
|
||||
\* [link geometry.reference.strategies.strategy_within_crossings_multiply Crossings Multiply (cartesian)]
|
||||
|
||||
[heading Example]
|
||||
[within_strategy]
|
||||
[within_strategy_output]
|
||||
|
||||
}
|
||||
*/
|
||||
template<typename Geometry1, typename Geometry2, typename Strategy>
|
||||
inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concept::within::check
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
|
||||
Strategy
|
||||
>();
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
assert_dimension_equal<Geometry1, Geometry2>();
|
||||
|
||||
return dispatch::within
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
Strategy
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_WITHIN_HPP
|
||||
Reference in New Issue
Block a user