mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-11 11:52:11 +00:00
Merge branch 'develop' of https://github.com/boostorg/geometry into feature/setops
Conflicts: include/boost/geometry/algorithms/detail/relate/less.hpp
This commit is contained in:
@@ -1,79 +0,0 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014 Oracle and/or its affiliates.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_GROUP_DIM_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_GROUP_DIM_HPP
|
||||
|
||||
#include <boost/type_traits/is_base_of.hpp>
|
||||
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
|
||||
namespace boost { namespace geometry {
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail {
|
||||
|
||||
template <typename Geometry,
|
||||
typename Tag = typename geometry::tag<Geometry>::type,
|
||||
bool IsPoint = boost::is_base_of<pointlike_tag, Tag>::value,
|
||||
bool IsLinear = boost::is_base_of<linear_tag, Tag>::value,
|
||||
bool IsAreal = boost::is_base_of<areal_tag, Tag>::value>
|
||||
struct group_tag
|
||||
: not_implemented<Tag>
|
||||
{};
|
||||
|
||||
template <typename Geometry, typename Tag>
|
||||
struct group_tag<Geometry, Tag, true, false, false>
|
||||
{
|
||||
typedef pointlike_tag type;
|
||||
};
|
||||
|
||||
template <typename Geometry, typename Tag>
|
||||
struct group_tag<Geometry, Tag, false, true, false>
|
||||
{
|
||||
typedef linear_tag type;
|
||||
};
|
||||
|
||||
template <typename Geometry, typename Tag>
|
||||
struct group_tag<Geometry, Tag, false, false, true>
|
||||
{
|
||||
typedef areal_tag type;
|
||||
};
|
||||
|
||||
template <typename Geometry,
|
||||
typename GroupTag = typename group_tag<Geometry>::type>
|
||||
struct group_dim
|
||||
: not_implemented<GroupTag>
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct group_dim<Geometry, pointlike_tag>
|
||||
{
|
||||
static const int value = 0;
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct group_dim<Geometry, linear_tag>
|
||||
{
|
||||
static const int value = 1;
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct group_dim<Geometry, areal_tag>
|
||||
{
|
||||
static const int value = 2;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_GROUP_DIM_HPP
|
||||
@@ -52,9 +52,8 @@ struct get_turn_without_info
|
||||
static inline OutputIterator apply(
|
||||
Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
// TODO: should this always be std::size_t or replace with template parameter?
|
||||
std::size_t /*p_segments_count*/,
|
||||
std::size_t /*q_segments_count*/,
|
||||
bool /*is_p_first*/, bool /*is_p_last*/,
|
||||
bool /*is_q_first*/, bool /*is_q_last*/,
|
||||
TurnInfo const& ,
|
||||
RescalePolicy const& rescale_policy,
|
||||
OutputIterator out)
|
||||
|
||||
@@ -975,9 +975,8 @@ struct get_turn_info
|
||||
static inline OutputIterator apply(
|
||||
Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
// TODO: should this always be std::size_t or replace with template parameter?
|
||||
std::size_t /*p_segments_count*/,
|
||||
std::size_t /*q_segments_count*/,
|
||||
bool /*is_p_first*/, bool /*is_p_last*/,
|
||||
bool /*is_q_first*/, bool /*is_q_last*/,
|
||||
TurnInfo const& tp_model,
|
||||
RescalePolicy const& , // TODO: this will be used. rescale_policy,
|
||||
OutputIterator out)
|
||||
|
||||
@@ -130,9 +130,8 @@ struct get_turn_info_for_endpoint
|
||||
>
|
||||
static inline bool apply(Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
// TODO: should this always be std::size_t or replace with template parameter?
|
||||
std::size_t p_segments_count,
|
||||
std::size_t q_segments_count,
|
||||
bool is_p_first, bool is_p_last,
|
||||
bool is_q_first, bool is_q_last,
|
||||
TurnInfo const& tp_model,
|
||||
IntersectionResult const& result,
|
||||
method_type method,
|
||||
@@ -147,11 +146,6 @@ struct get_turn_info_for_endpoint
|
||||
int segment_index1 = tp_model.operations[1].seg_id.segment_index;
|
||||
BOOST_ASSERT(segment_index0 >= 0 && segment_index1 >= 0);
|
||||
|
||||
bool is_p_first = segment_index0 == 0;
|
||||
bool is_q_first = segment_index1 == 0;
|
||||
bool is_p_last = static_cast<std::size_t>(segment_index0) + 1 == p_segments_count;
|
||||
bool is_q_last = static_cast<std::size_t>(segment_index1) + 1 == q_segments_count;
|
||||
|
||||
if ( !is_p_first && !is_p_last && !is_q_first && !is_q_last )
|
||||
return false;
|
||||
|
||||
@@ -418,14 +412,13 @@ struct get_turn_info_for_endpoint
|
||||
geometry::convert(i2, i2_conv);
|
||||
side_calculator<Point1, Point2> side_calc(i2_conv, i1, j1, i2, j2, k2);
|
||||
|
||||
TurnInfo tp = tp_model;
|
||||
equal<TurnInfo>::apply(i2_conv, i1, j1, i2, j2, k2,
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
std::pair<operation_type, operation_type>
|
||||
operations = operations_of_equal(side_calc);
|
||||
|
||||
// TODO: must the above be calculated?
|
||||
// wouldn't it be enough to check if segments are collinear?
|
||||
|
||||
if ( tp.both(operation_continue) )
|
||||
if ( operations_both(operations, operation_continue) )
|
||||
{
|
||||
// THIS IS WRT THE ORIGINAL SEGMENTS! NOT THE ONES ABOVE!
|
||||
bool opposite = result.template get<1>().opposite;
|
||||
@@ -435,7 +428,7 @@ struct get_turn_info_for_endpoint
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(tp.combination(operation_intersection, operation_union));
|
||||
BOOST_ASSERT(operations_combination(operations, operation_intersection, operation_union));
|
||||
//op1 = operation_union;
|
||||
//op2 = operation_union;
|
||||
}
|
||||
@@ -466,14 +459,13 @@ struct get_turn_info_for_endpoint
|
||||
|
||||
side_calculator<Point1, Point2> side_calc(i2_conv, j1, i1, i2, j2, k2);
|
||||
|
||||
TurnInfo tp = tp_model;
|
||||
equal<TurnInfo>::apply(i2_conv, j1, i1, i2, j2, k2,
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
std::pair<operation_type, operation_type>
|
||||
operations = operations_of_equal(side_calc);
|
||||
|
||||
// TODO: must the above be calculated?
|
||||
// wouldn't it be enough to check if segments are collinear?
|
||||
|
||||
if ( tp.both(operation_continue) )
|
||||
if ( operations_both(operations, operation_continue) )
|
||||
{
|
||||
// THIS IS WRT THE ORIGINAL SEGMENTS! NOT THE ONES ABOVE!
|
||||
bool second_going_out = result.template get<0>().count > 1;
|
||||
@@ -483,7 +475,7 @@ struct get_turn_info_for_endpoint
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(tp.combination(operation_intersection, operation_union));
|
||||
BOOST_ASSERT(operations_combination(operations, operation_intersection, operation_union));
|
||||
//op1 = operation_blocked;
|
||||
//op2 = operation_union;
|
||||
}
|
||||
@@ -558,6 +550,66 @@ struct get_turn_info_for_endpoint
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
*out++ = tp;
|
||||
}
|
||||
|
||||
template <typename SidePolicy>
|
||||
static inline std::pair<operation_type, operation_type> operations_of_equal(SidePolicy const& side)
|
||||
{
|
||||
int const side_pk_q2 = side.pk_wrt_q2();
|
||||
int const side_pk_p = side.pk_wrt_p1();
|
||||
int const side_qk_p = side.qk_wrt_p1();
|
||||
|
||||
// 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 )
|
||||
{
|
||||
return std::make_pair(operation_continue, operation_continue);
|
||||
}
|
||||
|
||||
// If they turn to same side (not opposite sides)
|
||||
if ( ! base_turn_handler::opposite(side_pk_p, side_qk_p) )
|
||||
{
|
||||
int const side_pk_q2 = side.pk_wrt_q2();
|
||||
// If pk is left of q2 or collinear: p: union, q: intersection
|
||||
if ( side_pk_q2 != -1 )
|
||||
{
|
||||
return std::make_pair(operation_union, operation_intersection);
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::make_pair(operation_intersection, operation_union);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// They turn opposite sides. If p turns left (or collinear),
|
||||
// p: union, q: intersection
|
||||
if ( side_pk_p != -1 )
|
||||
{
|
||||
return std::make_pair(operation_union, operation_intersection);
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::make_pair(operation_intersection, operation_union);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool operations_both(
|
||||
std::pair<operation_type, operation_type> const& operations,
|
||||
operation_type const op)
|
||||
{
|
||||
return operations.first == op && operations.second == op;
|
||||
}
|
||||
|
||||
static inline bool operations_combination(
|
||||
std::pair<operation_type, operation_type> const& operations,
|
||||
operation_type const op1, operation_type const op2)
|
||||
{
|
||||
return ( operations.first == op1 && operations.second == op2 )
|
||||
|| ( operations.first == op2 && operations.second == op1 );
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::overlay
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp>
|
||||
|
||||
// TEMP, for spikes detector
|
||||
//#include <boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp>
|
||||
|
||||
namespace boost { namespace geometry {
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
@@ -36,9 +39,8 @@ struct get_turn_info_linear_areal
|
||||
static inline OutputIterator apply(
|
||||
Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
// TODO: should this always be std::size_t or replace with template parameter?
|
||||
std::size_t p_segments_count,
|
||||
std::size_t q_segments_count,
|
||||
bool is_p_first, bool is_p_last,
|
||||
bool is_q_first, bool is_q_last,
|
||||
TurnInfo const& tp_model,
|
||||
RescalePolicy const& , // TODO: this will be used. rescale_policy,
|
||||
OutputIterator out)
|
||||
@@ -74,7 +76,8 @@ struct get_turn_info_linear_areal
|
||||
case 'f' : // collinear, "from"
|
||||
case 's' : // starts from the middle
|
||||
get_turn_info_for_endpoint<true, true>(
|
||||
pi, pj, pk, qi, qj, qk, p_segments_count, q_segments_count,
|
||||
pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, result, method_none, out);
|
||||
break;
|
||||
|
||||
@@ -84,7 +87,8 @@ struct get_turn_info_linear_areal
|
||||
case 'm' :
|
||||
{
|
||||
if ( get_turn_info_for_endpoint<false, true>(
|
||||
pi, pj, pk, qi, qj, qk, p_segments_count, q_segments_count,
|
||||
pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, result, method_touch_interior, out) )
|
||||
{
|
||||
// do nothing
|
||||
@@ -139,7 +143,8 @@ struct get_turn_info_linear_areal
|
||||
{
|
||||
// Both touch (both arrive there)
|
||||
if ( get_turn_info_for_endpoint<false, true>(
|
||||
pi, pj, pk, qi, qj, qk, p_segments_count, q_segments_count,
|
||||
pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, result, method_touch, out) )
|
||||
{
|
||||
// do nothing
|
||||
@@ -164,7 +169,8 @@ struct get_turn_info_linear_areal
|
||||
case 'e':
|
||||
{
|
||||
if ( get_turn_info_for_endpoint<true, true>(
|
||||
pi, pj, pk, qi, qj, qk, p_segments_count, q_segments_count,
|
||||
pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, result, method_equal, out) )
|
||||
{
|
||||
// do nothing
|
||||
@@ -183,6 +189,14 @@ struct get_turn_info_linear_areal
|
||||
replacer_of_method_and_operations_ec<false> replacer(method_touch);
|
||||
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
|
||||
// TODO: This isn't correct handling, hence commented out
|
||||
/*spike_detector<Point1, Point2> spike_detect(side_calc);
|
||||
if ( tp.operations[0].operation == operation_union
|
||||
&& spike_detect.is_spike_p())
|
||||
{
|
||||
tp.operations[0].operation = operation_continue;
|
||||
}*/
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
*out++ = tp;
|
||||
}
|
||||
@@ -202,7 +216,8 @@ struct get_turn_info_linear_areal
|
||||
{
|
||||
// Collinear
|
||||
if ( get_turn_info_for_endpoint<true, true>(
|
||||
pi, pj, pk, qi, qj, qk, p_segments_count, q_segments_count,
|
||||
pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, result, method_collinear, out) )
|
||||
{
|
||||
// do nothing
|
||||
@@ -219,6 +234,13 @@ struct get_turn_info_linear_areal
|
||||
equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
|
||||
spike_detector<Point1, Point2> spike_detect(side_calc);
|
||||
if ( tp.operations[0].operation == operation_union
|
||||
&& spike_detect.is_spike_p())
|
||||
{
|
||||
tp.operations[0].operation = operation_continue;
|
||||
}
|
||||
|
||||
replacer_of_method_and_operations_ec<false> replacer(method_touch);
|
||||
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
}
|
||||
@@ -288,12 +310,18 @@ struct get_turn_info_linear_areal
|
||||
|
||||
// Assuming G1 is always Linear
|
||||
if ( op0 == operation_blocked )
|
||||
{
|
||||
op0 = operation_continue;
|
||||
}
|
||||
|
||||
if ( op1 == operation_blocked )
|
||||
{
|
||||
op1 = operation_continue;
|
||||
}
|
||||
else if ( op1 == operation_intersection )
|
||||
{
|
||||
op1 = operation_union;
|
||||
}
|
||||
}
|
||||
|
||||
template <bool IsFront>
|
||||
@@ -318,12 +346,18 @@ struct get_turn_info_linear_areal
|
||||
|
||||
// Assuming G1 is always Linear
|
||||
if ( op0 == operation_blocked )
|
||||
{
|
||||
op0 = operation_continue;
|
||||
}
|
||||
|
||||
if ( op1 == operation_blocked )
|
||||
{
|
||||
op1 = operation_continue;
|
||||
}
|
||||
else if ( op1 == operation_intersection )
|
||||
{
|
||||
op1 = operation_union;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -347,9 +381,8 @@ struct get_turn_info_linear_areal
|
||||
static inline bool get_turn_info_for_endpoint(
|
||||
Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
// TODO: should this always be std::size_t or replace with template parameter?
|
||||
std::size_t p_segments_count,
|
||||
std::size_t q_segments_count,
|
||||
bool is_p_first, bool is_p_last,
|
||||
bool is_q_first, bool is_q_last,
|
||||
TurnInfo const& tp_model,
|
||||
IntersectionResult const& result,
|
||||
method_type method,
|
||||
@@ -367,11 +400,6 @@ struct get_turn_info_linear_areal
|
||||
const int segment_index1 = tp_model.operations[1].seg_id.segment_index;
|
||||
BOOST_ASSERT(segment_index0 >= 0 && segment_index1 >= 0);
|
||||
|
||||
const bool is_p_first = segment_index0 == 0;
|
||||
const bool is_q_first = segment_index1 == 0; // not used
|
||||
const bool is_p_last = static_cast<std::size_t>(segment_index0) + 1 == p_segments_count;
|
||||
const bool is_q_last = static_cast<std::size_t>(segment_index1) + 1 == q_segments_count; // not used
|
||||
|
||||
if ( !is_p_first && !is_p_last )
|
||||
return false;
|
||||
|
||||
@@ -430,8 +458,11 @@ struct get_turn_info_linear_areal
|
||||
{
|
||||
side_calculator<Point1, Point2> side_calc(qi_conv, pi, pj, qi, qj, qk);
|
||||
|
||||
equal<TurnInfo>::apply(qi_conv, pi, pj, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
std::pair<operation_type, operation_type>
|
||||
operations = get_info_e::operations_of_equal(side_calc);
|
||||
|
||||
tp.operations[0].operation = operations.first;
|
||||
tp.operations[1].operation = operations.second;
|
||||
|
||||
replaced_method = method_touch;
|
||||
}
|
||||
@@ -443,9 +474,11 @@ struct get_turn_info_linear_areal
|
||||
|
||||
side_calculator<Point1, Point2> side_calc(qi_conv, pi, pj, qi, pi_conv, qj);
|
||||
|
||||
// Collinear, but similar thus handled as equal
|
||||
equal<TurnInfo>::apply(qi_conv, pi, pj, qi, pi_conv, qj,
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
std::pair<operation_type, operation_type>
|
||||
operations = get_info_e::operations_of_equal(side_calc);
|
||||
|
||||
tp.operations[0].operation = operations.first;
|
||||
tp.operations[1].operation = operations.second;
|
||||
}
|
||||
|
||||
replacer_of_method_and_operations_ec<true> replacer(replaced_method);
|
||||
@@ -491,8 +524,11 @@ struct get_turn_info_linear_areal
|
||||
geometry::convert(qi, qi_conv);
|
||||
side_calculator<Point1, Point2> side_calc(qi_conv, pj, pi, qi, qj, qk);
|
||||
|
||||
equal<TurnInfo>::apply(qi_conv, pj, pi, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
std::pair<operation_type, operation_type>
|
||||
operations = get_info_e::operations_of_equal(side_calc);
|
||||
|
||||
tp.operations[0].operation = operations.first;
|
||||
tp.operations[1].operation = operations.second;
|
||||
|
||||
replacer_of_method_and_operations_ec<false> replacer(method_none);
|
||||
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
|
||||
@@ -22,6 +22,62 @@ namespace boost { namespace geometry {
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay {
|
||||
|
||||
template <typename Point1,
|
||||
typename Point2,
|
||||
typename SideCalc = side_calculator<Point1, Point2> >
|
||||
class spike_detector
|
||||
{
|
||||
public:
|
||||
explicit spike_detector(SideCalc const& side_calc)
|
||||
: m_side_calc(side_calc)
|
||||
{}
|
||||
|
||||
inline bool is_spike_p() const
|
||||
{
|
||||
if ( m_side_calc.pk_wrt_p1() == 0 )
|
||||
{
|
||||
int const qk_p1 = m_side_calc.qk_wrt_p1();
|
||||
int const qk_p2 = m_side_calc.qk_wrt_p2();
|
||||
|
||||
if ( qk_p1 == -qk_p2 )
|
||||
{
|
||||
if ( qk_p1 == 0 )
|
||||
{
|
||||
// TODO check additional things
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool is_spike_q() const
|
||||
{
|
||||
if ( m_side_calc.qk_wrt_q1() == 0 )
|
||||
{
|
||||
int const pk_q1 = m_side_calc.pk_wrt_q1();
|
||||
int const pk_q2 = m_side_calc.pk_wrt_q2();
|
||||
|
||||
if ( pk_q1 == -pk_q2 )
|
||||
{
|
||||
if ( pk_q1 == 0 )
|
||||
{
|
||||
// TODO check additional things
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
SideCalc const& m_side_calc;
|
||||
};
|
||||
|
||||
template<typename AssignPolicy>
|
||||
struct get_turn_info_linear_linear
|
||||
{
|
||||
@@ -36,9 +92,8 @@ struct get_turn_info_linear_linear
|
||||
static inline OutputIterator apply(
|
||||
Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
// TODO: should this always be std::size_t or replace with template parameter?
|
||||
std::size_t p_segments_count,
|
||||
std::size_t q_segments_count,
|
||||
bool is_p_first, bool is_p_last,
|
||||
bool is_q_first, bool is_q_last,
|
||||
TurnInfo const& tp_model,
|
||||
RescalePolicy const& , // TODO: this will be used. rescale_policy,
|
||||
OutputIterator out)
|
||||
@@ -74,8 +129,9 @@ struct get_turn_info_linear_linear
|
||||
case 'f' : // collinear, "from"
|
||||
case 's' : // starts from the middle
|
||||
get_turn_info_for_endpoint<AssignPolicy, true, true>
|
||||
::apply(pi, pj, pk, qi, qj, qk, p_segments_count, q_segments_count,
|
||||
tp_model, result, method_none, out);
|
||||
::apply(pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, result, method_none, out);
|
||||
break;
|
||||
|
||||
case 'd' : // disjoint: never do anything
|
||||
@@ -84,8 +140,9 @@ struct get_turn_info_linear_linear
|
||||
case 'm' :
|
||||
{
|
||||
if ( get_turn_info_for_endpoint<AssignPolicy, false, true>
|
||||
::apply(pi, pj, pk, qi, qj, qk, p_segments_count, q_segments_count,
|
||||
tp_model, result, method_touch_interior, out) )
|
||||
::apply(pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, result, method_touch_interior, out) )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@@ -143,7 +200,8 @@ struct get_turn_info_linear_linear
|
||||
{
|
||||
// Both touch (both arrive there)
|
||||
if ( get_turn_info_for_endpoint<AssignPolicy, false, true>
|
||||
::apply(pi, pj, pk, qi, qj, qk, p_segments_count, q_segments_count,
|
||||
::apply(pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, result, method_touch, out) )
|
||||
{
|
||||
// do nothing
|
||||
@@ -172,7 +230,8 @@ struct get_turn_info_linear_linear
|
||||
case 'e':
|
||||
{
|
||||
if ( get_turn_info_for_endpoint<AssignPolicy, true, true>
|
||||
::apply(pi, pj, pk, qi, qj, qk, p_segments_count, q_segments_count,
|
||||
::apply(pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, result, method_equal, out) )
|
||||
{
|
||||
// do nothing
|
||||
@@ -191,6 +250,19 @@ struct get_turn_info_linear_linear
|
||||
|
||||
replacer_of_method_and_operations_ec replacer(method_touch);
|
||||
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
|
||||
// TODO: This isn't correct handling, hence commented out
|
||||
/*spike_detector<Point1, Point2> spike_detect(side_calc);
|
||||
if ( tp.operations[0].operation == operation_union
|
||||
&& spike_detect.is_spike_p())
|
||||
{
|
||||
tp.operations[0].operation = operation_continue;
|
||||
}
|
||||
if ( tp.operations[1].operation == operation_union
|
||||
&& spike_detect.is_spike_q())
|
||||
{
|
||||
tp.operations[1].operation = operation_continue;
|
||||
}*/
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
*out++ = tp;
|
||||
@@ -211,7 +283,8 @@ struct get_turn_info_linear_linear
|
||||
{
|
||||
// Collinear
|
||||
if ( get_turn_info_for_endpoint<AssignPolicy, true, true>
|
||||
::apply(pi, pj, pk, qi, qj, qk, p_segments_count, q_segments_count,
|
||||
::apply(pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, result, method_collinear, out) )
|
||||
{
|
||||
// do nothing
|
||||
@@ -236,6 +309,19 @@ struct get_turn_info_linear_linear
|
||||
|
||||
replacer_of_method_and_operations_ec replacer(method_touch);
|
||||
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
|
||||
// TODO: This isn't correct handling, hence commented out
|
||||
/*spike_detector<Point1, Point2> spike_detect(side_calc);
|
||||
if ( tp.operations[0].operation == operation_union
|
||||
&& spike_detect.is_spike_p())
|
||||
{
|
||||
tp.operations[0].operation = operation_continue;
|
||||
}
|
||||
if ( tp.operations[1].operation == operation_union
|
||||
&& spike_detect.is_spike_q())
|
||||
{
|
||||
tp.operations[1].operation = operation_continue;
|
||||
}*/
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -244,6 +330,11 @@ struct get_turn_info_linear_linear
|
||||
|
||||
replacer_of_method_and_operations_ec replacer(method_touch_interior);
|
||||
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
|
||||
// TEST
|
||||
//spike_detector<Point1, Point2> spike_detect(side_calc);
|
||||
//spike_detect.is_spike_p();
|
||||
//spike_detect.is_spike_q();
|
||||
}
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
@@ -305,14 +396,22 @@ struct get_turn_info_linear_linear
|
||||
else
|
||||
{
|
||||
if ( op0 == operation_continue || op0 == operation_blocked )
|
||||
{
|
||||
op0 = operation_intersection;
|
||||
}
|
||||
else if ( op0 == operation_intersection )
|
||||
{
|
||||
op0 = operation_union;
|
||||
}
|
||||
|
||||
if ( op1 == operation_continue || op1 == operation_blocked )
|
||||
{
|
||||
op1 = operation_intersection;
|
||||
}
|
||||
else if ( op1 == operation_intersection )
|
||||
{
|
||||
op1 = operation_union;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,14 +429,22 @@ struct get_turn_info_linear_linear
|
||||
BOOST_ASSERT(op0 != operation_blocked || op1 != operation_blocked );
|
||||
|
||||
if ( op0 == operation_blocked )
|
||||
{
|
||||
op0 = operation_intersection;
|
||||
}
|
||||
else if ( op0 == operation_intersection )
|
||||
{
|
||||
op0 = operation_union;
|
||||
}
|
||||
|
||||
if ( op1 == operation_blocked )
|
||||
{
|
||||
op1 = operation_intersection;
|
||||
}
|
||||
else if ( op1 == operation_intersection )
|
||||
{
|
||||
op1 = operation_union;
|
||||
}
|
||||
|
||||
if ( op0 == operation_intersection || op0 == operation_union
|
||||
|| op1 == operation_intersection || op1 == operation_union )
|
||||
@@ -353,13 +460,15 @@ struct get_turn_info_linear_linear
|
||||
static inline void replace_operations_i(operation_type & op0, operation_type & op1)
|
||||
{
|
||||
if ( op0 == operation_intersection )
|
||||
{
|
||||
op0 = operation_union;
|
||||
}
|
||||
|
||||
if ( op1 == operation_intersection )
|
||||
{
|
||||
op1 = operation_union;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
}} // namespace detail::overlay
|
||||
|
||||
@@ -54,7 +54,6 @@
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp>
|
||||
#include <boost/geometry/algorithms/detail/group_dim.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
|
||||
|
||||
@@ -287,8 +286,13 @@ public :
|
||||
|
||||
std::size_t const size_before = boost::size(turns);
|
||||
|
||||
bool const is_1_first = sec1.is_non_duplicate_first && index1 == sec1.begin_index;
|
||||
bool const is_1_last = sec1.is_non_duplicate_last && index1+1 >= sec1.end_index;
|
||||
bool const is_2_first = sec2.is_non_duplicate_first && index2 == sec2.begin_index;
|
||||
bool const is_2_last = sec2.is_non_duplicate_last && index2+1 >= sec2.end_index;
|
||||
|
||||
TurnPolicy::apply(*prev1, *it1, *nd_next1, *prev2, *it2, *nd_next2,
|
||||
sec1.range_count - 1, sec2.range_count - 1,
|
||||
is_1_first, is_1_last, is_2_first, is_2_last,
|
||||
ti, rescale_policy, std::back_inserter(turns));
|
||||
|
||||
if (InterruptPolicy::enabled)
|
||||
@@ -598,7 +602,9 @@ struct get_turns_cs
|
||||
get_turns_with_box(seg_id, source_id2,
|
||||
*prev, *it, *next,
|
||||
bp[0], bp[1], bp[2], bp[3],
|
||||
segments_count1,
|
||||
// NOTE: some dummy values could be passed below since this would be called only for Polygons and Boxes
|
||||
index == 0,
|
||||
unsigned(index) == segments_count1,
|
||||
rescale_policy,
|
||||
turns, interrupt_policy);
|
||||
// Future performance enhancement:
|
||||
@@ -639,7 +645,8 @@ private:
|
||||
box_point_type const& bp1,
|
||||
box_point_type const& bp2,
|
||||
box_point_type const& bp3,
|
||||
std::size_t segments_count1,
|
||||
bool const is_range_first,
|
||||
bool const is_range_last,
|
||||
RescalePolicy const& rescale_policy,
|
||||
// Output
|
||||
Turns& turns,
|
||||
@@ -658,22 +665,26 @@ private:
|
||||
|
||||
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 0);
|
||||
TurnPolicy::apply(rp0, rp1, rp2, bp0, bp1, bp2,
|
||||
segments_count1, 4,
|
||||
is_range_first, is_range_last,
|
||||
true, false,
|
||||
ti, rescale_policy, std::back_inserter(turns));
|
||||
|
||||
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 1);
|
||||
TurnPolicy::apply(rp0, rp1, rp2, bp1, bp2, bp3,
|
||||
segments_count1, 4,
|
||||
is_range_first, is_range_last,
|
||||
false, false,
|
||||
ti, rescale_policy, std::back_inserter(turns));
|
||||
|
||||
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 2);
|
||||
TurnPolicy::apply(rp0, rp1, rp2, bp2, bp3, bp0,
|
||||
segments_count1, 4,
|
||||
is_range_first, is_range_last,
|
||||
false, false,
|
||||
ti, rescale_policy, std::back_inserter(turns));
|
||||
|
||||
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 3);
|
||||
TurnPolicy::apply(rp0, rp1, rp2, bp3, bp0, bp1,
|
||||
segments_count1, 4,
|
||||
is_range_first, is_range_last,
|
||||
false, true,
|
||||
ti, rescale_policy, std::back_inserter(turns));
|
||||
|
||||
if (InterruptPolicy::enabled)
|
||||
@@ -738,9 +749,15 @@ struct get_turns_polygon_cs
|
||||
|
||||
// GET_TURN_INFO_TYPE
|
||||
|
||||
template <typename Geometry>
|
||||
struct topological_tag_base
|
||||
{
|
||||
typedef typename tag_cast<typename tag<Geometry>::type, pointlike_tag, linear_tag, areal_tag>::type type;
|
||||
};
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename AssignPolicy,
|
||||
typename Tag1 = typename tag<Geometry1>::type, typename Tag2 = typename tag<Geometry2>::type,
|
||||
typename TagBase1 = typename group_tag<Geometry1>::type, typename TagBase2 = typename group_tag<Geometry2>::type>
|
||||
typename TagBase1 = typename topological_tag_base<Geometry1>::type, typename TagBase2 = typename topological_tag_base<Geometry2>::type>
|
||||
struct get_turn_info_type
|
||||
: overlay::get_turn_info<AssignPolicy>
|
||||
{};
|
||||
@@ -757,7 +774,7 @@ struct get_turn_info_type<Geometry1, Geometry2, AssignPolicy, Tag1, Tag2, linear
|
||||
|
||||
template <typename Geometry1, typename Geometry2,
|
||||
typename Tag1 = typename tag<Geometry1>::type, typename Tag2 = typename tag<Geometry2>::type,
|
||||
typename TagBase1 = typename group_tag<Geometry1>::type, typename TagBase2 = typename group_tag<Geometry2>::type>
|
||||
typename TagBase1 = typename topological_tag_base<Geometry1>::type, typename TagBase2 = typename topological_tag_base<Geometry2>::type>
|
||||
struct turn_operation_type
|
||||
{
|
||||
typedef overlay::turn_operation type;
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2013, 2014.
|
||||
// Modifications copyright (c) 2013-2014 Oracle and/or its affiliates.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RANGE_HELPERS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RANGE_HELPERS_HPP
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace range {
|
||||
|
||||
template <typename Range>
|
||||
inline typename boost::range_value<Range>::type const&
|
||||
at(Range const& rng, typename boost::range_size<Range>::type i)
|
||||
{
|
||||
BOOST_ASSERT(i < boost::size(rng));
|
||||
return *(boost::begin(rng) + i);
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
inline typename boost::range_value<Range>::type &
|
||||
at(Range & rng, typename boost::range_size<Range>::type i)
|
||||
{
|
||||
BOOST_ASSERT(i < boost::size(rng));
|
||||
return *(boost::begin(rng) + i);
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
inline typename boost::range_value<Range>::type const&
|
||||
front(Range const& rng)
|
||||
{
|
||||
BOOST_ASSERT(!boost::empty(rng));
|
||||
return *boost::begin(rng);
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
inline typename boost::range_value<Range>::type &
|
||||
front(Range & rng)
|
||||
{
|
||||
BOOST_ASSERT(!boost::empty(rng));
|
||||
return *boost::begin(rng);
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
inline typename boost::range_value<Range>::type const&
|
||||
back(Range const& rng)
|
||||
{
|
||||
BOOST_ASSERT(!boost::empty(rng));
|
||||
return *(--boost::end(rng));
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
inline typename boost::range_value<Range>::type &
|
||||
back(Range & rng)
|
||||
{
|
||||
BOOST_ASSERT(!boost::empty(rng));
|
||||
return *(--boost::end(rng));
|
||||
}
|
||||
|
||||
}} // namespace detail::range
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RANGE_HELPERS_HPP
|
||||
@@ -11,8 +11,10 @@
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_BOUNDARY_CHECKER_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_BOUNDARY_CHECKER_HPP
|
||||
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/sub_range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/range_helpers.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
@@ -112,14 +114,14 @@ public:
|
||||
|
||||
if ( BoundaryQuery == boundary_back )
|
||||
{
|
||||
if ( sid.segment_index + 2 != geometry::num_points(sub_geometry::get(geometry, sid)) )
|
||||
if ( sid.segment_index + 2 != geometry::num_points(sub_range(geometry, sid)) )
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( BoundaryQuery == boundary_any )
|
||||
{
|
||||
if ( sid.segment_index != 0
|
||||
&& sid.segment_index + 2 != geometry::num_points(sub_geometry::get(geometry, sid)) )
|
||||
&& sid.segment_index + 2 != geometry::num_points(sub_range(geometry, sid)) )
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,47 +18,37 @@
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace relate {
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace detail_dispatch { namespace relate {
|
||||
|
||||
// TODO: should this be integrated with geometry::less?
|
||||
// TODO: Integrate it with geometry::less?
|
||||
|
||||
template
|
||||
<
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
std::size_t I = 0,
|
||||
std::size_t D1 = geometry::dimension<Point1>::value,
|
||||
std::size_t D2 = geometry::dimension<Point2>::value
|
||||
>
|
||||
struct less_dispatch
|
||||
: not_implemented<Point1, Point2>
|
||||
{};
|
||||
|
||||
|
||||
template<typename Point1, typename Point2, std::size_t I, std::size_t D>
|
||||
struct less_dispatch<Point1, Point2, I, D, D>
|
||||
template <typename Point1,
|
||||
typename Point2,
|
||||
std::size_t I = 0,
|
||||
std::size_t D = geometry::dimension<Point1>::value>
|
||||
struct less
|
||||
{
|
||||
static inline bool apply(Point1 const& l, Point2 const& r)
|
||||
static inline bool apply(Point1 const& left, Point2 const& right)
|
||||
{
|
||||
typename geometry::coordinate_type<Point1>::type
|
||||
cl = geometry::get<I>(l);
|
||||
cleft = geometry::get<I>(left);
|
||||
typename geometry::coordinate_type<Point2>::type
|
||||
cr = geometry::get<I>(r);
|
||||
cright = geometry::get<I>(right);
|
||||
|
||||
if ( geometry::math::equals(cl, cr) )
|
||||
if ( geometry::math::equals(cleft, cright) )
|
||||
{
|
||||
return less_dispatch<Point1, Point2, I + 1, D, D>::apply(l, r);
|
||||
return less<Point1, Point2, I + 1, D>::apply(left, right);
|
||||
}
|
||||
else
|
||||
{
|
||||
return cl < cr;
|
||||
return cleft < cright;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Point1, typename Point2, std::size_t D>
|
||||
struct less_dispatch<Point1, Point2, D, D, D>
|
||||
struct less<Point1, Point2, D, D>
|
||||
{
|
||||
static inline bool apply(Point1 const&, Point2 const&)
|
||||
{
|
||||
@@ -66,12 +56,19 @@ struct less_dispatch<Point1, Point2, D, D, D>
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail_dispatch::relate
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace relate {
|
||||
|
||||
struct less
|
||||
{
|
||||
template <typename Point1, typename Point2>
|
||||
inline bool operator()(Point1 const& point1, Point2 const& point2) const
|
||||
{
|
||||
return less_dispatch<Point1, Point2>::apply(point1, point2);
|
||||
return detail_dispatch::relate::less<Point1, Point2>::apply(point1, point2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -14,9 +14,10 @@
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LINEAR_AREAL_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LINEAR_AREAL_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/detail/group_dim.hpp>
|
||||
#include <boost/geometry/algorithms/detail/sub_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/detail/range_helpers.hpp>
|
||||
#include <boost/geometry/core/topological_dimension.hpp>
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/sub_range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/relate/point_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/turns.hpp>
|
||||
@@ -185,8 +186,8 @@ template <typename Geometry1, typename Geometry2, bool TransposeResult = false>
|
||||
struct linear_areal
|
||||
{
|
||||
// check Linear / Areal
|
||||
BOOST_STATIC_ASSERT(detail::group_dim<Geometry1>::value == 1
|
||||
&& detail::group_dim<Geometry2>::value == 2);
|
||||
BOOST_STATIC_ASSERT(topological_dimension<Geometry1>::value == 1
|
||||
&& topological_dimension<Geometry2>::value == 2);
|
||||
|
||||
static const bool interruption_enabled = true;
|
||||
|
||||
@@ -607,6 +608,7 @@ struct linear_areal
|
||||
&& !fake_enter_detected
|
||||
&& it->operations[op_id].position != overlay::position_front )
|
||||
{
|
||||
// TODO: calculate_from_inside() is only needed if the current Linestring is not closed
|
||||
bool from_inside = first_in_range
|
||||
&& calculate_from_inside(geometry,
|
||||
other_geometry,
|
||||
@@ -621,7 +623,7 @@ struct linear_areal
|
||||
if ( first_in_range )
|
||||
{
|
||||
bool front_b = is_endpoint_on_boundary<boundary_front>(
|
||||
range::front(sub_geometry::get(geometry, seg_id)),
|
||||
range::front(sub_range(geometry, seg_id)),
|
||||
boundary_checker);
|
||||
|
||||
// if there is a boundary on the first point
|
||||
@@ -692,6 +694,7 @@ struct linear_areal
|
||||
// TODO: very similar code is used in the handling of intersection
|
||||
if ( it->operations[op_id].position != overlay::position_front )
|
||||
{
|
||||
// TODO: calculate_from_inside() is only needed if the current Linestring is not closed
|
||||
bool first_from_inside = first_in_range
|
||||
&& calculate_from_inside(geometry,
|
||||
other_geometry,
|
||||
@@ -712,7 +715,7 @@ struct linear_areal
|
||||
if ( first_in_range && ( !this_b || op_blocked ) )
|
||||
{
|
||||
bool front_b = is_endpoint_on_boundary<boundary_front>(
|
||||
range::front(sub_geometry::get(geometry, seg_id)),
|
||||
range::front(sub_range(geometry, seg_id)),
|
||||
boundary_checker);
|
||||
|
||||
// if there is a boundary on the first point
|
||||
@@ -758,7 +761,7 @@ struct linear_areal
|
||||
segment_identifier const& prev_seg_id = m_previous_turn_ptr->operations[op_id].seg_id;
|
||||
|
||||
bool prev_back_b = is_endpoint_on_boundary<boundary_back>(
|
||||
range::back(sub_geometry::get(geometry, prev_seg_id)),
|
||||
range::back(sub_range(geometry, prev_seg_id)),
|
||||
boundary_checker);
|
||||
|
||||
// if there is a boundary on the last point
|
||||
@@ -779,7 +782,7 @@ struct linear_areal
|
||||
segment_identifier const& prev_seg_id = m_previous_turn_ptr->operations[op_id].seg_id;
|
||||
|
||||
bool prev_back_b = is_endpoint_on_boundary<boundary_back>(
|
||||
range::back(sub_geometry::get(geometry, prev_seg_id)),
|
||||
range::back(sub_range(geometry, prev_seg_id)),
|
||||
boundary_checker);
|
||||
|
||||
// if there is a boundary on the last point
|
||||
@@ -832,10 +835,10 @@ struct linear_areal
|
||||
reverse2 ? iterate_reverse : iterate_forward
|
||||
>::type range2_view;
|
||||
|
||||
typedef typename sub_geometry::result_type<Geometry1 const>::type range1_ref;
|
||||
typedef typename sub_range_return_type<Geometry1 const>::type range1_ref;
|
||||
|
||||
range1_ref range1 = sub_geometry::get(geometry1, turn.operations[op_id].seg_id);
|
||||
range2_cview const cview(sub_geometry::get(geometry2, turn.operations[other_op_id].seg_id));
|
||||
range1_ref range1 = sub_range(geometry1, turn.operations[op_id].seg_id);
|
||||
range2_cview const cview(sub_range(geometry2, turn.operations[other_op_id].seg_id));
|
||||
range2_view const range2(cview);
|
||||
|
||||
std::size_t s1 = boost::size(range1);
|
||||
@@ -855,18 +858,23 @@ struct linear_areal
|
||||
geometry::convert(qi, qi_conv);
|
||||
bool is_ip_qj = equals::equals_point_point(turn.point, qj);
|
||||
// TODO: test this!
|
||||
BOOST_ASSERT(!equals::equals_point_point(turn.point, pi));
|
||||
BOOST_ASSERT(!equals::equals_point_point(turn.point, qi));
|
||||
// BOOST_ASSERT(!equals::equals_point_point(turn.point, pi));
|
||||
// BOOST_ASSERT(!equals::equals_point_point(turn.point, qi));
|
||||
point1_type new_pj;
|
||||
geometry::convert(turn.point, new_pj);
|
||||
|
||||
if ( is_ip_qj )
|
||||
{
|
||||
std::size_t q_seg_jk = (q_seg_ij + 1) % seg_count2;
|
||||
BOOST_ASSERT(q_seg_jk + 1 < s2);
|
||||
point2_type const& qk = range::at(range2, q_seg_jk + 1);
|
||||
// Will this sequence of point be always correct?
|
||||
overlay::side_calculator<point1_type, point2_type> side_calc(qi_conv, new_pj, pi, qi, qj, qk);
|
||||
// TODO: the following function should return immediately, however the worst case complexity is O(N)
|
||||
// It would be good to replace it with some O(1) mechanism
|
||||
typename boost::range_iterator<range2_view>::type
|
||||
qk_it = find_next_non_duplicated(boost::begin(range2),
|
||||
boost::begin(range2) + q_seg_jk,
|
||||
boost::end(range2));
|
||||
|
||||
// Will this sequence of points be always correct?
|
||||
overlay::side_calculator<point1_type, point2_type> side_calc(qi_conv, new_pj, pi, qi, qj, *qk_it);
|
||||
|
||||
return calculate_from_inside_sides(side_calc);
|
||||
}
|
||||
@@ -881,6 +889,29 @@ struct linear_areal
|
||||
}
|
||||
}
|
||||
|
||||
template <typename It>
|
||||
static inline It find_next_non_duplicated(It first, It current, It last)
|
||||
{
|
||||
BOOST_ASSERT( current != last );
|
||||
|
||||
It it = current;
|
||||
|
||||
for ( ++it ; it != last ; ++it )
|
||||
{
|
||||
if ( !equals::equals_point_point(*current, *it) )
|
||||
return it;
|
||||
}
|
||||
|
||||
// if not found start from the beginning
|
||||
for ( it = first ; it != current ; ++it )
|
||||
{
|
||||
if ( !equals::equals_point_point(*current, *it) )
|
||||
return it;
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
// calculate inside or outside based on side_calc
|
||||
// this is simplified version of a check from equal<>
|
||||
template <typename SideCalc>
|
||||
|
||||
@@ -14,8 +14,9 @@
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LINEAR_LINEAR_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LINEAR_LINEAR_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/detail/sub_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/detail/range_helpers.hpp>
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/sub_range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/relate/point_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/turns.hpp>
|
||||
@@ -454,7 +455,7 @@ struct linear_linear
|
||||
if ( first_in_range )
|
||||
{
|
||||
bool front_b = is_endpoint_on_boundary<boundary_front>(
|
||||
range::front(sub_geometry::get(geometry, seg_id)),
|
||||
range::front(sub_range(geometry, seg_id)),
|
||||
boundary_checker);
|
||||
|
||||
// if there is a boundary on the first point
|
||||
@@ -529,7 +530,7 @@ struct linear_linear
|
||||
if ( first_in_range )
|
||||
{
|
||||
bool front_b = is_endpoint_on_boundary<boundary_front>(
|
||||
range::front(sub_geometry::get(geometry, seg_id)),
|
||||
range::front(sub_range(geometry, seg_id)),
|
||||
boundary_checker);
|
||||
|
||||
// if there is a boundary on the first point
|
||||
@@ -557,25 +558,33 @@ struct linear_linear
|
||||
{
|
||||
// it's also the boundary of the other geometry
|
||||
if ( other_b )
|
||||
{
|
||||
update<boundary, boundary, '0', transpose_result>(res);
|
||||
}
|
||||
else
|
||||
{
|
||||
update<boundary, interior, '0', transpose_result>(res);
|
||||
}
|
||||
}
|
||||
// if current IP is not on boundary of the geometry
|
||||
else
|
||||
{
|
||||
// it's also the boundary of the other geometry
|
||||
if ( other_b )
|
||||
{
|
||||
update<interior, boundary, '0', transpose_result>(res);
|
||||
}
|
||||
else
|
||||
{
|
||||
update<interior, interior, '0', transpose_result>(res);
|
||||
}
|
||||
}
|
||||
|
||||
// first IP on the last segment point - this means that the first point is outside
|
||||
if ( first_in_range && ( !this_b || op_blocked ) && was_outside /*&& !is_collinear*/ )
|
||||
{
|
||||
bool front_b = is_endpoint_on_boundary<boundary_front>(
|
||||
range::front(sub_geometry::get(geometry, seg_id)),
|
||||
range::front(sub_range(geometry, seg_id)),
|
||||
boundary_checker);
|
||||
|
||||
// if there is a boundary on the first point
|
||||
@@ -611,7 +620,7 @@ struct linear_linear
|
||||
segment_identifier const& prev_seg_id = m_previous_turn_ptr->operations[op_id].seg_id;
|
||||
|
||||
bool prev_back_b = is_endpoint_on_boundary<boundary_back>(
|
||||
range::back(sub_geometry::get(geometry, prev_seg_id)),
|
||||
range::back(sub_range(geometry, prev_seg_id)),
|
||||
boundary_checker);
|
||||
|
||||
// if there is a boundary on the last point
|
||||
|
||||
@@ -15,8 +15,15 @@
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP
|
||||
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/mpl/vector_c.hpp>
|
||||
|
||||
#include <boost/mpl/is_sequence.hpp>
|
||||
#include <boost/mpl/begin.hpp>
|
||||
#include <boost/mpl/end.hpp>
|
||||
#include <boost/mpl/next.hpp>
|
||||
#include <boost/mpl/at.hpp>
|
||||
#include <boost/mpl/vector_c.hpp>
|
||||
|
||||
#include <boost/geometry/core/topological_dimension.hpp>
|
||||
|
||||
// TEMP - move this header to geometry/detail
|
||||
#include <boost/geometry/index/detail/tuples.hpp>
|
||||
@@ -796,8 +803,8 @@ typedef static_mask<'F', 'F', '*', 'F', 'F', '*', '*', '*', '*'> static_mask_dis
|
||||
// TOUCHES - NOT P/P
|
||||
template <typename Geometry1,
|
||||
typename Geometry2,
|
||||
std::size_t Dim1 = detail::group_dim<Geometry1>::value,
|
||||
std::size_t Dim2 = detail::group_dim<Geometry2>::value>
|
||||
std::size_t Dim1 = topological_dimension<Geometry1>::value,
|
||||
std::size_t Dim2 = topological_dimension<Geometry2>::value>
|
||||
struct static_mask_touches_type
|
||||
{
|
||||
typedef boost::mpl::vector<
|
||||
@@ -829,8 +836,8 @@ typedef boost::mpl::vector<
|
||||
// dim(G1) < dim(G2) - P/L P/A L/A
|
||||
template <typename Geometry1,
|
||||
typename Geometry2,
|
||||
std::size_t Dim1 = detail::group_dim<Geometry1>::value,
|
||||
std::size_t Dim2 = detail::group_dim<Geometry2>::value,
|
||||
std::size_t Dim1 = topological_dimension<Geometry1>::value,
|
||||
std::size_t Dim2 = topological_dimension<Geometry2>::value,
|
||||
bool D1LessD2 = (Dim1 < Dim2)
|
||||
>
|
||||
struct static_mask_crosses_type
|
||||
@@ -866,8 +873,8 @@ struct static_mask_crosses_type<Geometry1, Geometry2, 1, 1, D1LessD2>
|
||||
// dim(G1) != dim(G2) - NOT P/P, L/L, A/A
|
||||
template <typename Geometry1,
|
||||
typename Geometry2,
|
||||
std::size_t Dim1 = detail::group_dim<Geometry1>::value,
|
||||
std::size_t Dim2 = detail::group_dim<Geometry2>::value
|
||||
std::size_t Dim1 = topological_dimension<Geometry1>::value,
|
||||
std::size_t Dim2 = topological_dimension<Geometry2>::value
|
||||
>
|
||||
struct static_mask_overlaps_type
|
||||
: not_implemented<typename geometry::tag<Geometry1>::type,
|
||||
|
||||
@@ -11,8 +11,9 @@
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_TOPOLOGY_CHECK_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_TOPOLOGY_CHECK_HPP
|
||||
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/range_helpers.hpp>
|
||||
|
||||
namespace boost { namespace geometry {
|
||||
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2014.
|
||||
// Modifications copyright (c) 2014 Oracle and/or its affiliates.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
@@ -11,6 +14,8 @@
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_SECTIONALIZE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_SECTIONALIZE_HPP
|
||||
|
||||
@@ -72,6 +77,9 @@ struct section
|
||||
bool duplicate;
|
||||
int non_duplicate_index;
|
||||
|
||||
bool is_non_duplicate_first;
|
||||
bool is_non_duplicate_last;
|
||||
|
||||
inline section()
|
||||
: id(-1)
|
||||
, begin_index(-1)
|
||||
@@ -80,6 +88,8 @@ struct section
|
||||
, range_count(0)
|
||||
, duplicate(false)
|
||||
, non_duplicate_index(-1)
|
||||
, is_non_duplicate_first(false)
|
||||
, is_non_duplicate_last(false)
|
||||
{
|
||||
assign_inverse(bounding_box);
|
||||
for (std::size_t i = 0; i < DimensionCount; i++)
|
||||
@@ -251,13 +261,11 @@ struct sectionalize_part
|
||||
typename Sections
|
||||
>
|
||||
static inline void apply(Sections& sections,
|
||||
typename boost::range_value<Sections>::type& section,
|
||||
int& index, int& ndi,
|
||||
Range const& range,
|
||||
RescalePolicy const& rescale_policy,
|
||||
bool make_rescaled_boxes,
|
||||
ring_identifier ring_id,
|
||||
std::size_t max_count)
|
||||
Range const& range,
|
||||
RescalePolicy const& rescale_policy,
|
||||
bool make_rescaled_boxes,
|
||||
ring_identifier ring_id,
|
||||
std::size_t max_count)
|
||||
{
|
||||
boost::ignore_unused_variable_warning(rescale_policy);
|
||||
boost::ignore_unused_variable_warning(make_rescaled_boxes);
|
||||
@@ -267,19 +275,20 @@ struct sectionalize_part
|
||||
|
||||
typedef typename boost::range_iterator<Range const>::type iterator_type;
|
||||
|
||||
if (int(boost::size(range)) <= index)
|
||||
if ( boost::empty(range) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
ndi = 0;
|
||||
}
|
||||
int index = 0;
|
||||
int ndi = 0; // non duplicate index
|
||||
section_type section;
|
||||
|
||||
bool mark_first_non_duplicated = true;
|
||||
std::size_t last_non_duplicate_index = 0;
|
||||
|
||||
iterator_type it = boost::begin(range);
|
||||
it += index;
|
||||
|
||||
|
||||
for(iterator_type previous = it++;
|
||||
it != boost::end(range);
|
||||
++previous, ++it, index++)
|
||||
@@ -329,6 +338,11 @@ struct sectionalize_part
|
||||
)
|
||||
)
|
||||
{
|
||||
if ( !section.duplicate )
|
||||
{
|
||||
last_non_duplicate_index = sections.size();
|
||||
}
|
||||
|
||||
sections.push_back(section);
|
||||
section = section_type();
|
||||
}
|
||||
@@ -341,6 +355,12 @@ struct sectionalize_part
|
||||
section.non_duplicate_index = ndi;
|
||||
section.range_count = boost::size(range);
|
||||
|
||||
if ( mark_first_non_duplicated && !duplicate )
|
||||
{
|
||||
section.is_non_duplicate_first = true;
|
||||
mark_first_non_duplicated = false;
|
||||
}
|
||||
|
||||
copy_loop
|
||||
<
|
||||
int, 0, DimensionCount
|
||||
@@ -356,6 +376,23 @@ struct sectionalize_part
|
||||
ndi++;
|
||||
}
|
||||
}
|
||||
|
||||
// Add last section if applicable
|
||||
if (section.count > 0)
|
||||
{
|
||||
if ( !section.duplicate )
|
||||
{
|
||||
last_non_duplicate_index = sections.size();
|
||||
}
|
||||
|
||||
sections.push_back(section);
|
||||
}
|
||||
|
||||
if ( last_non_duplicate_index < sections.size()
|
||||
&& !sections[last_non_duplicate_index].duplicate )
|
||||
{
|
||||
sections[last_non_duplicate_index].is_non_duplicate_last = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -375,10 +412,11 @@ struct sectionalize_range
|
||||
typename Sections
|
||||
>
|
||||
static inline void apply(Range const& range,
|
||||
RescalePolicy const& rescale_policy,
|
||||
bool make_rescaled_boxes,
|
||||
Sections& sections,
|
||||
ring_identifier ring_id, std::size_t max_count)
|
||||
RescalePolicy const& rescale_policy,
|
||||
bool make_rescaled_boxes,
|
||||
Sections& sections,
|
||||
ring_identifier ring_id,
|
||||
std::size_t max_count)
|
||||
{
|
||||
typedef typename closeable_view<Range const, Closure>::type cview_type;
|
||||
typedef typename reversible_view
|
||||
@@ -403,20 +441,8 @@ struct sectionalize_range
|
||||
return;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
int ndi = 0; // non duplicate index
|
||||
|
||||
typedef typename boost::range_value<Sections>::type section_type;
|
||||
section_type section;
|
||||
|
||||
sectionalize_part<Point, DimensionCount>
|
||||
::apply(sections, section, index, ndi, view, rescale_policy, make_rescaled_boxes, ring_id, max_count);
|
||||
|
||||
// Add last section if applicable
|
||||
if (section.count > 0)
|
||||
{
|
||||
sections.push_back(section);
|
||||
}
|
||||
::apply(sections, view, rescale_policy, make_rescaled_boxes, ring_id, max_count);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2013, 2014.
|
||||
// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_GEOMETRY_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_GEOMETRY_HPP
|
||||
|
||||
namespace boost { namespace geometry {
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace sub_geometry {
|
||||
|
||||
// TODO: later implement Geometry-specialized index_type
|
||||
// polygons/multi_polygons also need ring_index member
|
||||
struct index_type
|
||||
{
|
||||
index_type() : multi_index(-1) {}
|
||||
|
||||
int multi_index;
|
||||
|
||||
inline bool operator<(index_type const& i) const
|
||||
{
|
||||
return multi_index < i.multi_index;
|
||||
}
|
||||
|
||||
inline bool operator==(index_type const& i) const
|
||||
{
|
||||
return multi_index == i.multi_index;
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::sub_geometry
|
||||
|
||||
namespace detail_dispatch { namespace sub_geometry {
|
||||
|
||||
// TODO: later remove IsMulti and move to multi directory
|
||||
template <typename Geometry,
|
||||
typename Tag = typename geometry::tag<Geometry>::type,
|
||||
bool IsMulti = boost::is_base_of<multi_tag, Tag>::value>
|
||||
struct get : not_implemented<Tag>
|
||||
{};
|
||||
|
||||
template <typename Geometry, typename Tag>
|
||||
struct get<Geometry, Tag, false>
|
||||
{
|
||||
typedef Geometry & result_type;
|
||||
|
||||
template <typename Id> static inline
|
||||
result_type apply(Geometry & geometry, Id const&)
|
||||
{
|
||||
return geometry;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct get<Geometry, polygon_tag, false>
|
||||
{
|
||||
typedef typename geometry::ring_type<Geometry>::type & result_type;
|
||||
|
||||
template <typename Id> static inline
|
||||
result_type apply(Geometry & geometry, Id const& id)
|
||||
{
|
||||
if ( id.ring_index < 0 )
|
||||
{
|
||||
return geometry::exterior_ring(geometry);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::size_t ri = static_cast<std::size_t>(id.ring_index);
|
||||
BOOST_ASSERT( ri < boost::size(geometry::interior_rings(geometry)) );
|
||||
|
||||
return *(boost::begin(geometry::interior_rings(geometry)) + ri);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry, typename Tag>
|
||||
struct get<Geometry, Tag, true>
|
||||
{
|
||||
typedef typename boost::range_value<Geometry>::type value_type;
|
||||
typedef typename boost::mpl::if_c
|
||||
<
|
||||
boost::is_const<Geometry>::value,
|
||||
typename boost::add_const<value_type>::type,
|
||||
value_type
|
||||
>::type sub_type;
|
||||
typedef detail_dispatch::sub_geometry::get<sub_type> get_type;
|
||||
typedef typename get_type::result_type result_type;
|
||||
|
||||
template <typename Id> static inline
|
||||
result_type apply(Geometry & geometry, Id const& id)
|
||||
{
|
||||
BOOST_ASSERT(0 <= id.multi_index);
|
||||
return get_type::apply(*(boost::begin(geometry) + id.multi_index), id);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail_dispatch::sub_geometry
|
||||
|
||||
namespace detail { namespace sub_geometry {
|
||||
|
||||
template <typename Geometry>
|
||||
struct result_type
|
||||
{
|
||||
typedef typename detail_dispatch::sub_geometry::get<Geometry>::result_type type;
|
||||
};
|
||||
|
||||
// This function also works for geometry::segment_identifier
|
||||
|
||||
template <typename Geometry, typename Id> inline
|
||||
typename detail_dispatch::sub_geometry::get<Geometry>::result_type
|
||||
get(Geometry & geometry, Id const& id)
|
||||
{
|
||||
return detail_dispatch::sub_geometry::get<Geometry>::apply(geometry, id);
|
||||
};
|
||||
|
||||
}} // namespace detail::sub_geometry
|
||||
#endif
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_GEOMETRY_HPP
|
||||
113
include/boost/geometry/algorithms/detail/sub_range.hpp
Normal file
113
include/boost/geometry/algorithms/detail/sub_range.hpp
Normal file
@@ -0,0 +1,113 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2013, 2014.
|
||||
// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP
|
||||
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
namespace boost { namespace geometry {
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace detail_dispatch {
|
||||
|
||||
template <typename Geometry,
|
||||
typename Tag = typename geometry::tag<Geometry>::type,
|
||||
bool IsMulti = boost::is_base_of<multi_tag, Tag>::value>
|
||||
struct sub_range : not_implemented<Tag>
|
||||
{};
|
||||
|
||||
template <typename Geometry, typename Tag>
|
||||
struct sub_range<Geometry, Tag, false>
|
||||
{
|
||||
typedef Geometry & return_type;
|
||||
|
||||
template <typename Id> static inline
|
||||
return_type apply(Geometry & geometry, Id const&)
|
||||
{
|
||||
return geometry;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct sub_range<Geometry, polygon_tag, false>
|
||||
{
|
||||
typedef typename geometry::ring_type<Geometry>::type & return_type;
|
||||
|
||||
template <typename Id> static inline
|
||||
return_type apply(Geometry & geometry, Id const& id)
|
||||
{
|
||||
if ( id.ring_index < 0 )
|
||||
{
|
||||
return geometry::exterior_ring(geometry);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::size_t ri = static_cast<std::size_t>(id.ring_index);
|
||||
return range::at(geometry::interior_rings(geometry), ri);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry, typename Tag>
|
||||
struct sub_range<Geometry, Tag, true>
|
||||
{
|
||||
typedef typename boost::range_value<Geometry>::type value_type;
|
||||
typedef typename boost::mpl::if_c
|
||||
<
|
||||
boost::is_const<Geometry>::value,
|
||||
typename boost::add_const<value_type>::type,
|
||||
value_type
|
||||
>::type sub_type;
|
||||
|
||||
typedef detail_dispatch::sub_range<sub_type> sub_sub_range;
|
||||
|
||||
// TODO: shouldn't it be return_type?
|
||||
typedef typename sub_sub_range::return_type return_type;
|
||||
|
||||
template <typename Id> static inline
|
||||
return_type apply(Geometry & geometry, Id const& id)
|
||||
{
|
||||
BOOST_ASSERT(0 <= id.multi_index);
|
||||
return sub_sub_range::apply(range::at(geometry, id.multi_index), id);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail_dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Geometry>
|
||||
struct sub_range_return_type
|
||||
{
|
||||
typedef typename detail_dispatch::sub_range<Geometry>::return_type type;
|
||||
};
|
||||
|
||||
// This function also works for geometry::segment_identifier
|
||||
|
||||
template <typename Geometry, typename Id> inline
|
||||
typename sub_range_return_type<Geometry>::type
|
||||
sub_range(Geometry & geometry, Id const& id)
|
||||
{
|
||||
return detail_dispatch::sub_range<Geometry>::apply(geometry, id);
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <boost/geometry/algorithms/disjoint.hpp>
|
||||
#include <boost/geometry/algorithms/intersects.hpp>
|
||||
#include <boost/geometry/algorithms/num_geometries.hpp>
|
||||
#include <boost/geometry/algorithms/detail/sub_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/detail/sub_range.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
@@ -207,8 +207,8 @@ struct linear_areal_interrupt_policy
|
||||
template <typename Turn>
|
||||
inline bool is_turn_on_last_point(Turn const& turn)
|
||||
{
|
||||
typename sub_geometry::result_type<Linear const>::type
|
||||
g = sub_geometry::get(linear, turn.operations[0].seg_id);
|
||||
typename sub_range_return_type<Linear const>::type
|
||||
g = sub_range(linear, turn.operations[0].seg_id);
|
||||
|
||||
std::size_t s = boost::size(g);
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2013.
|
||||
// Modifications copyright (c) 2013, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013, 2014.
|
||||
// Modifications copyright (c) 2013, 2014 Oracle and/or its affiliates.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
@@ -14,6 +14,8 @@
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_WITHIN_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_WITHIN_HPP
|
||||
|
||||
@@ -61,81 +63,21 @@ namespace boost { namespace geometry
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace within {
|
||||
|
||||
// currently works only for linestrings
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct linear_linear
|
||||
struct use_point_in_geometry
|
||||
{
|
||||
template <typename Strategy>
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
|
||||
{
|
||||
return detail::within::point_in_geometry(geometry1, geometry2, strategy) == 1;
|
||||
}
|
||||
};
|
||||
|
||||
struct use_relate
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& /*strategy*/)
|
||||
{
|
||||
// TODO within() should return FALSE if a length(geometry1) == 0 and is contained entirely within a boundary,
|
||||
// also if geometry2 has length(geometry2) == 0, it should be considered as a point.
|
||||
|
||||
// TODO: currently only for linestrings
|
||||
std::size_t s1 = boost::size(geometry1);
|
||||
std::size_t s2 = boost::size(geometry2);
|
||||
if ( s1 == 0 || s2 == 0 || s2 == 1 )
|
||||
return false;
|
||||
if ( s1 == 1 && s2 == 1 ) // within(Pt, Pt)
|
||||
return false;
|
||||
if ( s1 == 1 )
|
||||
return point_in_geometry(*boost::begin(geometry1), geometry2) > 0;
|
||||
|
||||
typedef typename geometry::point_type<Geometry1>::type point1_type;
|
||||
typedef detail::overlay::turn_info<point1_type> turn_info;
|
||||
|
||||
typedef detail::overlay::get_turn_info
|
||||
<
|
||||
detail::overlay::assign_null_policy
|
||||
> policy_type;
|
||||
|
||||
std::deque<turn_info> turns;
|
||||
|
||||
detail::get_turns::no_interrupt_policy policy;
|
||||
boost::geometry::get_turns
|
||||
<
|
||||
detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value, // should be false
|
||||
detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value, // should be false
|
||||
detail::overlay::assign_null_policy
|
||||
>(geometry1, geometry2, detail::no_rescale_policy(), turns, policy);
|
||||
|
||||
return analyse_turns(turns.begin(), turns.end())
|
||||
// TODO: currently only for linestrings
|
||||
&& point_in_geometry(*boost::begin(geometry1), geometry2) >= 0
|
||||
&& point_in_geometry(*(boost::end(geometry1) - 1), geometry2) >= 0;
|
||||
}
|
||||
|
||||
template <typename TurnIt>
|
||||
static inline bool analyse_turns(TurnIt first, TurnIt last)
|
||||
{
|
||||
bool has_turns = false;
|
||||
for ( TurnIt it = first ; it != last ; ++it )
|
||||
{
|
||||
switch ( it->method )
|
||||
{
|
||||
case overlay::method_crosses:
|
||||
return false;
|
||||
case overlay::method_touch:
|
||||
case overlay::method_touch_interior:
|
||||
if ( it->both(overlay::operation_continue)
|
||||
|| it->both(overlay::operation_blocked) )
|
||||
{
|
||||
has_turns = true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
case overlay::method_equal:
|
||||
case overlay::method_collinear:
|
||||
has_turns = true;
|
||||
break;
|
||||
case overlay::method_none :
|
||||
case overlay::method_disjoint :
|
||||
case overlay::method_error :
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return has_turns;
|
||||
return Strategy::apply(geometry1, geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -180,48 +122,73 @@ struct within<Box1, Box2, box_tag, box_tag>
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// P/A
|
||||
|
||||
template <typename Point, typename Ring>
|
||||
struct within<Point, Ring, point_tag, ring_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Point const& point, Ring const& ring, Strategy const& strategy)
|
||||
{
|
||||
return detail::within::point_in_geometry(point, ring, strategy) == 1;
|
||||
}
|
||||
};
|
||||
: public detail::within::use_point_in_geometry
|
||||
{};
|
||||
|
||||
template <typename Point, typename Polygon>
|
||||
struct within<Point, Polygon, point_tag, polygon_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Point const& point, Polygon const& polygon, Strategy const& strategy)
|
||||
{
|
||||
return detail::within::point_in_geometry(point, polygon, strategy) == 1;
|
||||
}
|
||||
};
|
||||
: public detail::within::use_point_in_geometry
|
||||
{};
|
||||
|
||||
// P/L
|
||||
|
||||
template <typename Point, typename Linestring>
|
||||
struct within<Point, Linestring, point_tag, linestring_tag>
|
||||
{
|
||||
template <typename Strategy> static inline
|
||||
bool apply(Point const& point, Linestring const& linestring, Strategy const& strategy)
|
||||
{
|
||||
return detail::within::point_in_geometry(point, linestring, strategy) == 1;
|
||||
}
|
||||
};
|
||||
: public detail::within::use_point_in_geometry
|
||||
{};
|
||||
|
||||
// L/L
|
||||
|
||||
template <typename Linestring1, typename Linestring2>
|
||||
struct within<Linestring1, Linestring2, linestring_tag, linestring_tag>
|
||||
{
|
||||
template <typename Strategy> static inline
|
||||
bool apply(Linestring1 const& linestring1, Linestring2 const& linestring2, Strategy const& strategy)
|
||||
{
|
||||
return detail::within::linear_linear<Linestring1, Linestring2>
|
||||
::apply(linestring1, linestring2, strategy);
|
||||
}
|
||||
};
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename Linestring, typename MultiLinestring>
|
||||
struct within<Linestring, MultiLinestring, linestring_tag, multi_linestring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring, typename Linestring>
|
||||
struct within<MultiLinestring, Linestring, multi_linestring_tag, linestring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
// L/A
|
||||
|
||||
template <typename Linestring, typename Ring>
|
||||
struct within<Linestring, Ring, linestring_tag, ring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring, typename Ring>
|
||||
struct within<MultiLinestring, Ring, multi_linestring_tag, ring_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename Linestring, typename Polygon>
|
||||
struct within<Linestring, Polygon, linestring_tag, polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring, typename Polygon>
|
||||
struct within<MultiLinestring, Polygon, multi_linestring_tag, polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename Linestring, typename MultiPolygon>
|
||||
struct within<Linestring, MultiPolygon, linestring_tag, multi_polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring, typename MultiPolygon>
|
||||
struct within<MultiLinestring, MultiPolygon, multi_linestring_tag, multi_polygon_tag>
|
||||
: public detail::within::use_relate
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
109
include/boost/geometry/iterators/concatenate_iterator.hpp
Normal file
109
include/boost/geometry/iterators/concatenate_iterator.hpp
Normal file
@@ -0,0 +1,109 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ITERATORS_CONCATENATE_ITERATOR_HPP
|
||||
#define BOOST_GEOMETRY_ITERATORS_CONCATENATE_ITERATOR_HPP
|
||||
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
|
||||
template <typename Iterator1, typename Iterator2, typename Value>
|
||||
struct concatenate_iterator
|
||||
: public boost::iterator_facade
|
||||
<
|
||||
concatenate_iterator<Iterator1, Iterator2, Value>,
|
||||
Value,
|
||||
boost::forward_traversal_tag
|
||||
>
|
||||
{
|
||||
private:
|
||||
Iterator1 m_it1, m_end1;
|
||||
Iterator2 m_it2;
|
||||
|
||||
struct enabler {};
|
||||
|
||||
public:
|
||||
typedef Iterator1 first_iterator_type;
|
||||
typedef Iterator2 second_iterator_type;
|
||||
|
||||
// default constructor
|
||||
concatenate_iterator() {}
|
||||
|
||||
// for begin
|
||||
concatenate_iterator(Iterator1 it1, Iterator1 end1,
|
||||
Iterator2 it2)
|
||||
: m_it1(it1), m_end1(end1), m_it2(it2)
|
||||
{}
|
||||
|
||||
// for end
|
||||
concatenate_iterator(Iterator1 end1, Iterator2 end2)
|
||||
: m_it1(end1), m_end1(end1), m_it2(end2)
|
||||
{}
|
||||
|
||||
template <typename OtherIt1, typename OtherIt2, typename OtherValue>
|
||||
concatenate_iterator
|
||||
(concatenate_iterator<OtherIt1, OtherIt2, OtherValue> const& other,
|
||||
typename boost::enable_if_c
|
||||
<
|
||||
boost::is_convertible<OtherIt1, Iterator1>::value
|
||||
&& boost::is_convertible<OtherIt2, Iterator2>::value,
|
||||
enabler
|
||||
>::type = enabler())
|
||||
: m_it1(other.m_it1), m_end1(other.m_end1), m_it2(other.m_it2)
|
||||
{}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
template <typename It1, typename It2, typename V>
|
||||
friend class concatenate_iterator;
|
||||
|
||||
Value& dereference() const
|
||||
{
|
||||
if ( m_it1 == m_end1 )
|
||||
{
|
||||
return *m_it2;
|
||||
}
|
||||
return *m_it1;
|
||||
}
|
||||
|
||||
bool equal(concatenate_iterator const& other) const
|
||||
{
|
||||
return m_it1 == other.m_it1 && m_it2 == other.m_it2;
|
||||
}
|
||||
|
||||
void increment()
|
||||
{
|
||||
if ( m_it1 == m_end1 )
|
||||
{
|
||||
++m_it2;
|
||||
}
|
||||
else
|
||||
{
|
||||
++m_it1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ITERATORS_CONCATENATE_ITERATOR_HPP
|
||||
47
include/boost/geometry/iterators/dispatch/point_iterator.hpp
Normal file
47
include/boost/geometry/iterators/dispatch/point_iterator.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_HPP
|
||||
#define BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_HPP
|
||||
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
// dispatch for points_begin
|
||||
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
|
||||
struct points_begin
|
||||
: not_implemented<Geometry>
|
||||
{};
|
||||
|
||||
|
||||
|
||||
// dispatch for points_end
|
||||
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
|
||||
struct points_end
|
||||
: not_implemented<Geometry>
|
||||
{};
|
||||
|
||||
|
||||
|
||||
} // namespace core_dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_HPP
|
||||
@@ -0,0 +1,37 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_TYPE_HPP
|
||||
#define BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_TYPE_HPP
|
||||
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
|
||||
struct point_iterator_type
|
||||
: not_implemented<Geometry>
|
||||
{};
|
||||
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_TYPE_HPP
|
||||
208
include/boost/geometry/iterators/flatten_iterator.hpp
Normal file
208
include/boost/geometry/iterators/flatten_iterator.hpp
Normal file
@@ -0,0 +1,208 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ITERATORS_FLATTEN_ITERATOR_HPP
|
||||
#define BOOST_GEOMETRY_ITERATORS_FLATTEN_ITERATOR_HPP
|
||||
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename OuterIterator,
|
||||
typename InnerIterator,
|
||||
typename Value,
|
||||
typename AccessInnerBegin,
|
||||
typename AccessInnerEnd
|
||||
>
|
||||
struct flatten_iterator
|
||||
: public boost::iterator_facade
|
||||
<
|
||||
flatten_iterator
|
||||
<
|
||||
OuterIterator,
|
||||
InnerIterator,
|
||||
Value,
|
||||
AccessInnerBegin,
|
||||
AccessInnerEnd>,
|
||||
Value,
|
||||
boost::forward_traversal_tag
|
||||
>
|
||||
{
|
||||
private:
|
||||
OuterIterator m_outer_it, m_outer_end;
|
||||
InnerIterator m_inner_it;
|
||||
|
||||
struct enabler {};
|
||||
|
||||
public:
|
||||
typedef OuterIterator outer_iterator_type;
|
||||
typedef InnerIterator inner_iterator_type;
|
||||
|
||||
// default constructor
|
||||
flatten_iterator() {}
|
||||
|
||||
// for begin
|
||||
flatten_iterator(OuterIterator outer_it, OuterIterator outer_end)
|
||||
: m_outer_it(outer_it), m_outer_end(outer_end)
|
||||
{
|
||||
advance_through_empty();
|
||||
}
|
||||
|
||||
// for end
|
||||
flatten_iterator(OuterIterator outer_end)
|
||||
: m_outer_it(outer_end), m_outer_end(outer_end)
|
||||
{}
|
||||
|
||||
template
|
||||
<
|
||||
typename OtherOuterIterator, typename OtherInnerIterator,
|
||||
typename OtherValue,
|
||||
typename OtherAccessInnerBegin, typename OtherAccessInnerEnd
|
||||
>
|
||||
flatten_iterator(flatten_iterator
|
||||
<
|
||||
OtherOuterIterator,
|
||||
OtherInnerIterator,
|
||||
OtherValue,
|
||||
OtherAccessInnerBegin,
|
||||
OtherAccessInnerEnd
|
||||
> const& other,
|
||||
typename boost::enable_if
|
||||
<
|
||||
boost::is_convertible<OtherValue*, Value*>,
|
||||
enabler
|
||||
>::type = enabler())
|
||||
: m_outer_it(other.m_outer_it),
|
||||
m_outer_end(other.m_outer_end),
|
||||
m_inner_it(other.m_inner_it)
|
||||
{}
|
||||
|
||||
template
|
||||
<
|
||||
typename OtherOuterIterator,
|
||||
typename OtherInnerIterator,
|
||||
typename OtherValue,
|
||||
typename OtherAccessInnerBegin,
|
||||
typename OtherAccessInnerEnd
|
||||
>
|
||||
flatten_iterator operator=(flatten_iterator
|
||||
<
|
||||
OtherOuterIterator,
|
||||
OtherInnerIterator,
|
||||
OtherValue,
|
||||
OtherAccessInnerBegin,
|
||||
OtherAccessInnerEnd
|
||||
> const& other)
|
||||
{
|
||||
m_outer_it = other.m_outer_it;
|
||||
m_outer_end = other.m_outer_end;
|
||||
m_inner_it = other.m_inner_it;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
template
|
||||
<
|
||||
typename Outer,
|
||||
typename Inner,
|
||||
typename V,
|
||||
typename InnerBegin,
|
||||
typename InnerEnd
|
||||
>
|
||||
friend class flatten_iterator;
|
||||
|
||||
static inline bool empty(OuterIterator outer_it)
|
||||
{
|
||||
return
|
||||
AccessInnerBegin::apply(*outer_it) == AccessInnerEnd::apply(*outer_it);
|
||||
}
|
||||
|
||||
inline void advance_through_empty()
|
||||
{
|
||||
while ( m_outer_it != m_outer_end && empty(m_outer_it) )
|
||||
{
|
||||
++m_outer_it;
|
||||
}
|
||||
|
||||
if ( m_outer_it != m_outer_end )
|
||||
{
|
||||
m_inner_it = AccessInnerBegin::apply(*m_outer_it);
|
||||
}
|
||||
}
|
||||
|
||||
Value& dereference() const
|
||||
{
|
||||
BOOST_ASSERT( m_outer_it != m_outer_end );
|
||||
BOOST_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) );
|
||||
return *m_inner_it;
|
||||
}
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename OtherOuterIterator,
|
||||
typename OtherInnerIterator,
|
||||
typename OtherValue,
|
||||
typename OtherAccessInnerBegin,
|
||||
typename OtherAccessInnerEnd
|
||||
>
|
||||
inline bool equal(flatten_iterator
|
||||
<
|
||||
OtherOuterIterator,
|
||||
OtherInnerIterator,
|
||||
OtherValue,
|
||||
OtherAccessInnerBegin,
|
||||
OtherAccessInnerEnd
|
||||
> const& other) const
|
||||
{
|
||||
if ( this->m_outer_it != other.m_outer_it )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( this->m_outer_it == m_outer_end )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return this->m_inner_it == other.m_inner_it;
|
||||
}
|
||||
|
||||
inline void increment()
|
||||
{
|
||||
BOOST_ASSERT( m_outer_it != m_outer_end );
|
||||
BOOST_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) );
|
||||
|
||||
++m_inner_it;
|
||||
if ( m_inner_it == AccessInnerEnd::apply(*m_outer_it) )
|
||||
{
|
||||
++m_outer_it;
|
||||
advance_through_empty();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ITERATORS_FLATTEN_ITERATOR_HPP
|
||||
278
include/boost/geometry/iterators/point_iterator.hpp
Normal file
278
include/boost/geometry/iterators/point_iterator.hpp
Normal file
@@ -0,0 +1,278 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP
|
||||
#define BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP
|
||||
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/geometry/iterators/dispatch/point_iterator.hpp>
|
||||
#include <boost/geometry/iterators/point_iterator_type.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
// specializations for points_begin
|
||||
|
||||
|
||||
template <typename Linestring>
|
||||
struct points_begin<Linestring, linestring_tag>
|
||||
{
|
||||
static inline typename point_iterator_type<Linestring>::type
|
||||
apply(Linestring& linestring)
|
||||
{
|
||||
return boost::begin(linestring);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Ring>
|
||||
struct points_begin<Ring, ring_tag>
|
||||
{
|
||||
static inline typename point_iterator_type<Ring>::type
|
||||
apply(Ring& ring)
|
||||
{
|
||||
return boost::begin(ring);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Polygon>
|
||||
struct points_begin<Polygon, polygon_tag>
|
||||
{
|
||||
typedef typename point_iterator_type<Polygon>::type return_type;
|
||||
|
||||
static inline return_type apply(Polygon& polygon)
|
||||
{
|
||||
typedef typename return_type::second_iterator_type flatten_iterator;
|
||||
|
||||
return return_type
|
||||
(boost::begin(geometry::exterior_ring(polygon)),
|
||||
boost::end(geometry::exterior_ring(polygon)),
|
||||
flatten_iterator(boost::begin(geometry::interior_rings(polygon)),
|
||||
boost::end(geometry::interior_rings(polygon))
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename MultiPoint>
|
||||
struct points_begin<MultiPoint, multi_point_tag>
|
||||
{
|
||||
static inline typename point_iterator_type<MultiPoint>::type
|
||||
apply(MultiPoint& multipoint)
|
||||
{
|
||||
return boost::begin(multipoint);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename MultiLinestring>
|
||||
struct points_begin<MultiLinestring, multi_linestring_tag>
|
||||
{
|
||||
static inline typename point_iterator_type<MultiLinestring>::type
|
||||
apply(MultiLinestring& multilinestring)
|
||||
{
|
||||
return typename point_iterator_type
|
||||
<
|
||||
MultiLinestring
|
||||
>::type(boost::begin(multilinestring), boost::end(multilinestring));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename MultiPolygon>
|
||||
struct points_begin<MultiPolygon, multi_polygon_tag>
|
||||
{
|
||||
static inline typename point_iterator_type<MultiPolygon>::type
|
||||
apply(MultiPolygon& multipolygon)
|
||||
{
|
||||
return typename point_iterator_type
|
||||
<
|
||||
MultiPolygon
|
||||
>::type(boost::begin(multipolygon), boost::end(multipolygon));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
// specializations for points_end
|
||||
|
||||
|
||||
template <typename Linestring>
|
||||
struct points_end<Linestring, linestring_tag>
|
||||
{
|
||||
static inline typename point_iterator_type<Linestring>::type
|
||||
apply(Linestring& linestring)
|
||||
{
|
||||
return boost::end(linestring);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Ring>
|
||||
struct points_end<Ring, ring_tag>
|
||||
{
|
||||
static inline typename point_iterator_type<Ring>::type
|
||||
apply(Ring& ring)
|
||||
{
|
||||
return boost::end(ring);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Polygon>
|
||||
struct points_end<Polygon, polygon_tag>
|
||||
{
|
||||
typedef typename point_iterator_type<Polygon>::type return_type;
|
||||
|
||||
static inline return_type apply(Polygon& polygon)
|
||||
{
|
||||
typedef typename return_type::second_iterator_type flatten_iterator;
|
||||
|
||||
return return_type
|
||||
(boost::end(geometry::exterior_ring(polygon)),
|
||||
flatten_iterator( boost::end(geometry::interior_rings(polygon)) )
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename MultiPoint>
|
||||
struct points_end<MultiPoint, multi_point_tag>
|
||||
{
|
||||
static inline typename point_iterator_type<MultiPoint>::type
|
||||
apply(MultiPoint& multipoint)
|
||||
{
|
||||
return boost::end(multipoint);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename MultiLinestring>
|
||||
struct points_end<MultiLinestring, multi_linestring_tag>
|
||||
{
|
||||
static inline typename point_iterator_type<MultiLinestring>::type
|
||||
apply(MultiLinestring& multilinestring)
|
||||
{
|
||||
return typename point_iterator_type
|
||||
<
|
||||
MultiLinestring
|
||||
>::type(boost::end(multilinestring));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename MultiPolygon>
|
||||
struct points_end<MultiPolygon, multi_polygon_tag>
|
||||
{
|
||||
static inline typename point_iterator_type<MultiPolygon>::type
|
||||
apply(MultiPolygon& multipolygon)
|
||||
{
|
||||
return typename point_iterator_type
|
||||
<
|
||||
MultiPolygon
|
||||
>::type(boost::end(multipolygon));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
// MK:: need to add doc here
|
||||
template <typename Geometry>
|
||||
class point_iterator
|
||||
: public dispatch::point_iterator_type<Geometry>::type
|
||||
{
|
||||
private:
|
||||
typedef typename dispatch::point_iterator_type<Geometry>::type base;
|
||||
|
||||
base* base_ptr()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
base const* base_ptr() const
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
template <typename G1, typename G2>
|
||||
struct is_convertible
|
||||
: boost::is_convertible
|
||||
<
|
||||
typename dispatch::point_iterator_type<G1>::type,
|
||||
typename dispatch::point_iterator_type<G2>::type
|
||||
>
|
||||
{};
|
||||
|
||||
struct enabler {};
|
||||
|
||||
template <typename OtherGeometry> friend class point_iterator;
|
||||
template <typename G> friend inline point_iterator<G> points_begin(G&);
|
||||
template <typename G> friend inline point_iterator<G> points_end(G&);
|
||||
|
||||
point_iterator(base const& base_it) : base(base_it) {}
|
||||
|
||||
public:
|
||||
point_iterator() {}
|
||||
|
||||
template <typename OtherGeometry>
|
||||
point_iterator(point_iterator<OtherGeometry> const& other,
|
||||
typename boost::enable_if
|
||||
<
|
||||
is_convertible<OtherGeometry, Geometry>,
|
||||
enabler
|
||||
>::type = enabler())
|
||||
|
||||
: base(*other.base_ptr())
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
// MK:: need to add doc here
|
||||
template <typename Geometry>
|
||||
inline point_iterator<Geometry>
|
||||
points_begin(Geometry& geometry)
|
||||
{
|
||||
return dispatch::points_begin<Geometry>::apply(geometry);
|
||||
}
|
||||
|
||||
|
||||
// MK:: need to add doc here
|
||||
template <typename Geometry>
|
||||
inline point_iterator<Geometry>
|
||||
points_end(Geometry& geometry)
|
||||
{
|
||||
return dispatch::points_end<Geometry>::apply(geometry);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP
|
||||
203
include/boost/geometry/iterators/point_iterator_type.hpp
Normal file
203
include/boost/geometry/iterators/point_iterator_type.hpp
Normal file
@@ -0,0 +1,203 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_TYPE_HPP
|
||||
#define BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_TYPE_HPP
|
||||
|
||||
#include <boost/geometry/iterators/dispatch/point_iterator_type.hpp>
|
||||
#include <boost/geometry/iterators/dispatch/point_iterator.hpp>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/multi/core/tags.hpp>
|
||||
#include <boost/geometry/iterators/flatten_iterator.hpp>
|
||||
#include <boost/geometry/iterators/concatenate_iterator.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail_dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename Geometry>
|
||||
struct point_iterator_value_type
|
||||
{
|
||||
typedef typename boost::mpl::if_c
|
||||
<
|
||||
!boost::is_const<Geometry>::type::value,
|
||||
typename geometry::point_type<Geometry>::type,
|
||||
typename geometry::point_type<Geometry>::type const
|
||||
>::type type;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Tag = typename tag<Geometry>::type
|
||||
>
|
||||
struct point_iterator_inner_range_type
|
||||
{
|
||||
typedef typename boost::mpl::if_c
|
||||
<
|
||||
!boost::is_const<Geometry>::type::value,
|
||||
typename boost::range_value<Geometry>::type,
|
||||
typename boost::range_value<Geometry>::type const
|
||||
>::type type;
|
||||
};
|
||||
|
||||
|
||||
template <typename Polygon>
|
||||
struct point_iterator_inner_range_type<Polygon, polygon_tag>
|
||||
{
|
||||
typedef typename boost::mpl::if_c
|
||||
<
|
||||
!boost::is_const<Polygon>::type::value,
|
||||
typename geometry::ring_type<Polygon>::type,
|
||||
typename geometry::ring_type<Polygon>::type const
|
||||
>::type type;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace detail_dispatch
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename Linestring>
|
||||
struct point_iterator_type<Linestring, linestring_tag>
|
||||
{
|
||||
typedef typename boost::range_iterator<Linestring>::type type;
|
||||
};
|
||||
|
||||
|
||||
template <typename Ring>
|
||||
struct point_iterator_type<Ring, ring_tag>
|
||||
{
|
||||
typedef typename boost::range_iterator<Ring>::type type;
|
||||
};
|
||||
|
||||
|
||||
template <typename Polygon>
|
||||
class point_iterator_type<Polygon, polygon_tag>
|
||||
{
|
||||
private:
|
||||
typedef typename detail_dispatch::point_iterator_inner_range_type
|
||||
<
|
||||
Polygon
|
||||
>::type InnerRange;
|
||||
|
||||
public:
|
||||
typedef concatenate_iterator
|
||||
<
|
||||
typename boost::range_iterator<InnerRange>::type,
|
||||
flatten_iterator
|
||||
<
|
||||
typename boost::range_iterator
|
||||
<
|
||||
typename geometry::interior_type<Polygon>::type
|
||||
>::type,
|
||||
typename dispatch::point_iterator_type
|
||||
<
|
||||
InnerRange
|
||||
>::type,
|
||||
typename detail_dispatch::point_iterator_value_type
|
||||
<
|
||||
Polygon
|
||||
>::type,
|
||||
dispatch::points_begin<InnerRange>,
|
||||
dispatch::points_end<InnerRange>
|
||||
>,
|
||||
typename detail_dispatch::point_iterator_value_type<Polygon>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
|
||||
template <typename MultiPoint>
|
||||
struct point_iterator_type<MultiPoint, multi_point_tag>
|
||||
{
|
||||
typedef typename boost::range_iterator<MultiPoint>::type type;
|
||||
};
|
||||
|
||||
|
||||
template <typename MultiLinestring>
|
||||
class point_iterator_type<MultiLinestring, multi_linestring_tag>
|
||||
{
|
||||
private:
|
||||
typedef typename detail_dispatch::point_iterator_inner_range_type
|
||||
<
|
||||
MultiLinestring
|
||||
>::type InnerRange;
|
||||
|
||||
public:
|
||||
typedef flatten_iterator
|
||||
<
|
||||
typename boost::range_iterator<MultiLinestring>::type,
|
||||
typename dispatch::point_iterator_type<InnerRange>::type,
|
||||
typename detail_dispatch::point_iterator_value_type
|
||||
<
|
||||
MultiLinestring
|
||||
>::type,
|
||||
dispatch::points_begin<InnerRange>,
|
||||
dispatch::points_end<InnerRange>
|
||||
> type;
|
||||
};
|
||||
|
||||
|
||||
template <typename MultiPolygon>
|
||||
class point_iterator_type<MultiPolygon, multi_polygon_tag>
|
||||
{
|
||||
private:
|
||||
typedef typename detail_dispatch::point_iterator_inner_range_type
|
||||
<
|
||||
MultiPolygon
|
||||
>::type InnerRange;
|
||||
|
||||
public:
|
||||
typedef flatten_iterator
|
||||
<
|
||||
typename boost::range_iterator<MultiPolygon>::type,
|
||||
typename dispatch::point_iterator_type<InnerRange>::type,
|
||||
typename detail_dispatch::point_iterator_value_type
|
||||
<
|
||||
MultiPolygon
|
||||
>::type,
|
||||
dispatch::points_begin<InnerRange>,
|
||||
dispatch::points_end<InnerRange>
|
||||
> type;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_TYPE_HPP
|
||||
@@ -81,7 +81,8 @@ struct within<Point, MultiPolygon, point_tag, multi_polygon_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Point const& point,
|
||||
MultiPolygon const& multi_polygon, Strategy const& strategy)
|
||||
MultiPolygon const& multi_polygon,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return detail::within::geometry_multi_within_code
|
||||
<
|
||||
@@ -101,12 +102,25 @@ struct within<Point, MultiLinestring, point_tag, multi_linestring_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Point const& point,
|
||||
MultiLinestring const& multi_linestring, Strategy const& strategy)
|
||||
MultiLinestring const& multi_linestring,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return detail::within::point_in_geometry(point, multi_linestring, strategy) == 1;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Point, typename MultiPoint>
|
||||
struct within<Point, MultiPoint, point_tag, multi_point_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Point const& point,
|
||||
MultiPoint const& multi_point,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return detail::within::point_in_geometry(point, multi_point, strategy) == 1;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <boost/geometry/strategies/side_info.hpp>
|
||||
#include <boost/geometry/util/select_calculation_type.hpp>
|
||||
#include <boost/geometry/util/select_most_precise.hpp>
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
@@ -28,37 +29,6 @@ namespace boost { namespace geometry
|
||||
namespace policies { namespace relate
|
||||
{
|
||||
|
||||
template <typename Result, bool IsInteger = std::numeric_limits<Result>::is_integer>
|
||||
struct round_dispatch
|
||||
{
|
||||
template <typename T>
|
||||
static inline Result apply(T const& v)
|
||||
{
|
||||
return v < 0 ?
|
||||
boost::numeric_cast<Result>(ceil(v - 0.5f)) :
|
||||
boost::numeric_cast<Result>(floor(v + 0.5f));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Result>
|
||||
struct round_dispatch<Result, false>
|
||||
{
|
||||
template <typename T>
|
||||
static inline Result apply(T const& v)
|
||||
{
|
||||
return boost::numeric_cast<Result>(v);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Result, typename T>
|
||||
inline Result round(T const& v)
|
||||
{
|
||||
// NOTE: boost::round() could be used instead but it throws in some situations
|
||||
|
||||
//BOOST_STATIC_ASSERT(!std::numeric_limits<T>::is_integer);
|
||||
return round_dispatch<Result>::apply(v);
|
||||
}
|
||||
|
||||
template <typename S1, typename S2, typename ReturnType, typename CalculationType = void>
|
||||
struct segments_intersection_points
|
||||
{
|
||||
@@ -89,9 +59,9 @@ struct segments_intersection_points
|
||||
return_type result;
|
||||
result.count = 1;
|
||||
set<0>(result.intersections[0],
|
||||
round<return_coordinate_type>(R(s1x) + r * R(dx1)));
|
||||
geometry::math::round<return_coordinate_type>(R(s1x) + r * R(dx1)));
|
||||
set<1>(result.intersections[0],
|
||||
round<return_coordinate_type>(R(s1y) + r * R(dy1)));
|
||||
geometry::math::round<return_coordinate_type>(R(s1y) + r * R(dy1)));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2013.
|
||||
// Modifications copyright (c) 2013, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013, 2014.
|
||||
// Modifications copyright (c) 2013, 2014 Oracle and/or its affiliates.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
@@ -13,6 +13,8 @@
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
#ifndef BOOST_GEOMETRY_STRATEGY_AGNOSTIC_POINT_IN_POLY_WINDING_HPP
|
||||
#define BOOST_GEOMETRY_STRATEGY_AGNOSTIC_POINT_IN_POLY_WINDING_HPP
|
||||
|
||||
@@ -198,23 +200,30 @@ struct default_strategy<point_tag, AnyTag, point_tag, areal_tag, spherical_tag,
|
||||
typedef winding<Point, typename geometry::point_type<Geometry>::type> type;
|
||||
};
|
||||
|
||||
// TODO: use linear_tag and pointlike_tag the same way how areal_tag is used
|
||||
|
||||
template <typename Point, typename Geometry>
|
||||
struct default_strategy<point_tag, linestring_tag, point_tag, linestring_tag, cartesian_tag, cartesian_tag, Point, Geometry>
|
||||
{
|
||||
typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
|
||||
typedef winding<Point, typename geometry::point_type<Geometry>::type> type;
|
||||
};
|
||||
|
||||
template <typename Point, typename Geometry>
|
||||
struct default_strategy<point_tag, linestring_tag, point_tag, linestring_tag, spherical_tag, spherical_tag, Point, Geometry>
|
||||
{
|
||||
typedef winding<Point, typename geometry::point_type<Geometry>::type> type;
|
||||
};
|
||||
|
||||
// TODO: later move it to multi/strategies/agnostic
|
||||
template <typename Point, typename Geometry>
|
||||
struct default_strategy<point_tag, multi_linestring_tag, point_tag, multi_linestring_tag, cartesian_tag, cartesian_tag, Point, Geometry>
|
||||
{
|
||||
typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
|
||||
typedef winding<Point, typename geometry::point_type<Geometry>::type> type;
|
||||
};
|
||||
|
||||
template <typename Linestring1, typename Linestring2>
|
||||
struct default_strategy<linestring_tag, linestring_tag, linestring_tag, linestring_tag, cartesian_tag, cartesian_tag, Linestring1, Linestring2>
|
||||
template <typename Point, typename Geometry>
|
||||
struct default_strategy<point_tag, multi_linestring_tag, point_tag, multi_linestring_tag, spherical_tag, spherical_tag, Point, Geometry>
|
||||
{
|
||||
typedef strategy::within::winding<typename geometry::point_type<Linestring1>::type, typename geometry::point_type<Linestring2>::type> type;
|
||||
typedef winding<Point, typename geometry::point_type<Geometry>::type> type;
|
||||
};
|
||||
|
||||
} // namespace services
|
||||
@@ -243,19 +252,32 @@ struct default_strategy<point_tag, AnyTag, point_tag, areal_tag, spherical_tag,
|
||||
typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
|
||||
};
|
||||
|
||||
// TODO: use linear_tag and pointlike_tag the same way how areal_tag is used
|
||||
|
||||
template <typename Point, typename Geometry>
|
||||
struct default_strategy<point_tag, linestring_tag, point_tag, linestring_tag, cartesian_tag, cartesian_tag, Point, Geometry>
|
||||
{
|
||||
typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
|
||||
};
|
||||
|
||||
// TODO: later move it to multi/strategies/agnostic
|
||||
template <typename Point, typename Geometry>
|
||||
struct default_strategy<point_tag, linestring_tag, point_tag, linestring_tag, spherical_tag, spherical_tag, Point, Geometry>
|
||||
{
|
||||
typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
|
||||
};
|
||||
|
||||
template <typename Point, typename Geometry>
|
||||
struct default_strategy<point_tag, multi_linestring_tag, point_tag, multi_linestring_tag, cartesian_tag, cartesian_tag, Point, Geometry>
|
||||
{
|
||||
typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
|
||||
};
|
||||
|
||||
template <typename Point, typename Geometry>
|
||||
struct default_strategy<point_tag, multi_linestring_tag, point_tag, multi_linestring_tag, spherical_tag, spherical_tag, Point, Geometry>
|
||||
{
|
||||
typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
|
||||
};
|
||||
|
||||
}}} // namespace strategy::covered_by::services
|
||||
#endif
|
||||
|
||||
|
||||
207
include/boost/geometry/strategies/agnostic/relate.hpp
Normal file
207
include/boost/geometry/strategies/agnostic/relate.hpp
Normal file
@@ -0,0 +1,207 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014 Oracle and/or its affiliates.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
#ifndef BOOST_GEOMETRY_STRATEGY_AGNOSTIC_RELATE_HPP
|
||||
#define BOOST_GEOMETRY_STRATEGY_AGNOSTIC_RELATE_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/detail/relate/relate.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace strategy { namespace relate
|
||||
{
|
||||
|
||||
template <typename StaticMask>
|
||||
struct relate
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
return detail::relate::relate<StaticMask>(geometry1, geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace relate
|
||||
|
||||
namespace within
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
|
||||
|
||||
namespace services
|
||||
{
|
||||
|
||||
// P/L
|
||||
|
||||
//template <typename Point, typename Linestring, typename AnyCS1, typename AnyCS2>
|
||||
//struct default_strategy<point_tag, linestring_tag, point_tag, linestring_tag, AnyCS1, AnyCS2, Point, Linestring>
|
||||
//{
|
||||
// typedef strategy::relate::relate<detail::relate::static_mask_within> type;
|
||||
//};
|
||||
//
|
||||
//template <typename Point, typename MultiLinestring, typename AnyCS1, typename AnyCS2>
|
||||
//struct default_strategy<point_tag, multi_linestring_tag, point_tag, multi_linestring_tag, AnyCS1, AnyCS2, Point, MultiLinestring>
|
||||
//{
|
||||
// typedef strategy::relate::relate<detail::relate::static_mask_within> type;
|
||||
//};
|
||||
|
||||
// L/L
|
||||
|
||||
template <typename Linestring1, typename Linestring2, typename AnyCS1, typename AnyCS2>
|
||||
struct default_strategy<linestring_tag, linestring_tag, linestring_tag, linestring_tag, AnyCS1, AnyCS2, Linestring1, Linestring2>
|
||||
{
|
||||
typedef strategy::relate::relate<detail::relate::static_mask_within> type;
|
||||
};
|
||||
|
||||
template <typename Linestring, typename MultiLinestring, typename AnyCS1, typename AnyCS2>
|
||||
struct default_strategy<linestring_tag, multi_linestring_tag, linestring_tag, multi_linestring_tag, AnyCS1, AnyCS2, Linestring, MultiLinestring>
|
||||
{
|
||||
typedef strategy::relate::relate<detail::relate::static_mask_within> type;
|
||||
};
|
||||
|
||||
template <typename MultiLinestring, typename Linestring, typename AnyCS1, typename AnyCS2>
|
||||
struct default_strategy<multi_linestring_tag, linestring_tag, multi_linestring_tag, linestring_tag, AnyCS1, AnyCS2, MultiLinestring, Linestring>
|
||||
{
|
||||
typedef strategy::relate::relate<detail::relate::static_mask_within> type;
|
||||
};
|
||||
|
||||
// L/A
|
||||
|
||||
template <typename Linestring, typename Ring, typename AnyCS1, typename AnyCS2>
|
||||
struct default_strategy<linestring_tag, ring_tag, linestring_tag, areal_tag, AnyCS1, AnyCS2, Linestring, Ring>
|
||||
{
|
||||
typedef strategy::relate::relate<detail::relate::static_mask_within> type;
|
||||
};
|
||||
|
||||
template <typename MultiLinestring, typename Ring, typename AnyCS1, typename AnyCS2>
|
||||
struct default_strategy<multi_linestring_tag, ring_tag, multi_linestring_tag, areal_tag, AnyCS1, AnyCS2, MultiLinestring, Ring>
|
||||
{
|
||||
typedef strategy::relate::relate<detail::relate::static_mask_within> type;
|
||||
};
|
||||
|
||||
template <typename Linestring, typename Polygon, typename AnyCS1, typename AnyCS2>
|
||||
struct default_strategy<linestring_tag, polygon_tag, linestring_tag, areal_tag, AnyCS1, AnyCS2, Linestring, Polygon>
|
||||
{
|
||||
typedef strategy::relate::relate<detail::relate::static_mask_within> type;
|
||||
};
|
||||
|
||||
template <typename MultiLinestring, typename Polygon, typename AnyCS1, typename AnyCS2>
|
||||
struct default_strategy<multi_linestring_tag, polygon_tag, multi_linestring_tag, areal_tag, AnyCS1, AnyCS2, MultiLinestring, Polygon>
|
||||
{
|
||||
typedef strategy::relate::relate<detail::relate::static_mask_within> type;
|
||||
};
|
||||
|
||||
template <typename Linestring, typename MultiPolygon, typename AnyCS1, typename AnyCS2>
|
||||
struct default_strategy<linestring_tag, multi_polygon_tag, linestring_tag, areal_tag, AnyCS1, AnyCS2, Linestring, MultiPolygon>
|
||||
{
|
||||
typedef strategy::relate::relate<detail::relate::static_mask_within> type;
|
||||
};
|
||||
|
||||
template <typename MultiLinestring, typename MultiPolygon, typename AnyCS1, typename AnyCS2>
|
||||
struct default_strategy<multi_linestring_tag, multi_polygon_tag, multi_linestring_tag, areal_tag, AnyCS1, AnyCS2, MultiLinestring, MultiPolygon>
|
||||
{
|
||||
typedef strategy::relate::relate<detail::relate::static_mask_within> type;
|
||||
};
|
||||
|
||||
} // namespace services
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
}} // namespace strategy::within
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
|
||||
namespace strategy { namespace covered_by { namespace services
|
||||
{
|
||||
|
||||
// P/L
|
||||
|
||||
//template <typename Point, typename Linestring, typename AnyCS1, typename AnyCS2>
|
||||
//struct default_strategy<point_tag, linestring_tag, point_tag, linestring_tag, AnyCS1, AnyCS2, Point, Linestring>
|
||||
//{
|
||||
// typedef strategy::relate::relate<detail::relate::static_mask_covered_by> type;
|
||||
//};
|
||||
//
|
||||
//template <typename Point, typename MultiLinestring, typename AnyCS1, typename AnyCS2>
|
||||
//struct default_strategy<point_tag, multi_linestring_tag, point_tag, multi_linestring_tag, AnyCS1, AnyCS2, Point, MultiLinestring>
|
||||
//{
|
||||
// typedef strategy::relate::relate<detail::relate::static_mask_covered_by> type;
|
||||
//};
|
||||
|
||||
// L/L
|
||||
|
||||
template <typename Linestring1, typename Linestring2, typename AnyCS1, typename AnyCS2>
|
||||
struct default_strategy<linestring_tag, linestring_tag, linestring_tag, linestring_tag, AnyCS1, AnyCS2, Linestring1, Linestring2>
|
||||
{
|
||||
typedef strategy::relate::relate<detail::relate::static_mask_covered_by> type;
|
||||
};
|
||||
|
||||
template <typename Linestring, typename MultiLinestring, typename AnyCS1, typename AnyCS2>
|
||||
struct default_strategy<linestring_tag, multi_linestring_tag, linestring_tag, multi_linestring_tag, AnyCS1, AnyCS2, Linestring, MultiLinestring>
|
||||
{
|
||||
typedef strategy::relate::relate<detail::relate::static_mask_covered_by> type;
|
||||
};
|
||||
|
||||
template <typename MultiLinestring, typename Linestring, typename AnyCS1, typename AnyCS2>
|
||||
struct default_strategy<multi_linestring_tag, linestring_tag, multi_linestring_tag, linestring_tag, AnyCS1, AnyCS2, MultiLinestring, Linestring>
|
||||
{
|
||||
typedef strategy::relate::relate<detail::relate::static_mask_covered_by> type;
|
||||
};
|
||||
|
||||
// L/A
|
||||
|
||||
template <typename Linestring, typename Ring, typename AnyCS1, typename AnyCS2>
|
||||
struct default_strategy<linestring_tag, ring_tag, linestring_tag, areal_tag, AnyCS1, AnyCS2, Linestring, Ring>
|
||||
{
|
||||
typedef strategy::relate::relate<detail::relate::static_mask_covered_by> type;
|
||||
};
|
||||
|
||||
template <typename MultiLinestring, typename Ring, typename AnyCS1, typename AnyCS2>
|
||||
struct default_strategy<multi_linestring_tag, ring_tag, multi_linestring_tag, areal_tag, AnyCS1, AnyCS2, MultiLinestring, Ring>
|
||||
{
|
||||
typedef strategy::relate::relate<detail::relate::static_mask_covered_by> type;
|
||||
};
|
||||
|
||||
template <typename Linestring, typename Polygon, typename AnyCS1, typename AnyCS2>
|
||||
struct default_strategy<linestring_tag, polygon_tag, linestring_tag, areal_tag, AnyCS1, AnyCS2, Linestring, Polygon>
|
||||
{
|
||||
typedef strategy::relate::relate<detail::relate::static_mask_covered_by> type;
|
||||
};
|
||||
|
||||
template <typename MultiLinestring, typename Polygon, typename AnyCS1, typename AnyCS2>
|
||||
struct default_strategy<multi_linestring_tag, polygon_tag, multi_linestring_tag, areal_tag, AnyCS1, AnyCS2, MultiLinestring, Polygon>
|
||||
{
|
||||
typedef strategy::relate::relate<detail::relate::static_mask_covered_by> type;
|
||||
};
|
||||
|
||||
template <typename Linestring, typename MultiPolygon, typename AnyCS1, typename AnyCS2>
|
||||
struct default_strategy<linestring_tag, multi_polygon_tag, linestring_tag, areal_tag, AnyCS1, AnyCS2, Linestring, MultiPolygon>
|
||||
{
|
||||
typedef strategy::relate::relate<detail::relate::static_mask_covered_by> type;
|
||||
};
|
||||
|
||||
template <typename MultiLinestring, typename MultiPolygon, typename AnyCS1, typename AnyCS2>
|
||||
struct default_strategy<multi_linestring_tag, multi_polygon_tag, multi_linestring_tag, areal_tag, AnyCS1, AnyCS2, MultiLinestring, MultiPolygon>
|
||||
{
|
||||
typedef strategy::relate::relate<detail::relate::static_mask_covered_by> type;
|
||||
};
|
||||
|
||||
}}} // namespace strategy::covered_by::services
|
||||
#endif
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_STRATEGY_AGNOSTIC_RELATE_HPP
|
||||
@@ -55,6 +55,8 @@
|
||||
#include <boost/geometry/strategies/agnostic/point_in_poly_winding.hpp>
|
||||
#include <boost/geometry/strategies/agnostic/simplify_douglas_peucker.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/agnostic/relate.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/strategy_transform.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/transform/matrix_transformers.hpp>
|
||||
|
||||
@@ -111,6 +111,29 @@ struct relaxed_epsilon
|
||||
}
|
||||
};
|
||||
|
||||
// ItoF ItoI FtoF
|
||||
template <typename Result, typename Source,
|
||||
bool ResultIsInteger = std::numeric_limits<Result>::is_integer,
|
||||
bool SourceIsInteger = std::numeric_limits<Source>::is_integer>
|
||||
struct round
|
||||
{
|
||||
static inline Result apply(Source const& v)
|
||||
{
|
||||
return boost::numeric_cast<Result>(v);
|
||||
}
|
||||
};
|
||||
|
||||
// FtoI
|
||||
template <typename Result, typename Source>
|
||||
struct round<Result, Source, true, false>
|
||||
{
|
||||
static inline Result apply(Source const& v)
|
||||
{
|
||||
return v < 0
|
||||
? boost::numeric_cast<Result>(ceil(v - 0.5f))
|
||||
: boost::numeric_cast<Result>(floor(v + 0.5f));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
#endif
|
||||
@@ -239,6 +262,19 @@ static inline int sign(T const& value)
|
||||
return value > zero ? 1 : value < zero ? -1 : 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to calculate the rounded value of a number.
|
||||
\ingroup utility
|
||||
\note If the source T is NOT an integral type and Result is an integral type
|
||||
the value is rounded towards the closest integral value. Otherwise it's
|
||||
just casted.
|
||||
*/
|
||||
template <typename Result, typename T>
|
||||
inline Result round(T const& v)
|
||||
{
|
||||
// NOTE: boost::round() could be used instead but it throws in some situations
|
||||
return detail::round<Result, T>::apply(v);
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
|
||||
|
||||
110
include/boost/geometry/util/range.hpp
Normal file
110
include/boost/geometry/util/range.hpp
Normal file
@@ -0,0 +1,110 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2013, 2014.
|
||||
// Modifications copyright (c) 2013-2014 Oracle and/or its affiliates.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
#ifndef BOOST_GEOMETRY_UTIL_RANGE_HPP
|
||||
#define BOOST_GEOMETRY_UTIL_RANGE_HPP
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/range/concepts.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/empty.hpp>
|
||||
#include <boost/range/size.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace range {
|
||||
|
||||
// NOTE: For SinglePassRanges at could iterate over all elements until the i-th element is met.
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently return an element of a RandomAccessRange.
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename RandomAccessRange>
|
||||
inline typename boost::range_value<RandomAccessRange const>::type const&
|
||||
at(RandomAccessRange const& rng,
|
||||
typename boost::range_size<RandomAccessRange const>::type i)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<RandomAccessRange const> ));
|
||||
BOOST_ASSERT(i < boost::size(rng));
|
||||
return *(boost::begin(rng) + i);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently return an element of a RandomAccessRange.
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename RandomAccessRange>
|
||||
inline typename boost::range_value<RandomAccessRange>::type &
|
||||
at(RandomAccessRange & rng,
|
||||
typename boost::range_size<RandomAccessRange>::type i)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<RandomAccessRange> ));
|
||||
BOOST_ASSERT(i < boost::size(rng));
|
||||
return *(boost::begin(rng) + i);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently return the front element of a Range.
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Range>
|
||||
inline typename boost::range_value<Range>::type const&
|
||||
front(Range const& rng)
|
||||
{
|
||||
BOOST_ASSERT(!boost::empty(rng));
|
||||
return *boost::begin(rng);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently return the front element of a Range.
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename Range>
|
||||
inline typename boost::range_value<Range>::type &
|
||||
front(Range & rng)
|
||||
{
|
||||
BOOST_ASSERT(!boost::empty(rng));
|
||||
return *boost::begin(rng);
|
||||
}
|
||||
|
||||
// NOTE: For SinglePassRanges back() could iterate over all elements until the last element is met.
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently return the back element of a BidirectionalRange.
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename BidirectionalRange>
|
||||
inline typename boost::range_value<BidirectionalRange>::type const&
|
||||
back(BidirectionalRange const& rng)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( boost::BidirectionalRangeConcept<BidirectionalRange const> ));
|
||||
BOOST_ASSERT(!boost::empty(rng));
|
||||
return *(--boost::end(rng));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Short utility to conveniently return the back element of a BidirectionalRange.
|
||||
\ingroup utility
|
||||
*/
|
||||
template <typename BidirectionalRange>
|
||||
inline typename boost::range_value<BidirectionalRange>::type &
|
||||
back(BidirectionalRange & rng)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( boost::BidirectionalRangeConcept<BidirectionalRange> ));
|
||||
BOOST_ASSERT(!boost::empty(rng));
|
||||
return *(--boost::end(rng));
|
||||
}
|
||||
|
||||
}}} // namespace boost::geometry::range
|
||||
|
||||
#endif // BOOST_GEOMETRY_UTIL_RANGE_HPP
|
||||
@@ -61,13 +61,11 @@ void test_sectionalize_part()
|
||||
bg::detail::no_rescale_policy rescale_policy;
|
||||
|
||||
bg::ring_identifier ring_id;
|
||||
int index = 0;
|
||||
int ndi = 0;
|
||||
sectionalize_part::apply(sections, section, index, ndi, geometry, rescale_policy, false, ring_id, 10);
|
||||
sectionalize_part::apply(sections, geometry, rescale_policy, false, ring_id, 10);
|
||||
// There should not yet be anything generated, because it is only ONE point
|
||||
|
||||
geometry.push_back(bg::make<point_type>(2, 2));
|
||||
sectionalize_part::apply(sections, section, index, ndi, geometry, rescale_policy, false, ring_id, 10);
|
||||
sectionalize_part::apply(sections, geometry, rescale_policy, false, ring_id, 10);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -198,6 +198,14 @@ void test_areal()
|
||||
ggl_list_20131119_james[0], ggl_list_20131119_james[1],
|
||||
1, 4, 6.6125873045, 0.1);
|
||||
|
||||
#if 0
|
||||
// TODO: fix this testcase, it should give 0 but instead it gives one of the input polygons
|
||||
// Mailed to the Boost.Geometry list on 2014/03/21 by 7415963@gmail.com
|
||||
test_one<Polygon, Polygon, Polygon>("ggl_list_20140321_7415963",
|
||||
ggl_list_20140321_7415963[0], ggl_list_20140321_7415963[1],
|
||||
0, 0, 0, 0.1);
|
||||
#endif
|
||||
|
||||
test_one<Polygon, Polygon, Polygon>("buffer_rt_f", buffer_rt_f[0], buffer_rt_f[1],
|
||||
1, 4, 0.00029437899183903937, 0.01);
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ test-suite boost-geometry-algorithms-overlay
|
||||
[ run get_turn_info.cpp ]
|
||||
[ run get_turns.cpp ]
|
||||
[ run get_turns_linear_linear.cpp ]
|
||||
[ run get_turns_linear_areal.cpp ]
|
||||
[ run relative_order.cpp ]
|
||||
[ run select_rings.cpp ]
|
||||
[ run self_intersection_points.cpp ]
|
||||
|
||||
@@ -51,7 +51,7 @@ void test_with_point(std::string const& caseid,
|
||||
<
|
||||
bg::detail::overlay::assign_null_policy
|
||||
>::apply(pi, pj, pk, qi, qj, qk,
|
||||
10, 10, // dummy max numbers of segments
|
||||
false, false, false, false, // dummy parameters
|
||||
model, bg::detail::no_rescale_policy(), std::back_inserter(info));
|
||||
|
||||
|
||||
|
||||
@@ -538,6 +538,12 @@ static std::string ggl_list_20131119_james[2] =
|
||||
};
|
||||
|
||||
|
||||
static std::string ggl_list_20140321_7415963[2] =
|
||||
{
|
||||
"POLYGON((-6.0 3.2500000000000013, -9.0 3.2500000000000022, -9.0 6.5, -6.0 6.5, -6.0 3.2500000000000013))",
|
||||
"POLYGON((-3.0 0.0, -6.0 0.0, -6.0 3.2500000000000013, -3.0 3.2500000000000009, -3.0 0.0))",
|
||||
};
|
||||
|
||||
// GEOS "TestOverlay" test.
|
||||
// Note that the first one WAS invalid and is made valid using SQL Server 2008 Spatial MakeValid() function
|
||||
static std::string geos_1_test_overlay[2] =
|
||||
|
||||
@@ -152,8 +152,8 @@ struct expected_pusher
|
||||
typedef std::vector<std::string>::iterator iterator;
|
||||
typedef std::vector<std::string>::const_iterator const_iterator;
|
||||
|
||||
//iterator begin() { return vec.begin(); }
|
||||
//iterator end() { return vec.end(); }
|
||||
iterator begin() { return vec.begin(); }
|
||||
iterator end() { return vec.end(); }
|
||||
const_iterator begin() const { return vec.begin(); }
|
||||
const_iterator end() const { return vec.end(); }
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#include <boost/geometry/multi/geometries/multi_polygon.hpp>
|
||||
|
||||
//TEST
|
||||
#include <to_svg.hpp>
|
||||
//#include <to_svg.hpp>
|
||||
|
||||
namespace bgdr = bg::detail::relate;
|
||||
|
||||
@@ -75,8 +75,8 @@ void check_geometry(Geometry1 const& geometry1,
|
||||
std::string expected_tr = transposed(expected);
|
||||
bool ok = boost::equal(res_str, expected_tr);
|
||||
BOOST_CHECK_MESSAGE(ok,
|
||||
"relate: " << wkt1
|
||||
<< " and " << wkt2
|
||||
"relate: " << wkt2
|
||||
<< " and " << wkt1
|
||||
<< " -> Expected: " << expected_tr
|
||||
<< " detected: " << res_str);
|
||||
}
|
||||
@@ -251,9 +251,14 @@ void test_linestring_linestring()
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 2,3 3,1 1,5 3)", "LINESTRING(6 3,3 3,0 0)", "1F100F102");
|
||||
test_geometry<ls, ls>("LINESTRING(5 3,1 1,3 3,2 2,0 0)", "LINESTRING(6 3,3 3,0 0)", "1F100F102");
|
||||
|
||||
// spike
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,10 0)",
|
||||
// spikes
|
||||
// FOR NOW DISABLED
|
||||
/*test_geometry<ls, ls>("LINESTRING(0 0,10 0)",
|
||||
"LINESTRING(1 0,9 0,2 0)", "101FF0FF2");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 2,3 3,1 1)", "LINESTRING(0 0,3 3,6 3)", "1FF00F102");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 2,3 3,1 1)", "LINESTRING(0 0,4 4,6 3)", "1FF00F102");*/
|
||||
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 2,3 3,4 4)", "LINESTRING(0 0,1 1,4 4)", "1FFF0FFF2");
|
||||
|
||||
// loop i/i i/i u/u u/u
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,10 0)",
|
||||
@@ -313,6 +318,10 @@ void test_linestring_linestring()
|
||||
test_geometry<ls, ls>("LINESTRING(1 0,5 0,7 0,8 1)", "LINESTRING(0 0,10 0,10 10,4 -1)",
|
||||
"1F10F0102");
|
||||
|
||||
// duplicated points
|
||||
test_geometry<ls, ls>("LINESTRING(1 1, 2 2, 2 2)", "LINESTRING(0 0, 2 2, 4 2)", "1FF0FF102");
|
||||
test_geometry<ls, ls>("LINESTRING(1 1, 1 1, 2 2)", "LINESTRING(0 0, 2 2, 4 2)", "1FF0FF102");
|
||||
|
||||
// linear ring
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,10 0)", "LINESTRING(5 0,9 0,5 5,1 0,5 0)", "1F1FF01F2");
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,5 0,10 0)", "LINESTRING(5 0,9 0,5 5,1 0,5 0)", "1F1FF01F2");
|
||||
@@ -426,8 +435,28 @@ void test_linestring_polygon()
|
||||
// IB1 IE
|
||||
test_geometry<ls, poly>("LINESTRING(10 10,10 5,15 5)", "POLYGON((0 0,0 10,10 10,10 0,0 0))", "F11F00212");
|
||||
|
||||
// II IB0 IE
|
||||
test_geometry<ls, poly>("LINESTRING(5 5,10 5,15 10)", "POLYGON((0 0,0 10,10 10,10 0,0 0))", "1010F0212");
|
||||
// duplicated points
|
||||
{
|
||||
// II IB0 IE
|
||||
test_geometry<ls, poly>("LINESTRING(5 5,10 5,15 10)", "POLYGON((0 0,0 10,10 10,10 0,0 0))", "1010F0212");
|
||||
test_geometry<ls, poly>("LINESTRING(5 5,5 5,5 5,10 5,10 5,10 5,15 10,15 10,15 10)",
|
||||
"POLYGON((0 0,0 0,0 0,0 10,0 10,0 10,10 10,10 10,10 10,10 0,10 0,10 0,0 0,0 0,0 0))",
|
||||
"1010F0212");
|
||||
test_geometry<ls, poly>("LINESTRING(5 5,5 5,5 5,10 0,10 0,10 0,15 10,15 10,15 10)",
|
||||
"POLYGON((0 0,0 0,0 0,0 10,0 10,0 10,10 10,10 10,10 10,10 0,10 0,10 0,0 0,0 0,0 0))",
|
||||
"1010F0212");
|
||||
// IE IB0 II
|
||||
test_geometry<ls, poly>("LINESTRING(15 10,15 10,15 10,10 5,10 5,10 5,5 5,5 5,5 5)",
|
||||
"POLYGON((0 0,0 0,0 0,0 10,0 10,0 10,10 10,10 10,10 10,10 0,10 0,10 0,0 0,0 0,0 0))",
|
||||
"1010F0212");
|
||||
test_geometry<ls, poly>("LINESTRING(15 10,15 10,15 10,10 0,10 0,10 0,5 5,5 5,5 5)",
|
||||
"POLYGON((0 0,0 0,0 0,0 10,0 10,0 10,10 10,10 10,10 10,10 0,10 0,10 0,0 0,0 0,0 0))",
|
||||
"1010F0212");
|
||||
|
||||
// TEST
|
||||
//test_geometry<ls, poly>("LINESTRING(5 5,5 5,5 5)", "POLYGON((0 0,0 10,10 10,10 0,0 0))", "1010F0212");
|
||||
test_geometry<ls, poly>("LINESTRING(5 5,5 5,5 5,15 5,15 5,15 5)", "POLYGON((0 0,0 10,10 10,10 0,0 0))", "1010F0212");
|
||||
}
|
||||
|
||||
// non-simple polygon with hole
|
||||
test_geometry<ls, poly>("LINESTRING(9 1,10 5,9 9)",
|
||||
|
||||
@@ -29,8 +29,6 @@ void test_linestring_linestring()
|
||||
test_geometry<ls, ls>("LINESTRING(1 1, 2 2, 3 2)", "LINESTRING(4 2, 2 2, 0 0)", true);
|
||||
test_geometry<ls, ls>("LINESTRING(3 2, 2 2, 1 1)", "LINESTRING(4 2, 2 2, 0 0)", true);
|
||||
|
||||
test_geometry<ls, ls>("LINESTRING(1 1, 2 2, 2 2)", "LINESTRING(0 0, 2 2, 4 2)", true);
|
||||
|
||||
test_geometry<ls, ls>("LINESTRING(1 1, 2 2, 3 3)", "LINESTRING(0 0, 2 2, 4 2)", false);
|
||||
test_geometry<ls, ls>("LINESTRING(1 1, 2 2, 3 2, 3 3)", "LINESTRING(0 0, 2 2, 4 2)", false);
|
||||
test_geometry<ls, ls>("LINESTRING(1 1, 2 2, 3 1)", "LINESTRING(0 0, 2 2, 4 2)", false);
|
||||
@@ -41,14 +39,30 @@ void test_linestring_linestring()
|
||||
test_geometry<ls, ls>("LINESTRING(1 0, 1 1, 2 2, 3 2)", "LINESTRING(0 0, 2 2, 4 2)", false);
|
||||
test_geometry<ls, ls>("LINESTRING(1 0, 0 0, 2 2, 3 2)", "LINESTRING(0 0, 2 2, 4 2)", false);
|
||||
|
||||
test_geometry<ls, ls>("LINESTRING(0 0)", "LINESTRING(0 0)", false);
|
||||
test_geometry<ls, ls>("LINESTRING(1 1)", "LINESTRING(0 0, 2 2)", true);
|
||||
test_geometry<ls, ls>("LINESTRING(0 0)", "LINESTRING(0 0, 2 2)", false);
|
||||
test_geometry<ls, ls>("LINESTRING(0 0, 1 1)", "LINESTRING(0 0)", false);
|
||||
// duplicated points
|
||||
test_geometry<ls, ls>("LINESTRING(1 1, 2 2, 2 2)", "LINESTRING(0 0, 2 2, 4 2)", true);
|
||||
test_geometry<ls, ls>("LINESTRING(1 1, 1 1, 2 2)", "LINESTRING(0 0, 2 2, 4 2)", true);
|
||||
|
||||
test_geometry<ls, ls>("LINESTRING(0 0, 0 0, 0 0, 1 1, 2 2, 2 2, 2 2, 2 2, 2 2, 2 2, 2 2, 2 2, 2 2, 2 2, 2 2, 2 2, 2 2, 2 2, 2 2, 2 2, 2 2, 2 2, 3 3)",
|
||||
"LINESTRING(0 0, 2 2, 4 4)", true);
|
||||
|
||||
// invalid linestrings
|
||||
// test_geometry<ls, ls>("LINESTRING(0 0)", "LINESTRING(0 0)", false);
|
||||
// test_geometry<ls, ls>("LINESTRING(1 1)", "LINESTRING(0 0, 2 2)", true);
|
||||
// test_geometry<ls, ls>("LINESTRING(0 0)", "LINESTRING(0 0, 2 2)", false);
|
||||
// test_geometry<ls, ls>("LINESTRING(0 0, 1 1)", "LINESTRING(0 0)", false);
|
||||
|
||||
// spikes
|
||||
// FOR NOW DISABLED
|
||||
|
||||
/*test_geometry<ls, ls>("LINESTRING(0 0,5 0,3 0,6 0)", "LINESTRING(0 0,6 0)", true);
|
||||
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,5 0,3 0,6 0)", "LINESTRING(0 0,6 0)", true);
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 2,3 3,1 1)", "LINESTRING(0 0,3 3,6 3)", true);
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 2,3 3,1 1,5 3)", "LINESTRING(0 0,3 3,6 3)", false);
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,3 3,6 3)", "LINESTRING(0 0,2 2,3 3,1 1)", false);
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 2,3 3,1 1)", "LINESTRING(0 0,4 4,6 3)", true);
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,4 4,6 3)", "LINESTRING(0 0,2 2,3 3,1 1)", false);
|
||||
|
||||
test_geometry<ls, ls>("LINESTRING(0 0,2 2,3 3,1 1,5 3)", "LINESTRING(0 0,3 3,6 3)", false);*/
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
# Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
#
|
||||
# Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
# Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
# Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
# Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
# Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
|
||||
# Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
|
||||
#
|
||||
# This file was modified by Oracle on 2014.
|
||||
# Modifications copyright (c) 2014, Oracle and/or its affiliates.
|
||||
#
|
||||
# Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
#
|
||||
# Use, modification and distribution is subject to the Boost Software License,
|
||||
# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -12,4 +17,7 @@ test-suite boost-geometry-iterators
|
||||
:
|
||||
[ run closing_iterator.cpp ]
|
||||
[ run ever_circling_iterator.cpp ]
|
||||
[ run point_iterator.cpp ]
|
||||
[ run concatenate_iterator.cpp ]
|
||||
[ run flatten_iterator.cpp ]
|
||||
;
|
||||
|
||||
260
test/iterators/concatenate_iterator.cpp
Normal file
260
test/iterators/concatenate_iterator.cpp
Normal file
@@ -0,0 +1,260 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_TEST_MODULE
|
||||
#define BOOST_TEST_MODULE test_concatenate_iterator
|
||||
#endif
|
||||
|
||||
#include <boost/test/included/unit_test.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
#include <boost/assign/std/vector.hpp>
|
||||
#include <boost/assign/std/list.hpp>
|
||||
#include <boost/geometry/iterators/concatenate_iterator.hpp>
|
||||
|
||||
using namespace boost::assign;
|
||||
|
||||
template <typename Iterator>
|
||||
std::ostream& print_container(std::ostream& os,
|
||||
Iterator begin, Iterator end,
|
||||
std::string const& header)
|
||||
{
|
||||
std::cout << header;
|
||||
for (Iterator it = begin; it != end; ++it)
|
||||
{
|
||||
os << " " << *it;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct is_odd
|
||||
{
|
||||
inline bool operator()(T const& t) const
|
||||
{
|
||||
return t % 2 != 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct test_concatenate_iterator
|
||||
{
|
||||
template <typename Container1, typename Container2>
|
||||
static inline void apply(Container1& c1, Container2& c2,
|
||||
std::string const& case_id)
|
||||
{
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << "case id: " << case_id << std::endl;
|
||||
#endif
|
||||
typedef typename Container1::const_iterator const_iterator1;
|
||||
typedef typename Container2::const_iterator const_iterator2;
|
||||
typedef typename Container1::iterator iterator1;
|
||||
typedef typename Container2::iterator iterator2;
|
||||
|
||||
typedef boost::geometry::concatenate_iterator
|
||||
<
|
||||
const_iterator1, const_iterator2,
|
||||
typename Container1::value_type const
|
||||
> const_concat_iterator;
|
||||
|
||||
typedef boost::geometry::concatenate_iterator
|
||||
<
|
||||
iterator1, iterator2, typename Container1::value_type
|
||||
> concat_iterator;
|
||||
|
||||
|
||||
concat_iterator begin(c1.begin(), c1.end(), c2.begin());
|
||||
concat_iterator end(c1.end(), c2.end());
|
||||
const_concat_iterator const_begin(begin);
|
||||
const_concat_iterator const_end(end);
|
||||
const_begin = begin;
|
||||
const_end = end;
|
||||
|
||||
std::size_t size(0);
|
||||
for (const_concat_iterator it = const_begin; it != const_end; ++it)
|
||||
{
|
||||
++size;
|
||||
}
|
||||
BOOST_CHECK( c1.size() + c2.size() == size );
|
||||
|
||||
size = 0;
|
||||
for (concat_iterator it = begin; it != end; ++it)
|
||||
{
|
||||
++size;
|
||||
}
|
||||
BOOST_CHECK( c1.size() + c2.size() == size );
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
print_container(std::cout, c1.begin(), c1.end(), "first :")
|
||||
<< std::endl;
|
||||
print_container(std::cout, c2.begin(), c2.end(), "second :")
|
||||
<< std::endl;
|
||||
print_container(std::cout, begin, end, "combined:")
|
||||
<< std::endl;
|
||||
|
||||
if ( begin != end )
|
||||
{
|
||||
std::cout << "min element: "
|
||||
<< *std::min_element(begin, end)
|
||||
<< std::endl;
|
||||
std::cout << "max element: "
|
||||
<< *std::max_element(const_begin, const_end)
|
||||
<< std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
const_iterator1 it1 = c1.begin();
|
||||
const_iterator2 it2 = c2.begin();
|
||||
for (const_concat_iterator it = const_begin; it != const_end; ++it)
|
||||
{
|
||||
if ( it1 != c1.end() )
|
||||
{
|
||||
BOOST_CHECK( *it == *it1 );
|
||||
++it1;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_CHECK( *it == *it2 );
|
||||
++it2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef typename std::iterator_traits
|
||||
<
|
||||
concat_iterator
|
||||
>::value_type value_type;
|
||||
|
||||
if ( c1.size() != 0 )
|
||||
{
|
||||
concat_iterator it_max = std::max_element(begin, end);
|
||||
const_concat_iterator const_it_max =
|
||||
std::max_element(const_begin, const_end);
|
||||
|
||||
BOOST_CHECK( it_max == const_it_max );
|
||||
|
||||
value_type old_value = *const_begin;
|
||||
value_type new_value = *it_max + 1;
|
||||
|
||||
*begin = *it_max + 1;
|
||||
BOOST_CHECK( *c1.begin() == new_value );
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << std::endl;
|
||||
std::cout << "modified element of 1st container:" << std::endl;
|
||||
print_container(std::cout, c1.begin(), c1.end(), "first :")
|
||||
<< std::endl;
|
||||
print_container(std::cout, begin, end, "combined:")
|
||||
<< std::endl;
|
||||
#endif
|
||||
|
||||
*begin = old_value;
|
||||
BOOST_CHECK( *c1.begin() == old_value );
|
||||
}
|
||||
|
||||
if ( c2.size() != 0 )
|
||||
{
|
||||
concat_iterator begin2 = begin;
|
||||
std::size_t counter(0);
|
||||
while ( counter != c1.size() )
|
||||
{
|
||||
++counter;
|
||||
begin2++;
|
||||
}
|
||||
|
||||
concat_iterator it_max = std::max_element(begin, end);
|
||||
const_concat_iterator const_it_max =
|
||||
std::max_element(const_begin, const_end);
|
||||
|
||||
BOOST_CHECK( it_max == const_it_max );
|
||||
|
||||
value_type old_value = *begin2;
|
||||
value_type new_value = *it_max + 1;
|
||||
|
||||
*begin2 = *it_max + 1;
|
||||
BOOST_CHECK( *c2.begin() == new_value );
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << std::endl;
|
||||
std::cout << "modified element of 2nd container:" << std::endl;
|
||||
print_container(std::cout, c2.begin(), c2.end(), "second :")
|
||||
<< std::endl;
|
||||
print_container(std::cout, begin, end, "combined:")
|
||||
<< std::endl;
|
||||
#endif
|
||||
|
||||
*begin2 = old_value;
|
||||
BOOST_CHECK( *c2.begin() == old_value );
|
||||
}
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << std::endl;
|
||||
std::cout << "odd elements removed:" << std::endl;
|
||||
print_container(std::cout, begin, end, "before:")
|
||||
<< std::endl;
|
||||
#endif
|
||||
concat_iterator new_end =
|
||||
std::remove_if(begin, end, is_odd<value_type>());
|
||||
|
||||
for (const_concat_iterator it = const_begin; it != new_end; ++it)
|
||||
{
|
||||
BOOST_CHECK( !is_odd<value_type>()(*it) );
|
||||
}
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
print_container(std::cout, begin, new_end, "after :")
|
||||
<< std::endl;
|
||||
#endif
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << "====================" << std::endl << std::endl;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_concatenate_iterator_all )
|
||||
{
|
||||
{
|
||||
std::vector<int> v;
|
||||
std::list<int> l;
|
||||
|
||||
test_concatenate_iterator::apply(v, l, "empty_both");
|
||||
}
|
||||
{
|
||||
std::vector<int> v;
|
||||
std::list<int> l;
|
||||
l += 10,11,12,13,14,15,16,17,18,19,20;
|
||||
|
||||
test_concatenate_iterator::apply(v, l, "empty_first");
|
||||
}
|
||||
{
|
||||
std::vector<int> v;
|
||||
v += 0,1,2,3,4,5,6;
|
||||
std::list<int> l;
|
||||
|
||||
test_concatenate_iterator::apply(v, l, "empty_second");
|
||||
}
|
||||
{
|
||||
std::vector<int> v;
|
||||
v += 0,1,2,3,4,5,6;
|
||||
std::list<int> l;
|
||||
l += 10,11,12,13,14,15,16,17,18,19,20;
|
||||
|
||||
test_concatenate_iterator::apply(l, v, "non_empty");
|
||||
}
|
||||
}
|
||||
430
test/iterators/flatten_iterator.cpp
Normal file
430
test/iterators/flatten_iterator.cpp
Normal file
@@ -0,0 +1,430 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_TEST_MODULE
|
||||
#define BOOST_TEST_MODULE test_flatten_iterator
|
||||
#endif
|
||||
|
||||
#include <boost/test/included/unit_test.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/assign/std/vector.hpp>
|
||||
#include <boost/assign/std/list.hpp>
|
||||
#include <boost/assign/std/set.hpp>
|
||||
#include <boost/geometry/iterators/flatten_iterator.hpp>
|
||||
|
||||
using namespace boost::assign;
|
||||
|
||||
template <typename Iterator>
|
||||
std::ostream& print_container(std::ostream& os,
|
||||
Iterator begin, Iterator end,
|
||||
std::string const& header)
|
||||
{
|
||||
std::cout << header;
|
||||
for (Iterator it = begin; it != end; ++it)
|
||||
{
|
||||
os << " " << *it;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
template <typename Iterator>
|
||||
std::ostream& print_nested_container(std::ostream& os,
|
||||
Iterator begin, Iterator end,
|
||||
std::string const& header)
|
||||
{
|
||||
std::cout << header;
|
||||
for (Iterator outer = begin; outer != end; ++outer)
|
||||
{
|
||||
os << " (";
|
||||
for (BOOST_AUTO_TPL(inner, outer->begin());
|
||||
inner != outer->end(); ++inner)
|
||||
{
|
||||
if ( inner != outer->begin() )
|
||||
{
|
||||
os << " ";
|
||||
}
|
||||
os << *inner;
|
||||
}
|
||||
os << ") ";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct is_odd
|
||||
{
|
||||
inline bool operator()(T const& t) const
|
||||
{
|
||||
return t % 2 != 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct is_even
|
||||
{
|
||||
inline bool operator()(T const& t) const
|
||||
{
|
||||
return !is_odd<T>()(t);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename InnerContainer>
|
||||
struct access_begin
|
||||
{
|
||||
typedef typename boost::mpl::if_
|
||||
<
|
||||
typename boost::is_const<InnerContainer>::type,
|
||||
typename InnerContainer::const_iterator,
|
||||
typename InnerContainer::iterator
|
||||
>::type return_type;
|
||||
|
||||
static inline return_type apply(InnerContainer& inner)
|
||||
{
|
||||
return inner.begin();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename InnerContainer>
|
||||
struct access_end
|
||||
{
|
||||
typedef typename boost::mpl::if_
|
||||
<
|
||||
typename boost::is_const<InnerContainer>::type,
|
||||
typename InnerContainer::const_iterator,
|
||||
typename InnerContainer::iterator
|
||||
>::type return_type;
|
||||
|
||||
static inline return_type apply(InnerContainer& inner)
|
||||
{
|
||||
return inner.end();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename NestedContainer>
|
||||
std::size_t number_of_elements(NestedContainer const& c)
|
||||
{
|
||||
std::size_t num_elements(0);
|
||||
for (typename NestedContainer::const_iterator outer = c.begin();
|
||||
outer != c.end(); ++outer)
|
||||
{
|
||||
num_elements += outer->size();
|
||||
}
|
||||
return num_elements;
|
||||
}
|
||||
|
||||
|
||||
struct test_flatten_iterator
|
||||
{
|
||||
template <typename NestedContainer>
|
||||
static inline void apply(NestedContainer& c,
|
||||
std::string const& case_id,
|
||||
std::string const& container_id)
|
||||
{
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::stringstream sstream;
|
||||
sstream << case_id << " " << "[" << container_id << "]";
|
||||
|
||||
std::cout << "case id: " << sstream.str() << std::endl;
|
||||
#endif
|
||||
typedef typename NestedContainer::const_iterator const_outer_iterator;
|
||||
typedef typename NestedContainer::iterator outer_iterator;
|
||||
typedef typename NestedContainer::value_type inner_container;
|
||||
|
||||
typedef typename inner_container::const_iterator const_inner_iterator;
|
||||
typedef typename inner_container::iterator inner_iterator;
|
||||
|
||||
typedef boost::geometry::flatten_iterator
|
||||
<
|
||||
const_outer_iterator,
|
||||
const_inner_iterator,
|
||||
typename inner_container::value_type const,
|
||||
access_begin<inner_container const>,
|
||||
access_end<inner_container const>
|
||||
> const_flatten_iterator;
|
||||
|
||||
typedef boost::geometry::flatten_iterator
|
||||
<
|
||||
outer_iterator,
|
||||
inner_iterator,
|
||||
typename inner_container::value_type,
|
||||
access_begin<inner_container>,
|
||||
access_end<inner_container>
|
||||
> flatten_iterator;
|
||||
|
||||
|
||||
flatten_iterator begin(c.begin(), c.end());
|
||||
flatten_iterator end(c.end());
|
||||
const_flatten_iterator const_begin(begin);
|
||||
const_flatten_iterator const_end(end);
|
||||
const_begin = begin;
|
||||
const_end = end;
|
||||
|
||||
std::size_t size(0);
|
||||
for (const_flatten_iterator it = const_begin; it != const_end; ++it)
|
||||
{
|
||||
++size;
|
||||
}
|
||||
BOOST_CHECK( number_of_elements(c) == size );
|
||||
|
||||
size = 0;
|
||||
for (flatten_iterator it = begin; it != end; ++it)
|
||||
{
|
||||
++size;
|
||||
}
|
||||
BOOST_CHECK( number_of_elements(c) == size );
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
print_nested_container(std::cout, c.begin(), c.end(), "nested :")
|
||||
<< std::endl;
|
||||
print_container(std::cout, begin, end, "flattened :")
|
||||
<< std::endl;
|
||||
|
||||
if ( begin != end )
|
||||
{
|
||||
std::cout << "min element: "
|
||||
<< *std::min_element(begin, end)
|
||||
<< std::endl;
|
||||
std::cout << "max element: "
|
||||
<< *std::max_element(const_begin, const_end)
|
||||
<< std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
const_flatten_iterator it = begin;
|
||||
const_outer_iterator outer_begin = c.begin();
|
||||
const_outer_iterator outer_end = c.end();
|
||||
for (const_outer_iterator outer = outer_begin;
|
||||
outer != outer_end; ++outer)
|
||||
{
|
||||
const_inner_iterator inner_begin = outer->begin();
|
||||
const_inner_iterator inner_end = outer->end();
|
||||
for (const_inner_iterator inner = inner_begin;
|
||||
inner != inner_end; ++inner, it++)
|
||||
// it++, instead of ++it, on purpose here
|
||||
{
|
||||
BOOST_CHECK( *it == *inner );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef typename std::iterator_traits
|
||||
<
|
||||
flatten_iterator
|
||||
>::value_type value_type;
|
||||
|
||||
if ( begin != end )
|
||||
{
|
||||
flatten_iterator it_max = std::max_element(begin, end);
|
||||
const_flatten_iterator const_it_max =
|
||||
std::max_element(const_begin, const_end);
|
||||
|
||||
BOOST_CHECK( it_max == const_it_max );
|
||||
BOOST_CHECK( *it_max == *const_it_max );
|
||||
|
||||
value_type old_value = *const_begin;
|
||||
value_type new_value = *it_max + 1;
|
||||
|
||||
*begin = *it_max + 1;
|
||||
const_outer_iterator outer = c.begin();
|
||||
while ( outer->begin() == outer->end() )
|
||||
{
|
||||
++outer;
|
||||
}
|
||||
const_inner_iterator inner = outer->begin();
|
||||
|
||||
BOOST_CHECK( *inner == new_value );
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << std::endl;
|
||||
std::cout << "modified 1st element of 1st non-empty "
|
||||
<< "inner container:" << std::endl;
|
||||
print_nested_container(std::cout, c.begin(), c.end(), "nested :")
|
||||
<< std::endl;
|
||||
print_container(std::cout, begin, end, "flattened:")
|
||||
<< std::endl;
|
||||
#endif
|
||||
|
||||
*begin = old_value;
|
||||
BOOST_CHECK( *inner == old_value );
|
||||
}
|
||||
|
||||
|
||||
if ( begin != end )
|
||||
{
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << std::endl;
|
||||
std::cout << "odd elements removed:" << std::endl;
|
||||
print_nested_container(std::cout, c.begin(), c.end(),
|
||||
"nested before:")
|
||||
<< std::endl;
|
||||
print_container(std::cout, begin, end,
|
||||
"flattended before:")
|
||||
<< std::endl;
|
||||
#endif
|
||||
typename std::iterator_traits<flatten_iterator>::difference_type
|
||||
num_even = std::count_if(begin, end, is_even<int>());
|
||||
|
||||
flatten_iterator new_end =
|
||||
std::remove_if(begin, end, is_odd<value_type>());
|
||||
|
||||
std::size_t new_size(0);
|
||||
for (const_flatten_iterator it = const_begin; it != new_end; ++it)
|
||||
{
|
||||
++new_size;
|
||||
BOOST_CHECK( !is_odd<value_type>()(*it) );
|
||||
}
|
||||
BOOST_CHECK( new_size == static_cast<std::size_t>(num_even) );
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << std::endl;
|
||||
print_nested_container(std::cout, c.begin(), c.end(),
|
||||
"nested after (all elements) :")
|
||||
<< std::endl;
|
||||
print_container(std::cout, begin, new_end, "flattened after :")
|
||||
<< std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << "====================" << std::endl << std::endl;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// the actual test cases -- START
|
||||
template <int CaseNumber>
|
||||
struct test_case_per_container;
|
||||
|
||||
template<>
|
||||
struct test_case_per_container<0>
|
||||
{
|
||||
template <typename NestedContainer>
|
||||
static inline void apply(std::string const& case_id,
|
||||
std::string const& container_id)
|
||||
{
|
||||
NestedContainer c;
|
||||
test_flatten_iterator::apply(c, case_id, container_id);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct test_case_per_container<1>
|
||||
{
|
||||
template <typename NestedContainer>
|
||||
static inline void apply(std::string const& case_id,
|
||||
std::string const& container_id)
|
||||
{
|
||||
NestedContainer c;
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
c += typename NestedContainer::value_type();
|
||||
}
|
||||
test_flatten_iterator::apply(c, case_id, container_id);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct test_case_per_container<2>
|
||||
{
|
||||
template <typename NestedContainer>
|
||||
static inline void apply(std::string const& case_id,
|
||||
std::string const& container_id)
|
||||
{
|
||||
NestedContainer c;
|
||||
typename NestedContainer::value_type ic[4];
|
||||
|
||||
ic[0] += 5,4,3,2,1;
|
||||
ic[1] += 6,7,8;
|
||||
ic[2] += 9;
|
||||
ic[3] += 9,8,7,6,5;
|
||||
c += ic[0],ic[1],ic[2],ic[3];
|
||||
|
||||
test_flatten_iterator::apply(c, case_id, container_id);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct test_case_per_container<3>
|
||||
{
|
||||
template <typename NestedContainer>
|
||||
static inline void apply(std::string const& case_id,
|
||||
std::string const& container_id)
|
||||
{
|
||||
NestedContainer c;
|
||||
typename NestedContainer::value_type ic[20];
|
||||
|
||||
ic[2] += 5,4,3,2,1;
|
||||
ic[3] += 6,7,8;
|
||||
ic[8] += 9;
|
||||
ic[9] += 9,8,7,6,5;
|
||||
ic[14] += 4,3,2,1;
|
||||
for (std::size_t i = 0; i < 20; ++i)
|
||||
{
|
||||
c += ic[i];
|
||||
}
|
||||
|
||||
test_flatten_iterator::apply(c, case_id, container_id);
|
||||
}
|
||||
};
|
||||
// the actual test cases -- END
|
||||
|
||||
|
||||
|
||||
template <int CaseNumber>
|
||||
inline void test_case_all_containers(std::string const& case_id)
|
||||
{
|
||||
typedef typename std::vector<std::vector<int> > VV;
|
||||
typedef typename std::vector<std::list<int> > VL;
|
||||
typedef typename std::list<std::vector<int> > LV;
|
||||
typedef typename std::list<std::list<int> > LL;
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << std::endl << std::endl;
|
||||
#endif
|
||||
test_case_per_container<CaseNumber>::template apply<VV>(case_id, "VV");
|
||||
test_case_per_container<CaseNumber>::template apply<VL>(case_id, "VL");
|
||||
test_case_per_container<CaseNumber>::template apply<LV>(case_id, "LV");
|
||||
test_case_per_container<CaseNumber>::template apply<LL>(case_id, "LL");
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << std::endl;
|
||||
std::cout << "********************************************************"
|
||||
<< std::endl << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_flatten_iterator_all )
|
||||
{
|
||||
test_case_all_containers<0>("empty");
|
||||
test_case_all_containers<1>("case1");
|
||||
test_case_all_containers<2>("case2");
|
||||
test_case_all_containers<3>("case3");
|
||||
}
|
||||
468
test/iterators/point_iterator.cpp
Normal file
468
test/iterators/point_iterator.cpp
Normal file
@@ -0,0 +1,468 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#ifndef BOOST_TEST_MODULE
|
||||
#define BOOST_TEST_MODULE test_point_iterator
|
||||
#endif
|
||||
|
||||
#include <boost/test/included/unit_test.hpp>
|
||||
|
||||
#include <boost/assign/list_of.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/geometries.hpp>
|
||||
#include <boost/geometry/geometries/adapted/boost_tuple.hpp>
|
||||
#include <boost/geometry/multi/geometries/multi_geometries.hpp>
|
||||
#include <boost/geometry/multi/geometries/register/multi_point.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/equals.hpp>
|
||||
|
||||
#include <boost/geometry/io/wkt/read.hpp>
|
||||
#include <boost/geometry/io/wkt/write.hpp>
|
||||
#include <boost/geometry/io/dsv/write.hpp>
|
||||
#include <boost/geometry/multi/io/dsv/write.hpp>
|
||||
#include <boost/geometry/multi/io/wkt/write.hpp>
|
||||
#include <boost/geometry/multi/io/wkt/read.hpp>
|
||||
|
||||
#include <boost/geometry/iterators/point_iterator.hpp>
|
||||
|
||||
namespace bg = ::boost::geometry;
|
||||
namespace ba = ::boost::assign;
|
||||
|
||||
typedef bg::model::point<double, 2, bg::cs::cartesian> point_type;
|
||||
typedef bg::model::point<double, 3, bg::cs::cartesian> point_type_3d;
|
||||
typedef bg::model::linestring<point_type> linestring_type;
|
||||
typedef bg::model::polygon<point_type, false, false> polygon_type; //ccw, open
|
||||
|
||||
// multi geometries
|
||||
typedef bg::model::multi_point<point_type> multi_point_type;
|
||||
typedef bg::model::multi_point<point_type_3d> multi_point_type_3d;
|
||||
typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
|
||||
typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
|
||||
|
||||
typedef boost::tuple<double, double> tuple_point_type;
|
||||
typedef boost::tuple<double, double, double> tuple_point_type_3d;
|
||||
typedef std::vector<tuple_point_type> tuple_multi_point_type;
|
||||
typedef std::vector<tuple_point_type_3d> tuple_multi_point_type_3d;
|
||||
|
||||
BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)
|
||||
BOOST_GEOMETRY_REGISTER_MULTI_POINT(tuple_multi_point_type)
|
||||
BOOST_GEOMETRY_REGISTER_MULTI_POINT(tuple_multi_point_type_3d)
|
||||
|
||||
|
||||
template <typename Geometry>
|
||||
Geometry from_wkt(std::string const& wkt)
|
||||
{
|
||||
Geometry geometry;
|
||||
boost::geometry::read_wkt(wkt, geometry);
|
||||
return geometry;
|
||||
}
|
||||
|
||||
|
||||
struct equals
|
||||
{
|
||||
template <typename Iterator>
|
||||
static inline std::size_t number_of_elements(Iterator begin,
|
||||
Iterator end)
|
||||
{
|
||||
std::size_t num_elems(0);
|
||||
for (Iterator it = begin; it != end; ++it)
|
||||
{
|
||||
++num_elems;
|
||||
}
|
||||
return num_elems;
|
||||
}
|
||||
|
||||
template <typename Iterator1, typename Iterator2>
|
||||
static inline bool apply(Iterator1 begin1, Iterator1 end1,
|
||||
Iterator2 begin2, Iterator2 end2)
|
||||
{
|
||||
std::size_t num_points1 = number_of_elements(begin1, end1);
|
||||
std::size_t num_points2 = number_of_elements(begin2, end2);
|
||||
|
||||
if ( num_points1 != num_points2 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Iterator1 it1 = begin1;
|
||||
Iterator2 it2 = begin2;
|
||||
for (; it1 != end1; ++it1, ++it2)
|
||||
{
|
||||
if ( !bg::equals(*it1, *it2) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct test_assignment
|
||||
{
|
||||
template <typename Iterator, typename ConstIterator, typename Value>
|
||||
static inline void apply(Iterator it, ConstIterator cit,
|
||||
Value const& value1, Value const& value2)
|
||||
{
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << "== before assignment ==" << std::endl;
|
||||
std::cout << "value1: " << bg::wkt(value1) << std::endl;
|
||||
std::cout << "value2: " << bg::wkt(value2) << std::endl;
|
||||
std::cout << "*it : " << bg::wkt(*it) << std::endl;
|
||||
std::cout << "*cit : " << bg::wkt(*cit) << std::endl;
|
||||
#endif
|
||||
|
||||
BOOST_CHECK( bg::equals(*it, value1) );
|
||||
BOOST_CHECK( !bg::equals(*it, value2) );
|
||||
BOOST_CHECK( bg::equals(*cit, value1) );
|
||||
BOOST_CHECK( !bg::equals(*cit, value2) );
|
||||
|
||||
*it = value2;
|
||||
BOOST_CHECK( bg::equals(*it, value2) );
|
||||
BOOST_CHECK( !bg::equals(*it, value1) );
|
||||
BOOST_CHECK( bg::equals(*cit, value2) );
|
||||
BOOST_CHECK( !bg::equals(*cit, value1) );
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << "== after 1st assignment ==" << std::endl;
|
||||
std::cout << "value1: " << bg::wkt(value1) << std::endl;
|
||||
std::cout << "value2: " << bg::wkt(value2) << std::endl;
|
||||
std::cout << "*it : " << bg::wkt(*it) << std::endl;
|
||||
std::cout << "*cit : " << bg::wkt(*cit) << std::endl;
|
||||
#endif
|
||||
|
||||
*it = value1;
|
||||
BOOST_CHECK( bg::equals(*it, value1) );
|
||||
BOOST_CHECK( !bg::equals(*it, value2) );
|
||||
BOOST_CHECK( bg::equals(*cit, value1) );
|
||||
BOOST_CHECK( !bg::equals(*cit, value2) );
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << "== after 2nd assignment ==" << std::endl;
|
||||
std::cout << "value1: " << bg::wkt(value1) << std::endl;
|
||||
std::cout << "value2: " << bg::wkt(value2) << std::endl;
|
||||
std::cout << "*it : " << bg::wkt(*it) << std::endl;
|
||||
std::cout << "*cit : " << bg::wkt(*cit) << std::endl;
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Geometry, typename PointRange>
|
||||
struct test_point_iterator_of_geometry
|
||||
{
|
||||
template <typename G>
|
||||
static inline void base_test(G& geometry,
|
||||
PointRange const& point_range,
|
||||
std::string const& header)
|
||||
{
|
||||
typedef bg::point_iterator<G> point_iterator;
|
||||
typedef bg::point_iterator<G const> const_point_iterator;
|
||||
|
||||
point_iterator begin = bg::points_begin(geometry);
|
||||
point_iterator end = bg::points_end(geometry);
|
||||
|
||||
BOOST_CHECK( equals::apply(begin, end,
|
||||
bg::points_begin(point_range),
|
||||
bg::points_end(point_range))
|
||||
);
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << header << " geometry: " << bg::wkt(geometry) << std::endl;
|
||||
std::cout << "point range: (";
|
||||
for (point_iterator pit = begin; pit != end; ++pit)
|
||||
{
|
||||
std::cout << " " << bg::dsv(*pit);
|
||||
}
|
||||
std::cout << " )" << std::endl;
|
||||
|
||||
typedef bg::point_iterator<PointRange const> point_range_iterator;
|
||||
|
||||
point_range_iterator rng_begin = bg::points_begin(point_range);
|
||||
point_range_iterator rng_end = bg::points_end(point_range);
|
||||
std::cout << "expected point range: (";
|
||||
for (point_range_iterator pit = rng_begin; pit != rng_end; ++pit)
|
||||
{
|
||||
std::cout << " " << bg::dsv(*pit);
|
||||
}
|
||||
std::cout << " )" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void apply(Geometry geometry, PointRange const& point_range)
|
||||
{
|
||||
base_test<Geometry>(geometry, point_range, "non-const");
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
|
||||
base_test<Geometry const>(geometry, point_range, "const");
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << std::endl << std::endl;
|
||||
#endif
|
||||
|
||||
// testing construction of const and non-const iterator
|
||||
typedef bg::point_iterator<Geometry> point_iterator;
|
||||
typedef bg::point_iterator<Geometry const> const_point_iterator;
|
||||
|
||||
point_iterator begin = bg::points_begin(geometry);
|
||||
point_iterator end = bg::points_end(geometry);
|
||||
|
||||
const_point_iterator const_begin = bg::points_begin(geometry);
|
||||
const_point_iterator const_end = bg::points_end(geometry);
|
||||
|
||||
// testing assignment of non-const to const iterator
|
||||
const_begin = begin;
|
||||
const_end = end;
|
||||
|
||||
// testing dereferencing/assignment
|
||||
if ( begin != end )
|
||||
{
|
||||
typedef typename bg::point_type<Geometry>::type point;
|
||||
|
||||
point p = *begin;
|
||||
point q = bg::make_zero<point>();
|
||||
|
||||
test_assignment::apply(begin, const_begin, p, q);
|
||||
|
||||
*begin = q;
|
||||
test_assignment::apply(begin, const_begin, q, p);
|
||||
|
||||
*begin = p;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//======================================================================
|
||||
//======================================================================
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_linestring_point_iterator )
|
||||
{
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << "*** LINESTRING ***" << std::endl;
|
||||
#endif
|
||||
|
||||
typedef tuple_multi_point_type TMP;
|
||||
typedef linestring_type L;
|
||||
|
||||
typedef test_point_iterator_of_geometry<L, TMP> tester;
|
||||
|
||||
tester::apply(from_wkt<L>("LINESTRING()"),
|
||||
TMP()
|
||||
);
|
||||
|
||||
tester::apply(from_wkt<L>("LINESTRING(3 3,4 4,5 5)"),
|
||||
ba::tuple_list_of(3,3)(4,4)(5,5)
|
||||
);
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << std::endl << std::endl << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//======================================================================
|
||||
//======================================================================
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_polygon_point_iterator )
|
||||
{
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << "*** POLYGON ***" << std::endl;
|
||||
#endif
|
||||
|
||||
typedef tuple_multi_point_type TMP;
|
||||
typedef polygon_type P;
|
||||
|
||||
typedef test_point_iterator_of_geometry<P, TMP> tester;
|
||||
|
||||
tester::apply(from_wkt<P>("POLYGON()"),
|
||||
TMP()
|
||||
);
|
||||
|
||||
tester::apply(from_wkt<P>("POLYGON(())"),
|
||||
TMP()
|
||||
);
|
||||
|
||||
tester::apply(from_wkt<P>("POLYGON((1 1,9 1,9 9,1 9),(5 5,6 5,6 6,5 6))"),
|
||||
ba::tuple_list_of(1,1)(9,1)(9,9)(1,9)(5,5)(6,5)(6,6)(5,6)
|
||||
);
|
||||
|
||||
tester::apply(from_wkt<P>("POLYGON((3 3,4 4,5 5),(),(),(),(6 6,7 7,8 8),(),(),(9 9),())"),
|
||||
ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9)
|
||||
);
|
||||
|
||||
tester::apply(from_wkt<P>("POLYGON((),(3 3,4 4,5 5),(),(),(6 6,7 7,8 8),(),(),(9 9),())"),
|
||||
ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9)
|
||||
);
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << std::endl << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//======================================================================
|
||||
//======================================================================
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_multipoint_point_iterator )
|
||||
{
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << "*** MULTIPOINT ***" << std::endl;
|
||||
#endif
|
||||
|
||||
typedef tuple_multi_point_type TMP;
|
||||
typedef multi_point_type MP;
|
||||
|
||||
typedef test_point_iterator_of_geometry<MP, TMP> tester;
|
||||
|
||||
tester::apply(from_wkt<MP>("MULTIPOINT()"),
|
||||
TMP()
|
||||
);
|
||||
|
||||
tester::apply(from_wkt<MP>("MULTIPOINT(3 3,4 4,5 5)"),
|
||||
ba::tuple_list_of(3,3)(4,4)(5,5)
|
||||
);
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << std::endl << std::endl << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//======================================================================
|
||||
//======================================================================
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_multipoint_3d_point_iterator )
|
||||
{
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << "*** MULTIPOINT 3D ***" << std::endl;
|
||||
#endif
|
||||
|
||||
typedef tuple_multi_point_type_3d TMP;
|
||||
typedef multi_point_type_3d MP;
|
||||
|
||||
typedef test_point_iterator_of_geometry<MP, TMP> tester;
|
||||
|
||||
tester::apply(from_wkt<MP>("MULTIPOINT()"),
|
||||
TMP()
|
||||
);
|
||||
|
||||
tester::apply(from_wkt<MP>("MULTIPOINT(3 3 3,4 4 4,5 5 5)"),
|
||||
ba::tuple_list_of(3,3,3)(4,4,4)(5,5,5)
|
||||
);
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << std::endl << std::endl << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//======================================================================
|
||||
//======================================================================
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_multilinestring_point_iterator )
|
||||
{
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << "*** MULTILINESTRING ***" << std::endl;
|
||||
#endif
|
||||
|
||||
typedef tuple_multi_point_type TMP;
|
||||
typedef multi_linestring_type ML;
|
||||
|
||||
typedef test_point_iterator_of_geometry<ML, TMP> tester;
|
||||
|
||||
tester::apply(from_wkt<ML>("MULTILINESTRING()"),
|
||||
TMP()
|
||||
);
|
||||
|
||||
tester::apply(from_wkt<ML>("MULTILINESTRING(())"),
|
||||
TMP()
|
||||
);
|
||||
|
||||
tester::apply(from_wkt<ML>("MULTILINESTRING((),(),())"),
|
||||
TMP()
|
||||
);
|
||||
|
||||
tester::apply(from_wkt<ML>("MULTILINESTRING((1 1,2 2,3 3),(3 3,4 4,5 5),(6 6))"),
|
||||
ba::tuple_list_of(1,1)(2,2)(3,3)(3,3)(4,4)(5,5)(6,6)
|
||||
);
|
||||
|
||||
tester::apply(from_wkt<ML>("MULTILINESTRING((),(),(1 1,2 2,3 3),(),(),(3 3,4 4,5 5),(),(6 6),(),(),())"),
|
||||
ba::tuple_list_of(1,1)(2,2)(3,3)(3,3)(4,4)(5,5)(6,6)
|
||||
);
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << std::endl << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//======================================================================
|
||||
//======================================================================
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_multipolygon_point_iterator )
|
||||
{
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << "*** MULTIPOLYGON ***" << std::endl;
|
||||
#endif
|
||||
|
||||
typedef tuple_multi_point_type TMP;
|
||||
typedef multi_polygon_type MPL;
|
||||
|
||||
typedef test_point_iterator_of_geometry<MPL, TMP> tester;
|
||||
|
||||
tester::apply(from_wkt<MPL>("MULTIPOLYGON()"),
|
||||
TMP()
|
||||
);
|
||||
|
||||
tester::apply(from_wkt<MPL>("MULTIPOLYGON( () )"),
|
||||
TMP()
|
||||
);
|
||||
|
||||
tester::apply(from_wkt<MPL>("MULTIPOLYGON( (()) )"),
|
||||
TMP()
|
||||
);
|
||||
|
||||
tester::apply(from_wkt<MPL>("MULTIPOLYGON( ((),()) )"),
|
||||
TMP()
|
||||
);
|
||||
|
||||
tester::apply(from_wkt<MPL>("MULTIPOLYGON(((3 3,4 4,5 5),(6 6,7 7,8 8),(9 9)),((1 1,2 2,10 10),(11 11,12 12)))"),
|
||||
ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9)\
|
||||
(1,1)(2,2)(10,10)(11,11)(12,12)
|
||||
);
|
||||
|
||||
tester::apply(from_wkt<MPL>("MULTIPOLYGON(((3 3,4 4,5 5),(),(),(),(6 6,7 7,8 8),(),(),(9 9),()),((),(1 1,2 2,10 10),(),(),(),(11 11,12 12),(),(),(13 13),()))"),
|
||||
ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9)\
|
||||
(1,1)(2,2)(10,10)(11,11)(12,12)(13,13)
|
||||
);
|
||||
|
||||
tester::apply(from_wkt<MPL>("MULTIPOLYGON(((3 3,4 4,5 5),(),(),(),(6 6,7 7,8 8),(),(),(9 9),()),((),(1 1,2 2,10 10),(),(),(),(11 11,12 12),(),(),(13 13),()),((),(),()))"),
|
||||
ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9)\
|
||||
(1,1)(2,2)(10,10)(11,11)(12,12)(13,13)
|
||||
);
|
||||
|
||||
#ifdef GEOMETRY_TEST_DEBUG
|
||||
std::cout << std::endl << std::endl;
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user