Merge branch 'develop' into feature/buffer

This commit is contained in:
Barend Gehrels 2014-08-27 11:34:07 +02:00
commit 12b61c6a0f
45 changed files with 1075 additions and 771 deletions

View File

@ -21,7 +21,7 @@
[[Case] [Behavior] ]
[[__point__][[qbk_ret 1]]]
[[__segment__][[qbk_ret 2]]]
[[__box__][[qbk_ret 4]]]
[[__box__][[qbk_ret 2^d, where d is the dimension of the box]]]
[[__range__][[qbk_ret boost::size(geometry)]]]
[[__other__][[qbk_ret the sum of the number of points of its elements]]]
[[Open geometries][[qbk_ret the sum of the number of points of its elements, it adds one for open (per ring) if specified]]]

View File

@ -16,13 +16,11 @@
[heading Behavior]
[table
[[Case] [Behavior] ]
[[__point__][[qbk_ret 0]]]
[[__0dim__][[qbk_ret 0]]]
[[__segment__][[qbk_ret 1]]]
[[__box__][[qbk_ret 4]]]
[[__box__][[qbk_ret d * 2^(d-1), where d is the dimension of the box]]]
[[__range__][[qbk_ret boost::size(geometry) - 1]]]
[[__other__][[qbk_ret the sum of the number of segments of its elements]]]
[[Open geometries][[qbk_ret the sum of the number of segments of its elements, it adds one for open (per ring) if specified]]]
[[Closed geometries][[qbk_ret the sum of the number of segments of its elements]]]
]
@ -32,4 +30,3 @@ Constant or Linear
[heading Examples]
[num_segments]
[num_segments_output]

View File

@ -48,6 +48,7 @@
* [@https://svn.boost.org/trac/boost/ticket/9828 9828] boost::geometry::union_(...) creates redundant closing point
* [@https://svn.boost.org/trac/boost/ticket/9871 9871] Remove spike in polygon with only a spike
* [@https://svn.boost.org/trac/boost/ticket/9947 9947] Missing info about WKT in documentation
* [@https://svn.boost.org/trac/boost/ticket/9759 9759] Invalid results of R-tree knn queries for non-cartesian coordinate systems
* [@https://svn.boost.org/trac/boost/ticket/10019 10019] Difference of Linestring and Box returns their intersection
* [@https://svn.boost.org/trac/boost/ticket/10077 10077] Wrong types in concept checks in boost/geometry/arithmetic/arithmetic.hpp
* [@https://svn.boost.org/trac/boost/ticket/10234 10234] Wrong results of covered_by() for nearly-horizontal segments

View File

@ -28,7 +28,6 @@ int main()
> mp;
boost::geometry::read_wkt("MULTIPOLYGON(((0 0,0 10,10 0),(1 1,8 1,1 8)),((10 10,10 20,20 10)))", mp);
std::cout << "Number of segments: " << boost::geometry::num_segments(mp) << std::endl;
std::cout << "Number of segments (add_to_open <- true): " << boost::geometry::num_segments(mp, true) << std::endl;
return 0;
}
@ -39,8 +38,7 @@ int main()
/*`
Output:
[pre
Number of segments: 6
Number of segments (add_to_open <- true): 9
Number of segments: 9
]
*/
//]

View File

@ -0,0 +1,107 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// 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.
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
// 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
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_COUNTING_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_COUNTING_HPP
#include <cstddef>
#include <boost/range.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace counting
{
template <std::size_t D>
struct other_count
{
template <typename Geometry>
static inline std::size_t apply(Geometry const&)
{
return D;
}
template <typename Geometry>
static inline std::size_t apply(Geometry const&, bool)
{
return D;
}
};
template <typename RangeCount>
struct polygon_count
{
template <typename Polygon>
static inline std::size_t apply(Polygon const& poly)
{
std::size_t n = RangeCount::apply(exterior_ring(poly));
typename interior_return_type<Polygon const>::type
rings = interior_rings(poly);
for (typename detail::interior_iterator<Polygon const>::type
it = boost::begin(rings); it != boost::end(rings); ++it)
{
n += RangeCount::apply(*it);
}
return n;
}
};
template <typename SingleCount>
struct multi_count
{
template <typename MultiGeometry>
static inline std::size_t apply(MultiGeometry const& geometry)
{
std::size_t n = 0;
for (typename boost::range_iterator<MultiGeometry const>::type
it = boost::begin(geometry);
it != boost::end(geometry);
++it)
{
n += SingleCount::apply(*it);
}
return n;
}
};
}} // namespace detail::counting
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_COUNTING_HPP

View File

@ -17,6 +17,8 @@
#include <boost/assert.hpp>
#include <boost/range.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
@ -92,6 +94,13 @@ private:
m_r_tree.query(index::nearest(query_geometry, 1), &t_v);
BOOST_ASSERT( n > 0 );
// n above is unused outside BOOST_ASSERT, hence the call
// to boost::ignore_unused below
//
// however, t_v (initialized by the call to m_r_tree.query(...))
// is used below, which is why we cannot put the call to
// m_r_tree.query(...) inside BOOST_ASSERT
boost::ignore_unused(n);
comparable_return_type cd = dispatch::distance
<

View File

@ -11,6 +11,7 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_MULTIPOLYGON_HPP
#include <deque>
#include <vector>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/range.hpp>
@ -22,9 +23,12 @@
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/algorithms/within.hpp>
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
#include <boost/geometry/algorithms/detail/partition.hpp>
#include <boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp>
#include <boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp>
@ -71,6 +75,7 @@ private:
TurnIterator turns_first,
TurnIterator turns_beyond)
{
// collect all polygons that have turns
std::set<int> multi_indices;
for (TurnIterator tit = turns_first; tit != turns_beyond; ++tit)
{
@ -78,28 +83,28 @@ private:
multi_indices.insert(tit->operations[0].other_id.multi_index);
}
// put polygon iterators without turns in a vector
std::vector<PolygonIterator> polygon_iterators;
int multi_index = 0;
for (PolygonIterator it1 = polygons_first; it1 != polygons_beyond;
++it1, ++multi_index)
for (PolygonIterator it = polygons_first; it != polygons_beyond;
++it, ++multi_index)
{
if ( multi_indices.find(multi_index) != multi_indices.end() )
if ( multi_indices.find(multi_index) == multi_indices.end() )
{
continue;
}
for (PolygonIterator it2 = polygons_first;
it2 != polygons_beyond; ++it2)
{
if ( it1 != it2
&&
geometry::within(range::front(exterior_ring(*it1)), *it2)
)
{
return false;
}
polygon_iterators.push_back(it);
}
}
return true;
typename base::item_visitor visitor;
geometry::partition
<
geometry::model::box<typename point_type<MultiPolygon>::type>,
typename base::expand_box,
typename base::overlaps_box
>::apply(polygon_iterators, visitor);
return !visitor.items_overlap;
}

View File

@ -16,6 +16,7 @@
#include <deque>
#include <iterator>
#include <set>
#include <vector>
#include <boost/assert.hpp>
#include <boost/range.hpp>
@ -27,11 +28,18 @@
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/iterators/point_iterator.hpp>
#include <boost/geometry/algorithms/covered_by.hpp>
#include <boost/geometry/algorithms/disjoint.hpp>
#include <boost/geometry/algorithms/expand.hpp>
#include <boost/geometry/algorithms/num_interior_rings.hpp>
#include <boost/geometry/algorithms/within.hpp>
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
#include <boost/geometry/algorithms/detail/partition.hpp>
#include <boost/geometry/algorithms/detail/is_valid/complement_graph.hpp>
#include <boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp>
@ -111,6 +119,46 @@ protected:
};
// structs from partition -- start
struct expand_box
{
template <typename Box, typename Iterator>
static inline void apply(Box& total, Iterator const& it)
{
geometry::expand(total, geometry::return_envelope<Box>(*it));
}
};
struct overlaps_box
{
template <typename Box, typename Iterator>
static inline bool apply(Box const& box, Iterator const& it)
{
return !geometry::disjoint(*it, box);
}
};
struct item_visitor
{
bool items_overlap;
item_visitor() : items_overlap(false) {}
template <typename Item1, typename Item2>
inline void apply(Item1 const& item1, Item2 const& item2)
{
if ( !items_overlap
&& (geometry::within(*points_begin(*item1), *item2)
|| geometry::within(*points_begin(*item2), *item1))
)
{
items_overlap = true;
}
}
};
// structs for partition -- end
template
@ -162,24 +210,30 @@ protected:
ring_indices.insert(tit->operations[0].other_id.ring_index);
}
// put iterators for interior rings without turns in a vector
std::vector<RingIterator> ring_iterators;
ring_index = 0;
for (RingIterator it1 = rings_first; it1 != rings_beyond;
++it1, ++ring_index)
for (RingIterator it = rings_first; it != rings_beyond;
++it, ++ring_index)
{
// do not examine rings that are associated with turns
if ( ring_indices.find(ring_index) == ring_indices.end() )
{
for (RingIterator it2 = rings_first; it2 != rings_beyond; ++it2)
{
if ( it1 != it2
&& geometry::within(range::front(*it1), *it2) )
{
return false;
}
}
ring_iterators.push_back(it);
}
}
return true;
// call partition to check is interior rings are disjoint from
// each other
item_visitor visitor;
geometry::partition
<
geometry::model::box<typename point_type<Polygon>::type>,
expand_box,
overlaps_box
>::apply(ring_iterators, visitor);
return !visitor.items_overlap;
}
template

View File

@ -48,17 +48,23 @@ struct indexed_turn_operation
{
typedef TurnOperation type;
int index;
int operation_index;
std::size_t turn_index;
std::size_t operation_index;
bool discarded;
TurnOperation subject;
// use pointers to avoid copies, const& is not possible because of usage in vector
segment_identifier const* other_seg_id; // segment id of other segment of intersection of two segments
TurnOperation const* subject;
inline indexed_turn_operation(int i, int oi, TurnOperation const& s)
: index(i)
inline indexed_turn_operation(std::size_t ti, std::size_t oi,
TurnOperation const& s,
segment_identifier const& oid)
: turn_index(ti)
, operation_index(oi)
, discarded(false)
, subject(s)
, other_seg_id(&oid)
, subject(&s)
{}
};
template <typename IndexedTurnOperation>
@ -124,13 +130,13 @@ private :
point_type pi, pj, ri, rj, si, sj;
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
left.subject.seg_id,
left.subject->seg_id,
pi, pj);
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
left.subject.other_id,
*left.other_seg_id,
ri, rj);
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
right.subject.other_id,
*right.other_seg_id,
si, sj);
geometry::recalculate(pi_rob, pi, m_robust_policy);
@ -160,21 +166,21 @@ public :
// but to the "indexed_turn_operation"
inline bool operator()(Indexed const& left, Indexed const& right) const
{
segment_identifier const& sl = left.subject.seg_id;
segment_identifier const& sr = right.subject.seg_id;
segment_identifier const& sl = left.subject->seg_id;
segment_identifier const& sr = right.subject->seg_id;
if (sl == sr)
{
// Both left and right are located on the SAME segment.
if (left.subject.fraction == right.subject.fraction)
if (left.subject->fraction == right.subject->fraction)
{
// First check "real" intersection (crosses)
// -> distance zero due to precision, solve it by sorting
// TODO: reconsider this. Using integer maths, this will
// ALWAYS return 0 because either fractions are different, or
// the (currently calculated) relative-order is identical
if (m_turn_points[left.index].method == method_crosses
&& m_turn_points[right.index].method == method_crosses)
if (m_turn_points[left.turn_index].method == method_crosses
&& m_turn_points[right.turn_index].method == method_crosses)
{
return consider_relative_order(left, right);
}
@ -185,7 +191,7 @@ public :
}
}
return sl == sr
? left.subject.fraction < right.subject.fraction
? left.subject->fraction < right.subject->fraction
: sl < sr;
}
};
@ -200,13 +206,13 @@ inline void update_discarded(Turns& turn_points, Operations& operations)
it != boost::end(operations);
++it)
{
if (turn_points[it->index].discarded)
if (turn_points[it->turn_index].discarded)
{
it->discarded = true;
}
else if (it->discarded)
{
turn_points[it->index].discarded = true;
turn_points[it->turn_index].discarded = true;
}
}
}
@ -262,14 +268,14 @@ inline void enrich_sort(Container& operations,
it != boost::end(operations);
prev = it++)
{
operations_type& prev_op = turn_points[prev->index]
operations_type& prev_op = turn_points[prev->turn_index]
.operations[prev->operation_index];
operations_type& op = turn_points[it->index]
operations_type& op = turn_points[it->turn_index]
.operations[it->operation_index];
if (prev_op.seg_id == op.seg_id
&& (turn_points[prev->index].method != method_crosses
|| turn_points[it->index].method != method_crosses)
&& (turn_points[prev->turn_index].method != method_crosses
|| turn_points[it->turn_index].method != method_crosses)
&& prev_op.fraction == op.fraction)
{
if (begin_cluster == boost::end(operations))
@ -346,19 +352,19 @@ inline void enrich_assign(Container& operations,
prev = it++)
{
operations_type& prev_op
= turn_points[prev->index].operations[prev->operation_index];
= turn_points[prev->turn_index].operations[prev->operation_index];
operations_type& op
= turn_points[it->index].operations[it->operation_index];
= turn_points[it->turn_index].operations[it->operation_index];
prev_op.enriched.travels_to_ip_index
= it->index;
= static_cast<int>(it->turn_index);
prev_op.enriched.travels_to_vertex_index
= it->subject.seg_id.segment_index;
= it->subject->seg_id.segment_index;
if (! first
&& prev_op.seg_id.segment_index == op.seg_id.segment_index)
{
prev_op.enriched.next_ip_index = it->index;
prev_op.enriched.next_ip_index = static_cast<int>(it->turn_index);
}
first = false;
}
@ -371,16 +377,16 @@ inline void enrich_assign(Container& operations,
it != boost::end(operations);
++it)
{
operations_type& op = turn_points[it->index]
operations_type& op = turn_points[it->turn_index]
.operations[it->operation_index];
std::cout << it->index
<< " meth: " << method_char(turn_points[it->index].method)
std::cout << it->turn_index
<< " meth: " << method_char(turn_points[it->turn_index].method)
<< " seg: " << op.seg_id
<< " dst: " << op.fraction // needs define
<< " op: " << operation_char(turn_points[it->index].operations[0].operation)
<< operation_char(turn_points[it->index].operations[1].operation)
<< " dsc: " << (turn_points[it->index].discarded ? "T" : "F")
<< " op: " << operation_char(turn_points[it->turn_index].operations[0].operation)
<< operation_char(turn_points[it->turn_index].operations[1].operation)
<< " dsc: " << (turn_points[it->turn_index].discarded ? "T" : "F")
<< " ->vtx " << op.enriched.travels_to_vertex_index
<< " ->ip " << op.enriched.travels_to_ip_index
<< " ->nxt ip " << op.enriched.next_ip_index
@ -401,7 +407,7 @@ inline void create_map(TurnPoints const& turn_points, MappedVector& mapped_vecto
typedef typename boost::range_value<TurnPoints>::type turn_point_type;
typedef typename turn_point_type::container_type container_type;
int index = 0;
std::size_t index = 0;
for (typename boost::range_iterator<TurnPoints const>::type
it = boost::begin(turn_points);
it != boost::end(turn_points);
@ -410,7 +416,7 @@ inline void create_map(TurnPoints const& turn_points, MappedVector& mapped_vecto
// Add operations on this ring, but skip discarded ones
if (! it->discarded)
{
int op_index = 0;
std::size_t op_index = 0;
for (typename boost::range_iterator<container_type const>::type
op_it = boost::begin(it->operations);
op_it != boost::end(it->operations);
@ -428,7 +434,8 @@ inline void create_map(TurnPoints const& turn_points, MappedVector& mapped_vecto
);
mapped_vector[ring_id].push_back
(
IndexedType(index, op_index, *op_it)
IndexedType(index, op_index, *op_it,
it->operations[1 - op_index].seg_id)
);
}
}

View File

@ -245,10 +245,6 @@ struct get_turn_info_for_endpoint
if ( ip_count == 0 )
return false;
int segment_index0 = tp_model.operations[0].seg_id.segment_index;
int segment_index1 = tp_model.operations[1].seg_id.segment_index;
BOOST_ASSERT(segment_index0 >= 0 && segment_index1 >= 0);
if ( !is_p_first && !is_p_last && !is_q_first && !is_q_last )
return false;

View File

@ -652,10 +652,6 @@ struct get_turn_info_linear_areal
if ( ip_count == 0 )
return false;
const int segment_index0 = tp_model.operations[0].seg_id.segment_index;
const int segment_index1 = tp_model.operations[1].seg_id.segment_index;
BOOST_ASSERT(segment_index0 >= 0 && segment_index1 >= 0);
if ( !is_p_first && !is_p_last )
return false;

View File

@ -87,13 +87,13 @@ private :
point_type pi, pj, ri, rj, si, sj;
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
left.subject.seg_id,
left.subject->seg_id,
pi, pj);
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
left.subject.other_id,
*left.other_seg_id,
ri, rj);
geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
right.subject.other_id,
*right.other_seg_id,
si, sj);
geometry::recalculate(pi_rob, pi, m_rescale_policy);
@ -167,7 +167,7 @@ private :
{
if (skip) return;
std::cout << "Case: " << header << " for " << left.index << " / " << right.index << std::endl;
std::cout << "Case: " << header << " for " << left.turn_index << " / " << right.turn_index << std::endl;
robust_point_type pi, pj, ri, rj, si, sj;
get_situation_map(left, right, pi, pj, ri, rj, si, sj);
@ -196,15 +196,15 @@ private :
std::cout << header
//<< " order: " << order
<< " ops: " << operation_char(left.subject.operation)
<< "/" << operation_char(right.subject.operation)
<< " ops: " << operation_char(left.subject->operation)
<< "/" << operation_char(right.subject->operation)
<< " ri//p: " << side_ri_p
<< " si//p: " << side_si_p
<< " si//r: " << side_si_r
#if BOOST_GEOMETRY_HANDLE_TANGENCIES_WITH_OVERLAP_INFO
<< " cnts: " << int(prc) << "," << int(psc) << "," << int(rsc)
#endif
//<< " idx: " << left.index << "/" << right.index
//<< " idx: " << left.turn_index << "/" << right.turn_index
;
if (! extra.empty())
@ -229,17 +229,17 @@ private :
, std::string const& // header
) const
{
bool ret = left.index < right.index;
bool ret = left.turn_index < right.turn_index;
// In combination of u/x, x/u: take first union, then blocked.
// Solves #88, #61, #56, #80
if (left.subject.operation == operation_union
&& right.subject.operation == operation_blocked)
if (left.subject->operation == operation_union
&& right.subject->operation == operation_blocked)
{
ret = true;
}
else if (left.subject.operation == operation_blocked
&& right.subject.operation == operation_union)
else if (left.subject->operation == operation_blocked
&& right.subject->operation == operation_union)
{
ret = false;
}
@ -263,26 +263,26 @@ private :
{
bool ret = false;
if (left.subject.operation == operation_union
&& right.subject.operation == operation_union)
if (left.subject->operation == operation_union
&& right.subject->operation == operation_union)
{
ret = order == 1;
}
else if (left.subject.operation == operation_union
&& right.subject.operation == operation_blocked)
else if (left.subject->operation == operation_union
&& right.subject->operation == operation_blocked)
{
ret = true;
}
else if (right.subject.operation == operation_union
&& left.subject.operation == operation_blocked)
else if (right.subject->operation == operation_union
&& left.subject->operation == operation_blocked)
{
ret = false;
}
else if (left.subject.operation == operation_union)
else if (left.subject->operation == operation_union)
{
ret = true;
}
else if (right.subject.operation == operation_union)
else if (right.subject->operation == operation_union)
{
ret = false;
}
@ -307,10 +307,10 @@ private :
{
//debug_consider(order, left, right, header, false, "iu/ix");
return left.subject.operation == operation_intersection
&& right.subject.operation == operation_intersection ? order == 1
: left.subject.operation == operation_intersection ? false
: right.subject.operation == operation_intersection ? true
return left.subject->operation == operation_intersection
&& right.subject->operation == operation_intersection ? order == 1
: left.subject->operation == operation_intersection ? false
: right.subject->operation == operation_intersection ? true
: order == 1;
}
@ -319,13 +319,13 @@ private :
) const
{
// Take first intersection, then blocked.
if (left.subject.operation == operation_intersection
&& right.subject.operation == operation_blocked)
if (left.subject->operation == operation_intersection
&& right.subject->operation == operation_blocked)
{
return true;
}
else if (left.subject.operation == operation_blocked
&& right.subject.operation == operation_intersection)
else if (left.subject->operation == operation_blocked
&& right.subject->operation == operation_intersection)
{
return false;
}
@ -337,7 +337,7 @@ private :
#endif
//debug_consider(0, left, right, header, false, "-> return", ret);
return left.index < right.index;
return left.turn_index < right.turn_index;
}
@ -347,14 +347,14 @@ private :
//debug_consider(0, left, right, header);
// In general, order it like "union, intersection".
if (left.subject.operation == operation_intersection
&& right.subject.operation == operation_union)
if (left.subject->operation == operation_intersection
&& right.subject->operation == operation_union)
{
//debug_consider(0, left, right, header, false, "i,u", false);
return false;
}
else if (left.subject.operation == operation_union
&& right.subject.operation == operation_intersection)
else if (left.subject->operation == operation_union
&& right.subject->operation == operation_intersection)
{
//debug_consider(0, left, right, header, false, "u,i", true);
return true;
@ -371,8 +371,8 @@ private :
if (side_ri_p * side_si_p == 1 && side_si_r != 0)
{
// Take the most left one
if (left.subject.operation == operation_union
&& right.subject.operation == operation_union)
if (left.subject->operation == operation_union
&& right.subject->operation == operation_union)
{
bool ret = side_si_r == 1;
//debug_consider(0, left, right, header, false, "same side", ret);
@ -456,7 +456,7 @@ private :
#if defined(BOOST_GEOMETRY_DEBUG_HANDLE_TANGENCIES)
std::cout << " iu/iu unhandled" << std::endl;
debug_consider(0, left, right, header, false, "unhandled", left.index < right.index);
debug_consider(0, left, right, header, false, "unhandled", left.turn_index < right.turn_index);
#endif
if (! redo)
{
@ -465,7 +465,7 @@ private :
return ! consider_iu_iu(right, left, header, true);
}
return left.index < right.index;
return left.turn_index < right.turn_index;
}
inline bool consider_ii(Indexed const& left, Indexed const& right,
@ -489,89 +489,89 @@ private :
bool const ret = side_si_r != 1;
return ret;
}
return left.index < right.index;
return left.turn_index < right.turn_index;
}
public :
inline bool operator()(Indexed const& left, Indexed const& right) const
{
bool const default_order = left.index < right.index;
bool const default_order = left.turn_index < right.turn_index;
if ((m_turn_points[left.index].discarded || left.discarded)
&& (m_turn_points[right.index].discarded || right.discarded))
if ((m_turn_points[left.turn_index].discarded || left.discarded)
&& (m_turn_points[right.turn_index].discarded || right.discarded))
{
return default_order;
}
else if (m_turn_points[left.index].discarded || left.discarded)
else if (m_turn_points[left.turn_index].discarded || left.discarded)
{
// Be careful to sort discarded first, then all others
return true;
}
else if (m_turn_points[right.index].discarded || right.discarded)
else if (m_turn_points[right.turn_index].discarded || right.discarded)
{
// See above so return false here such that right (discarded)
// is sorted before left (not discarded)
return false;
}
else if (m_turn_points[left.index].combination(operation_blocked, operation_union)
&& m_turn_points[right.index].combination(operation_blocked, operation_union))
else if (m_turn_points[left.turn_index].combination(operation_blocked, operation_union)
&& m_turn_points[right.turn_index].combination(operation_blocked, operation_union))
{
// ux/ux
return consider_ux_ux(left, right, "ux/ux");
}
else if (m_turn_points[left.index].both(operation_union)
&& m_turn_points[right.index].both(operation_union))
else if (m_turn_points[left.turn_index].both(operation_union)
&& m_turn_points[right.turn_index].both(operation_union))
{
// uu/uu, Order is arbitrary
// Note: uu/uu is discarded now before so this point will
// not be reached.
return default_order;
}
else if (m_turn_points[left.index].combination(operation_intersection, operation_union)
&& m_turn_points[right.index].combination(operation_intersection, operation_union))
else if (m_turn_points[left.turn_index].combination(operation_intersection, operation_union)
&& m_turn_points[right.turn_index].combination(operation_intersection, operation_union))
{
return consider_iu_iu(left, right, "iu/iu");
}
else if (m_turn_points[left.index].combination(operation_intersection, operation_blocked)
&& m_turn_points[right.index].combination(operation_intersection, operation_blocked))
else if (m_turn_points[left.turn_index].combination(operation_intersection, operation_blocked)
&& m_turn_points[right.turn_index].combination(operation_intersection, operation_blocked))
{
return consider_ix_ix(left, right, "ix/ix");
}
else if (m_turn_points[left.index].both(operation_intersection)
&& m_turn_points[right.index].both(operation_intersection))
else if (m_turn_points[left.turn_index].both(operation_intersection)
&& m_turn_points[right.turn_index].both(operation_intersection))
{
return consider_ii(left, right, "ii/ii");
}
else if (m_turn_points[left.index].combination(operation_union, operation_blocked)
&& m_turn_points[right.index].combination(operation_intersection, operation_union))
else if (m_turn_points[left.turn_index].combination(operation_union, operation_blocked)
&& m_turn_points[right.turn_index].combination(operation_intersection, operation_union))
{
return consider_iu_ux(left, right, -1, "ux/iu");
}
else if (m_turn_points[left.index].combination(operation_intersection, operation_union)
&& m_turn_points[right.index].combination(operation_union, operation_blocked))
else if (m_turn_points[left.turn_index].combination(operation_intersection, operation_union)
&& m_turn_points[right.turn_index].combination(operation_union, operation_blocked))
{
return consider_iu_ux(left, right, 1, "iu/ux");
}
else if (m_turn_points[left.index].combination(operation_intersection, operation_blocked)
&& m_turn_points[right.index].combination(operation_intersection, operation_union))
else if (m_turn_points[left.turn_index].combination(operation_intersection, operation_blocked)
&& m_turn_points[right.turn_index].combination(operation_intersection, operation_union))
{
return consider_iu_ix(left, right, 1, "ix/iu");
}
else if (m_turn_points[left.index].combination(operation_intersection, operation_union)
&& m_turn_points[right.index].combination(operation_intersection, operation_blocked))
else if (m_turn_points[left.turn_index].combination(operation_intersection, operation_union)
&& m_turn_points[right.turn_index].combination(operation_intersection, operation_blocked))
{
return consider_iu_ix(left, right, -1, "iu/ix");
}
else if (m_turn_points[left.index].method != method_equal
&& m_turn_points[right.index].method == method_equal
else if (m_turn_points[left.turn_index].method != method_equal
&& m_turn_points[right.turn_index].method == method_equal
)
{
// If one of them was EQUAL or CONTINUES, it should always come first
return false;
}
else if (m_turn_points[left.index].method == method_equal
&& m_turn_points[right.index].method != method_equal
else if (m_turn_points[left.turn_index].method == method_equal
&& m_turn_points[right.turn_index].method != method_equal
)
{
return true;
@ -580,11 +580,11 @@ public :
// Now we have no clue how to sort.
#if defined(BOOST_GEOMETRY_DEBUG_HANDLE_TANGENCIES)
std::cout << " Consider: " << operation_char(m_turn_points[left.index].operations[0].operation)
<< operation_char(m_turn_points[left.index].operations[1].operation)
<< "/" << operation_char(m_turn_points[right.index].operations[0].operation)
<< operation_char(m_turn_points[right.index].operations[1].operation)
<< " " << " Take " << left.index << " < " << right.index
std::cout << " Consider: " << operation_char(m_turn_points[left.turn_index].operations[0].operation)
<< operation_char(m_turn_points[left.turn_index].operations[1].operation)
<< "/" << operation_char(m_turn_points[right.turn_index].operations[0].operation)
<< operation_char(m_turn_points[right.turn_index].operations[1].operation)
<< " " << " Take " << left.turn_index << " < " << right.turn_index
<< std::endl;
#endif
@ -615,8 +615,8 @@ inline void inspect_cluster(Iterator begin_cluster, Iterator end_cluster,
std::map<std::pair<operation_type, operation_type>, int> inspection;
for (Iterator it = begin_cluster; it != end_cluster; ++it)
{
operation_type first = turn_points[it->index].operations[0].operation;
operation_type second = turn_points[it->index].operations[1].operation;
operation_type first = turn_points[it->turn_index].operations[0].operation;
operation_type second = turn_points[it->turn_index].operations[1].operation;
if (first > second)
{
std::swap(first, second);
@ -645,7 +645,7 @@ inline void inspect_cluster(Iterator begin_cluster, Iterator end_cluster,
// Because (in case of not discarding iu) correctly ordering of ii/iu appears impossible
for (Iterator it = begin_cluster; it != end_cluster; ++it)
{
if (turn_points[it->index].combination(operation_intersection, operation_union))
if (turn_points[it->turn_index].combination(operation_intersection, operation_union))
{
it->discarded = true;
}
@ -661,7 +661,7 @@ inline void inspect_cluster(Iterator begin_cluster, Iterator end_cluster,
if (! it->discarded)
{
nd_count++;
if (turn_points[it->index].both(operation_continue))
if (turn_points[it->turn_index].both(operation_continue))
{
cc_count++;
}
@ -677,7 +677,7 @@ inline void inspect_cluster(Iterator begin_cluster, Iterator end_cluster,
{
for (Iterator it = begin_cluster; it != end_cluster; ++it)
{
if (turn_points[it->index].both(operation_continue))
if (turn_points[it->turn_index].both(operation_continue))
{
it->discarded = true;
}
@ -723,24 +723,24 @@ inline void handle_cluster(Iterator begin_cluster, Iterator end_cluster,
#if defined(BOOST_GEOMETRY_DEBUG_HANDLE_TANGENCIES)
typedef typename IndexType::type operations_type;
operations_type const& op = turn_points[begin_cluster->index].operations[begin_cluster->operation_index];
operations_type const& op = turn_points[begin_cluster->turn_index].operations[begin_cluster->operation_index];
std::cout << std::endl << "Clustered points on equal distance " << op.fraction << std::endl;
std::cout << "->Indexes ";
for (Iterator it = begin_cluster; it != end_cluster; ++it)
{
std::cout << " " << it->index;
std::cout << " " << it->turn_index;
}
std::cout << std::endl << "->Methods: ";
for (Iterator it = begin_cluster; it != end_cluster; ++it)
{
std::cout << " " << method_char(turn_points[it->index].method);
std::cout << " " << method_char(turn_points[it->turn_index].method);
}
std::cout << std::endl << "->Operations: ";
for (Iterator it = begin_cluster; it != end_cluster; ++it)
{
std::cout << " " << operation_char(turn_points[it->index].operations[0].operation)
<< operation_char(turn_points[it->index].operations[1].operation);
std::cout << " " << operation_char(turn_points[it->turn_index].operations[0].operation)
<< operation_char(turn_points[it->turn_index].operations[1].operation);
}
std::cout << std::endl << "->Discarded: ";
for (Iterator it = begin_cluster; it != end_cluster; ++it)
@ -750,7 +750,7 @@ inline void handle_cluster(Iterator begin_cluster, Iterator end_cluster,
std::cout << std::endl;
//<< "\tOn segments: " << prev_op.seg_id << " / " << prev_op.other_id
//<< " and " << op.seg_id << " / " << op.other_id
//<< geometry::distance(turn_points[prev->index].point, turn_points[it->index].point)
//<< geometry::distance(turn_points[prev->turn_index].point, turn_points[it->turn_index].point)
#endif
}

View File

@ -844,15 +844,16 @@ struct linear_areal
typedef typename boost::range_iterator<range2_type>::type range2_iterator;
range2_type range2(sub_range(geometry2, turn.operations[other_op_id].seg_id));
std::size_t const s1 = boost::size(range1);
BOOST_ASSERT(boost::size(range1));
std::size_t const s2 = boost::size(range2);
BOOST_ASSERT(s1 > 1 && s2 > 2);
BOOST_ASSERT(s2 > 2);
std::size_t const seg_count2 = s2 - 1;
std::size_t const p_seg_ij = turn.operations[op_id].seg_id.segment_index;
std::size_t const q_seg_ij = turn.operations[other_op_id].seg_id.segment_index;
BOOST_ASSERT(p_seg_ij + 1 < s1 && q_seg_ij + 1 < s2);
BOOST_ASSERT(p_seg_ij + 1 < boost::size(range1));
BOOST_ASSERT(q_seg_ij + 1 < s2);
point1_type const& pi = range::at(range1, p_seg_ij);
point2_type const& qi = range::at(range2, q_seg_ij);

View File

@ -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
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@ -27,6 +32,8 @@
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/algorithms/detail/counting.hpp>
namespace boost { namespace geometry
{
@ -53,12 +60,8 @@ struct num_geometries: not_implemented<Tag>
template <typename Geometry>
struct num_geometries<Geometry, single_tag>
{
static inline std::size_t apply(Geometry const&)
{
return 1;
}
};
: detail::counting::other_count<1>
{};
template <typename MultiGeometry>
@ -72,7 +75,43 @@ struct num_geometries<MultiGeometry, multi_tag>
} // namespace dispatch
#endif
#endif // DOXYGEN_NO_DISPATCH
namespace resolve_variant
{
template <typename Geometry>
struct num_geometries
{
static inline std::size_t apply(Geometry const& geometry)
{
concept::check<Geometry const>();
return dispatch::num_geometries<Geometry>::apply(geometry);
}
};
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct num_geometries<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
struct visitor: boost::static_visitor<std::size_t>
{
template <typename Geometry>
inline std::size_t operator()(Geometry const& geometry) const
{
return num_geometries<Geometry>::apply(geometry);
}
};
static inline std::size_t
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
{
return boost::apply_visitor(visitor(), geometry);
}
};
} // namespace resolve_variant
/*!
@ -88,9 +127,7 @@ struct num_geometries<MultiGeometry, multi_tag>
template <typename Geometry>
inline std::size_t num_geometries(Geometry const& geometry)
{
concept::check<Geometry const>();
return dispatch::num_geometries<Geometry>::apply(geometry);
return resolve_variant::num_geometries<Geometry>::apply(geometry);
}

View File

@ -1,13 +1,14 @@
// 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 Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@ -23,11 +24,19 @@
#include <boost/range.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/algorithms/detail/counting.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
namespace boost { namespace geometry
{
@ -39,12 +48,8 @@ namespace dispatch
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
struct num_interior_rings
{
static inline std::size_t apply(Geometry const& )
{
return 0;
}
};
: detail::counting::other_count<0>
{};
@ -61,28 +66,54 @@ struct num_interior_rings<Polygon, polygon_tag>
template <typename MultiPolygon>
struct num_interior_rings<MultiPolygon, multi_polygon_tag>
{
static inline std::size_t apply(MultiPolygon const& multi_polygon)
{
std::size_t n = 0;
for (typename boost::range_iterator<MultiPolygon const>::type
it = boost::begin(multi_polygon);
it != boost::end(multi_polygon);
++it)
{
n += num_interior_rings
<
typename boost::range_value<MultiPolygon const>::type
>::apply(*it);
}
return n;
}
};
: detail::counting::multi_count
<
num_interior_rings
<
typename boost::range_value<MultiPolygon const>::type
>
>
{};
} // namespace dispatch
#endif
#endif // DOXYGEN_NO_DISPATCH
namespace resolve_variant
{
template <typename Geometry>
struct num_interior_rings
{
static inline std::size_t apply(Geometry const& geometry)
{
concept::check<Geometry const>();
return dispatch::num_interior_rings<Geometry>::apply(geometry);
}
};
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct num_interior_rings<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
struct visitor: boost::static_visitor<std::size_t>
{
template <typename Geometry>
inline std::size_t operator()(Geometry const& geometry) const
{
return num_interior_rings<Geometry>::apply(geometry);
}
};
static inline std::size_t
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
{
return boost::apply_visitor(visitor(), geometry);
}
};
} // namespace resolve_variant
/*!
@ -101,7 +132,7 @@ struct num_interior_rings<MultiPolygon, multi_polygon_tag>
template <typename Geometry>
inline std::size_t num_interior_rings(Geometry const& geometry)
{
return dispatch::num_interior_rings<Geometry>::apply(geometry);
return resolve_variant::num_interior_rings<Geometry>::apply(geometry);
}

View File

@ -1,10 +1,15 @@
// 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.
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
// 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
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@ -17,20 +22,25 @@
#include <cstddef>
#include <boost/mpl/size_t.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/tag_cast.hpp>
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
#include <boost/geometry/algorithms/disjoint.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/tag_cast.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/algorithms/detail/counting.hpp>
#include <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
namespace boost { namespace geometry
{
@ -47,55 +57,26 @@ namespace detail { namespace num_points
{
template <bool AddForOpen>
struct range_count
{
template <typename Range>
static inline std::size_t apply(Range const& range, bool add_for_open)
static inline std::size_t apply(Range const& range)
{
std::size_t n = boost::size(range);
if (add_for_open && n > 0)
if (AddForOpen
&& n > 0
&& geometry::closure<Range>::value == open
&& detail::disjoint::disjoint_point_point(range::front(range),
range::at(range, n - 1))
)
{
if (geometry::closure<Range>::value == open)
{
if (geometry::disjoint(*boost::begin(range), *(boost::begin(range) + n - 1)))
{
return n + 1;
}
}
return n + 1;
}
return n;
}
};
template <std::size_t D>
struct other_count
{
template <typename Geometry>
static inline std::size_t apply(Geometry const&, bool)
{
return D;
}
};
struct polygon_count: private range_count
{
template <typename Polygon>
static inline std::size_t apply(Polygon const& poly, bool add_for_open)
{
std::size_t n = range_count::apply(exterior_ring(poly), add_for_open);
typename interior_return_type<Polygon const>::type
rings = interior_rings(poly);
for (typename detail::interior_iterator<Polygon const>::type
it = boost::begin(rings); it != boost::end(rings); ++it)
{
n += range_count::apply(*it, add_for_open);
}
return n;
}
};
}} // namespace detail::num_points
#endif // DOXYGEN_NO_DETAIL
@ -107,46 +88,62 @@ namespace dispatch
template
<
typename Geometry,
typename Tag = typename tag_cast<typename tag<Geometry>::type, multi_tag>::type
bool AddForOpen,
typename Tag = typename tag_cast
<
typename tag<Geometry>::type, multi_tag
>::type
>
struct num_points: not_implemented<Tag>
{};
template <typename Geometry>
struct num_points<Geometry, point_tag>
: detail::num_points::other_count<1>
template <typename Geometry, bool AddForOpen>
struct num_points<Geometry, AddForOpen, point_tag>
: detail::counting::other_count<1>
{};
template <typename Geometry>
struct num_points<Geometry, box_tag>
: detail::num_points::other_count<4>
template <typename Geometry, bool AddForOpen>
struct num_points<Geometry, AddForOpen, box_tag>
: detail::counting::other_count<(1 << geometry::dimension<Geometry>::value)>
{};
template <typename Geometry>
struct num_points<Geometry, segment_tag>
: detail::num_points::other_count<2>
template <typename Geometry, bool AddForOpen>
struct num_points<Geometry, AddForOpen, segment_tag>
: detail::counting::other_count<2>
{};
template <typename Geometry>
struct num_points<Geometry, linestring_tag>
: detail::num_points::range_count
template <typename Geometry, bool AddForOpen>
struct num_points<Geometry, AddForOpen, linestring_tag>
: detail::num_points::range_count<AddForOpen>
{};
template <typename Geometry>
struct num_points<Geometry, ring_tag>
: detail::num_points::range_count
template <typename Geometry, bool AddForOpen>
struct num_points<Geometry, AddForOpen, ring_tag>
: detail::num_points::range_count<AddForOpen>
{};
template <typename Geometry>
struct num_points<Geometry, polygon_tag>
: detail::num_points::polygon_count
template <typename Geometry, bool AddForOpen>
struct num_points<Geometry, AddForOpen, polygon_tag>
: detail::counting::polygon_count
<
detail::num_points::range_count<AddForOpen>
>
{};
template <typename Geometry, bool AddForOpen>
struct num_points<Geometry, AddForOpen, multi_tag>
: detail::counting::multi_count
<
num_points<typename boost::range_value<Geometry>::type, AddForOpen>
>
{};
} // namespace dispatch
#endif
namespace resolve_variant {
namespace resolve_variant
{
template <typename Geometry>
struct num_points
@ -154,7 +151,11 @@ struct num_points
static inline std::size_t apply(Geometry const& geometry,
bool add_for_open)
{
return dispatch::num_points<Geometry>::apply(geometry, add_for_open);
concept::check<Geometry const>();
return add_for_open
? dispatch::num_points<Geometry, true>::apply(geometry)
: dispatch::num_points<Geometry, false>::apply(geometry);
}
};
@ -168,7 +169,7 @@ struct num_points<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
visitor(bool add_for_open): m_add_for_open(add_for_open) {}
template <typename Geometry>
typename std::size_t operator()(Geometry const& geometry) const
inline std::size_t operator()(Geometry const& geometry) const
{
return num_points<Geometry>::apply(geometry, m_add_for_open);
}
@ -199,8 +200,6 @@ struct num_points<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
template <typename Geometry>
inline std::size_t num_points(Geometry const& geometry, bool add_for_open = false)
{
concept::check<Geometry const>();
return resolve_variant::num_points<Geometry>::apply(geometry, add_for_open);
}

View File

@ -12,6 +12,9 @@
#include <cstddef>
#include <boost/mpl/size_t.hpp>
#include <boost/mpl/times.hpp>
#include <boost/range.hpp>
#include <boost/variant/static_visitor.hpp>
@ -19,9 +22,6 @@
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/interior_type.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
@ -29,35 +29,14 @@
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
#include <boost/geometry/algorithms/disjoint.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
#include <boost/geometry/algorithms/detail/counting.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
template
<
typename Geometry,
typename Tag = typename tag<Geometry>::type
>
struct num_segments
: not_implemented<Tag>
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace num_segments
{
@ -66,72 +45,23 @@ namespace detail { namespace num_segments
struct range_count
{
template <typename Range>
static inline std::size_t apply(Range const& range, bool add_for_open)
static inline std::size_t apply(Range const& range)
{
std::size_t n = boost::size(range);
if ( n <= 1 )
{
return 0;
}
if (add_for_open
&& geometry::closure<Range>::value == open
&& geometry::disjoint(range::front(range), range::at(range, n - 1))
)
{
return n;
}
return static_cast<std::size_t>(n - 1);
return
geometry::closure<Range>::value == open
?
n
:
static_cast<std::size_t>(n - 1);
}
};
struct polygon_count
: private range_count
{
template <typename Polygon>
static inline std::size_t apply(Polygon const& poly, bool add_for_open)
{
std::size_t n = range_count::apply(exterior_ring(poly), add_for_open);
typename interior_return_type<Polygon const>::type
rings = interior_rings(poly);
for (typename detail::interior_iterator<Polygon const>::type
it = boost::begin(rings); it != boost::end(rings); ++it)
{
n += range_count::apply(*it, add_for_open);
}
return n;
}
};
struct multi_count
{
template <typename MultiGeometry>
static inline
std::size_t apply(MultiGeometry const& geometry, bool add_for_open)
{
typedef typename boost::range_value<MultiGeometry>::type geometry_type;
typedef typename boost::range_iterator
<
MultiGeometry const
>::type iterator_type;
std::size_t n = 0;
for (iterator_type it = boost::begin(geometry);
it != boost::end(geometry); ++it)
{
n += dispatch::num_segments
<
geometry_type
>::apply(*it, add_for_open);
}
return n;
}
};
}} // namespace detail::num_segments
#endif // DOXYGEN_NO_DETAIL
@ -141,20 +71,32 @@ struct multi_count
namespace dispatch
{
template <typename Geometry>
struct num_segments<Geometry, point_tag>
: detail::num_points::other_count<0>
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
struct num_segments
: not_implemented<Tag>
{};
template <typename Geometry>
struct num_segments<Geometry, point_tag>
: detail::counting::other_count<0>
{};
// the number of segments (1-dimensional faces) of the hypercube is
// given by the formula: d * 2^(d-1), where d is the dimension of the
// hypercube; see also:
// http://en.wikipedia.org/wiki/Hypercube
template <typename Geometry>
struct num_segments<Geometry, box_tag>
: detail::num_points::other_count<4>
: detail::counting::other_count
<
geometry::dimension<Geometry>::value
* (1 << (geometry::dimension<Geometry>::value - 1))
>
{};
template <typename Geometry>
struct num_segments<Geometry, segment_tag>
: detail::num_points::other_count<1>
: detail::counting::other_count<1>
{};
template <typename Geometry>
@ -169,22 +111,28 @@ struct num_segments<Geometry, ring_tag>
template <typename Geometry>
struct num_segments<Geometry, polygon_tag>
: detail::num_segments::polygon_count
: detail::counting::polygon_count<detail::num_segments::range_count>
{};
template <typename Geometry>
struct num_segments<Geometry, multi_point_tag>
: detail::num_points::other_count<0>
: detail::counting::other_count<0>
{};
template <typename Geometry>
struct num_segments<Geometry, multi_linestring_tag>
: detail::num_segments::multi_count
: detail::counting::multi_count
<
num_segments< typename boost::range_value<Geometry>::type>
>
{};
template <typename Geometry>
struct num_segments<Geometry, multi_polygon_tag>
: detail::num_segments::multi_count
: detail::counting::multi_count
<
num_segments< typename boost::range_value<Geometry>::type>
>
{};
@ -199,8 +147,14 @@ namespace resolve_variant
template <typename Geometry>
struct num_segments
: dispatch::num_segments<Geometry>
{};
{
static inline std::size_t apply(Geometry const& geometry)
{
concept::check<Geometry const>();
return dispatch::num_segments<Geometry>::apply(geometry);
}
};
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
@ -208,22 +162,17 @@ struct num_segments<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
struct visitor: boost::static_visitor<std::size_t>
{
bool m_add_for_open;
visitor(bool add_for_open): m_add_for_open(add_for_open) {}
template <typename Geometry>
typename std::size_t operator()(Geometry const& geometry) const
inline std::size_t operator()(Geometry const& geometry) const
{
return num_segments<Geometry>::apply(geometry, m_add_for_open);
return num_segments<Geometry>::apply(geometry);
}
};
static inline std::size_t
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
bool add_for_open)
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
{
return boost::apply_visitor(visitor(add_for_open), geometry);
return boost::apply_visitor(visitor(), geometry);
}
};
@ -238,21 +187,14 @@ struct num_segments<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
\details \details_calc{num_segments, number of segments}.
\tparam Geometry \tparam_geometry
\param geometry \param_geometry
\param add_for_open add one for open geometries (i.e. polygon types which are not closed)
\return \return_calc{number of segments}
\qbk{[include reference/algorithms/num_segments.qbk]}
*/
template <typename Geometry>
inline std::size_t num_segments(Geometry const& geometry,
bool add_for_open = false)
inline std::size_t num_segments(Geometry const& geometry)
{
concept::check<Geometry const>();
return resolve_variant::num_segments
<
Geometry
>::apply(geometry, add_for_open);
return resolve_variant::num_segments<Geometry>::apply(geometry);
}

View File

@ -179,68 +179,6 @@ struct union_insert
namespace detail { namespace union_
{
template
<
typename GeometryOut,
typename Geometry1, typename Geometry2,
typename RobustPolicy,
typename OutputIterator,
typename Strategy
>
inline OutputIterator insert(Geometry1 const& geometry1,
Geometry2 const& geometry2,
RobustPolicy const& robust_policy,
OutputIterator out,
Strategy const& strategy)
{
return dispatch::union_insert
<
Geometry1, Geometry2, GeometryOut
>::apply(geometry1, geometry2, robust_policy, out, strategy);
}
/*!
\brief_calc2{union} \brief_strategy
\ingroup union
\details \details_calc2{union_insert, spatial set theoretic union}
\brief_strategy. details_insert{union}
\tparam GeometryOut output geometry type, must be specified
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry
\tparam OutputIterator output iterator
\tparam Strategy \tparam_strategy_overlay
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\param out \param_out{union}
\param strategy \param_strategy{union}
\return \return_out
\qbk{distinguish,with strategy}
*/
template
<
typename GeometryOut,
typename Geometry1,
typename Geometry2,
typename OutputIterator,
typename Strategy
>
inline OutputIterator union_insert(Geometry1 const& geometry1,
Geometry2 const& geometry2,
OutputIterator out,
Strategy const& strategy)
{
concept::check<Geometry1 const>();
concept::check<Geometry2 const>();
concept::check<GeometryOut>();
typedef typename Strategy::rescale_policy_type rescale_policy_type;
rescale_policy_type robust_policy
= geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
return detail::union_::insert<GeometryOut>(geometry1, geometry2, robust_policy, out, strategy);
}
/*!
\brief_calc2{union}
\ingroup union
@ -285,7 +223,13 @@ inline OutputIterator union_insert(Geometry1 const& geometry1,
rescale_policy_type
> strategy;
return union_insert<GeometryOut>(geometry1, geometry2, out, strategy());
rescale_policy_type robust_policy
= geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
return dispatch::union_insert
<
Geometry1, Geometry2, GeometryOut
>::apply(geometry1, geometry2, robust_policy, out, strategy());
}

View File

@ -64,12 +64,11 @@ struct spatial_predicate
// ------------------------------------------------------------------ //
// TODO
// may be replaced by
// nearest_predicate<Geometry>
// Geometry geometry
// unsigned count
// + point_tag, path_tag
// CONSIDER: separated nearest<> and path<> may be replaced by
// nearest_predicate<Geometry, Tag>
// where Tag = point_tag | path_tag
// IMPROVEMENT: user-defined nearest predicate allowing to define
// all or only geometrical aspects of the search
template <typename PointOrRelation>
struct nearest

View File

@ -1,171 +0,0 @@
// Boost.Geometry Index
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_PUSHABLE_ARRAY_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_PUSHABLE_ARRAY_HPP
#include <boost/array.hpp>
#include <boost/geometry/index/detail/assert.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
template <typename Element, size_t Capacity>
class pushable_array
{
typedef typename boost::array<Element, Capacity> array_type;
public:
typedef typename array_type::value_type value_type;
typedef typename array_type::size_type size_type;
typedef typename array_type::iterator iterator;
typedef typename array_type::const_iterator const_iterator;
typedef typename array_type::reverse_iterator reverse_iterator;
typedef typename array_type::const_reverse_iterator const_reverse_iterator;
typedef typename array_type::reference reference;
typedef typename array_type::const_reference const_reference;
inline pushable_array()
: m_size(0)
{}
inline explicit pushable_array(size_type s)
: m_size(s)
{
BOOST_GEOMETRY_INDEX_ASSERT(s <= Capacity, "size too big");
}
inline void resize(size_type s)
{
BOOST_GEOMETRY_INDEX_ASSERT(s <= Capacity, "size too big");
m_size = s;
}
inline void reserve(size_type /*s*/)
{
//BOOST_GEOMETRY_INDEX_ASSERT(s <= Capacity, "size too big");
// do nothing
}
inline Element & operator[](size_type i)
{
BOOST_GEOMETRY_INDEX_ASSERT(i < m_size, "index of the element outside the container");
return m_array[i];
}
inline Element const& operator[](size_type i) const
{
BOOST_GEOMETRY_INDEX_ASSERT(i < m_size, "index of the element outside the container");
return m_array[i];
}
inline Element const& front() const
{
BOOST_GEOMETRY_INDEX_ASSERT(0 < m_size, "there are no elements in the container");
return m_array.front();
}
inline Element & front()
{
BOOST_GEOMETRY_INDEX_ASSERT(0 < m_size, "there are no elements in the container");
return m_array.front();
}
inline Element const& back() const
{
BOOST_GEOMETRY_INDEX_ASSERT(0 < m_size, "there are no elements in the container");
return *(begin() + (m_size - 1));
}
inline Element & back()
{
BOOST_GEOMETRY_INDEX_ASSERT(0 < m_size, "there are no elements in the container");
return *(begin() + (m_size - 1));
}
inline iterator begin()
{
return m_array.begin();
}
inline iterator end()
{
return m_array.begin() + m_size;
}
inline const_iterator begin() const
{
return m_array.begin();
}
inline const_iterator end() const
{
return m_array.begin() + m_size;
}
inline reverse_iterator rbegin()
{
return reverse_iterator(end());
}
inline reverse_iterator rend()
{
return reverse_iterator(begin());
}
inline const_reverse_iterator rbegin() const
{
return const_reverse_iterator(end());
}
inline const_reverse_iterator rend() const
{
return const_reverse_iterator(begin());
}
inline void clear()
{
m_size = 0;
}
inline void push_back(Element const& v)
{
BOOST_GEOMETRY_INDEX_ASSERT(m_size < Capacity, "can't further increase the size of the container");
m_array[m_size] = v;
++m_size;
}
inline void pop_back()
{
BOOST_GEOMETRY_INDEX_ASSERT(0 < m_size, "there are no elements in the container");
--m_size;
}
inline bool empty() const
{
return m_size == 0;
}
inline size_t size() const
{
return m_size;
}
inline size_t capacity() const
{
return Capacity;
}
private:
boost::array<Element, Capacity> m_array;
size_type m_size;
};
}}}} // namespace boost::geometry::index::detail
#endif // BOOST_GEOMETRY_INDEX_DETAIL_PUSHABLE_ARRAY_HPP

View File

@ -2,7 +2,7 @@
//
// R-tree distance (knn, path, etc. ) query visitor implementation
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@ -187,6 +187,33 @@ public:
rtree::apply_visitor(*this, *(it->second));
}
// ALTERNATIVE VERSION - use heap instead of sorted container
// It seems to be faster for greater MaxElements and slower otherwise
// CONSIDER: using one global container/heap for active branches
// instead of a sorted container per level
// This would also change the way how branches are traversed!
// The same may be applied to the iterative version which btw suffers
// from the copying of the whole containers on resize of the ABLs container
//// make a heap
//std::make_heap(active_branch_list.begin(), active_branch_list.end(), abl_greater);
//// recursively visit nodes
//while ( !active_branch_list.empty() )
//{
// //if current node is further than furthest neighbor, the rest of nodes also will be further
// if ( m_result.has_enough_neighbors()
// && is_node_prunable(m_result.greatest_comparable_distance(), active_branch_list.front().first) )
// {
// break;
// }
// rtree::apply_visitor(*this, *(active_branch_list.front().second));
// std::pop_heap(active_branch_list.begin(), active_branch_list.end(), abl_greater);
// active_branch_list.pop_back();
//}
}
inline void operator()(leaf const& n)
@ -226,6 +253,13 @@ private:
return p1.first < p2.first;
}
//static inline bool abl_greater(
// std::pair<node_distance_type, typename Allocators::node_pointer> const& p1,
// std::pair<node_distance_type, typename Allocators::node_pointer> const& p2)
//{
// return p1.first > p2.first;
//}
template <typename Distance>
static inline bool is_node_prunable(Distance const& greatest_dist, node_distance_type const& d)
{

View File

@ -303,7 +303,8 @@ public:
typedef typename rtree::elements_type<internal_node>::type elements_type;
elements_type const& elements = rtree::elements(n);
// change to elements_type::size_type or size_type?
// CONSIDER: change to elements_type::size_type or size_type
// or use fixed-size type like uint32 or even uint16?
size_t s = elements.size();
m_archive << boost::serialization::make_nvp("s", s);
@ -318,10 +319,11 @@ public:
inline void operator()(leaf const& l)
{
typedef typename rtree::elements_type<leaf>::type elements_type;
typedef typename elements_type::size_type elements_size;
//typedef typename elements_type::size_type elements_size;
elements_type const& elements = rtree::elements(l);
// change to elements_type::size_type or size_type?
// CONSIDER: change to elements_type::size_type or size_type
// or use fixed-size type like uint32 or even uint16?
size_t s = elements.size();
m_archive << boost::serialization::make_nvp("s", s);
@ -368,7 +370,12 @@ private:
{
//BOOST_GEOMETRY_INDEX_ASSERT(current_level <= leafs_level, "invalid parameter");
// change to elements_type::size_type or size_type?
typedef typename rtree::elements_type<internal_node>::type elements_type;
typedef typename elements_type::value_type element_type;
//typedef typename elements_type::size_type elements_size;
// CONSIDER: change to elements_type::size_type or size_type
// or use fixed-size type like uint32 or even uint16?
size_t elements_count;
ar >> boost::serialization::make_nvp("s", elements_count);
@ -381,9 +388,6 @@ private:
node_auto_ptr auto_remover(n, allocators);
internal_node & in = rtree::get<internal_node>(*n);
typedef typename rtree::elements_type<internal_node>::type elements_type;
typedef typename elements_type::value_type element_type;
typedef typename elements_type::size_type elements_size;
elements_type & elements = rtree::elements(in);
elements.reserve(elements_count); // MAY THROW (A)

View File

@ -1,6 +1,6 @@
// Boost.Container varray
//
// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2012-2014 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2013 Andrew Hundt.
//
// Use, modification and distribution is subject to the Boost Software License,
@ -1406,7 +1406,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
const_reverse_iterator rbegin() const { return reverse_iterator(this->end()); }
const_reverse_iterator rbegin() const { return const_reverse_iterator(this->end()); }
//! @brief Returns const reverse iterator to the first element of the reversed container.
//!
@ -1418,7 +1418,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
const_reverse_iterator crbegin() const { return reverse_iterator(this->end()); }
const_reverse_iterator crbegin() const { return const_reverse_iterator(this->end()); }
//! @brief Returns reverse iterator to the one after the last element of the reversed container.
//!
@ -1442,7 +1442,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
const_reverse_iterator rend() const { return reverse_iterator(this->begin()); }
const_reverse_iterator rend() const { return const_reverse_iterator(this->begin()); }
//! @brief Returns const reverse iterator to the one after the last element of the reversed container.
//!
@ -1454,7 +1454,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
const_reverse_iterator crend() const { return reverse_iterator(this->begin()); }
const_reverse_iterator crend() const { return const_reverse_iterator(this->begin()); }
//! @brief Returns container's capacity.
//!

View File

@ -20,7 +20,6 @@ namespace detail {
template <size_t MaxElements>
struct default_min_elements_s
{
// TODO - assert MaxElements <= (std::numeric_limits<size_t>::max)()/3
static const size_t raw_value = (MaxElements * 3) / 10;
static const size_t value = 1 <= raw_value ? raw_value : 1;
};
@ -34,7 +33,6 @@ inline size_t default_min_elements_d_calc(size_t max_elements, size_t min_elemen
{
if ( default_min_elements_d() == min_elements )
{
// TODO - assert MaxElements <= (std::numeric_limits<size_t>::max)()/3
size_t raw_value = (max_elements * 3) / 10;
return 1 <= raw_value ? raw_value : 1;
}
@ -45,7 +43,6 @@ inline size_t default_min_elements_d_calc(size_t max_elements, size_t min_elemen
template <size_t MaxElements>
struct default_rstar_reinserted_elements_s
{
// TODO - assert MaxElements <= (std::numeric_limits<size_t>::max)()/3
static const size_t value = (MaxElements * 3) / 10;
};
@ -58,7 +55,6 @@ inline size_t default_rstar_reinserted_elements_d_calc(size_t max_elements, size
{
if ( default_rstar_reinserted_elements_d() == reinserted_elements )
{
// TODO - assert MaxElements <= (std::numeric_limits<size_t>::max)()/3
return (max_elements * 3) / 10;
}

View File

@ -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
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@ -15,66 +20,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_POINTS_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_POINTS_HPP
#include <cstddef>
#include <boost/range.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace num_points
{
struct multi_count
{
template <typename MultiGeometry>
static inline
std::size_t apply(MultiGeometry const& geometry, bool add_for_open)
{
typedef typename boost::range_value<MultiGeometry>::type geometry_type;
typedef typename boost::range_iterator
<
MultiGeometry const
>::type iterator_type;
std::size_t n = 0;
for (iterator_type it = boost::begin(geometry);
it != boost::end(geometry);
++it)
{
n += dispatch::num_points<geometry_type>::apply(*it, add_for_open);
}
return n;
}
};
}} // namespace detail::num_points
#endif
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
template <typename Geometry>
struct num_points<Geometry, multi_tag>
: detail::num_points::multi_count {};
} // namespace dispatch
#endif
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_POINTS_HPP

View File

@ -44,6 +44,7 @@
#include <boost/geometry/algorithms/length.hpp>
#include <boost/geometry/algorithms/num_geometries.hpp>
#include <boost/geometry/algorithms/num_interior_rings.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
#include <boost/geometry/algorithms/perimeter.hpp>
#include <boost/geometry/algorithms/remove_spikes.hpp>
#include <boost/geometry/algorithms/reverse.hpp>
@ -52,8 +53,6 @@
#include <boost/geometry/algorithms/unique.hpp>
#include <boost/geometry/algorithms/within.hpp>
#include <boost/geometry/multi/algorithms/num_points.hpp>
#include <boost/geometry/algorithms/detail/point_on_border.hpp>
#include <boost/geometry/algorithms/detail/for_each_range.hpp>

View File

@ -8,6 +8,7 @@
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@ -22,10 +23,10 @@
#include <cmath>
#include <limits>
#include <boost/type_traits/is_fundamental.hpp>
#include <boost/math/constants/constants.hpp>
#include <boost/math/special_functions/round.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/type_traits/is_fundamental.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
@ -200,9 +201,10 @@ 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 bmp = boost::math::policies;
// ignore rounding errors for backward compatibility
typedef bmp::policy< bmp::rounding_error<bmp::ignore_error> > policy;
return boost::numeric_cast<Result>(boost::math::round(v, policy()));
}
};

View File

@ -1,7 +1,7 @@
// Boost.Geometry.Index varray
// Unit Test
// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2012-2014 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2012-2013 Andrew Hundt.
// Use, modification and distribution is subject to the Boost Software License,
@ -283,8 +283,15 @@ void test_iterators_nd()
s.assign(v.rbegin(), v.rend());
test_compare_ranges(s.begin(), s.end(), v.rbegin(), v.rend());
test_compare_ranges(s.rbegin(), s.rend(), v.begin(), v.end());
test_compare_ranges(s.cbegin(), s.cend(), v.rbegin(), v.rend());
test_compare_ranges(s.crbegin(), s.crend(), v.begin(), v.end());
varray<T, N> const& cs = s;
std::vector<T> const& cv = v;
s.assign(cv.rbegin(), cv.rend());
test_compare_ranges(cs.begin(), cs.end(), cv.rbegin(), cv.rend());
test_compare_ranges(cs.rbegin(), cs.rend(), cv.begin(), cv.end());
}
template <typename T, size_t N>

View File

@ -50,6 +50,8 @@ test-suite boost-geometry-algorithms
[ run is_valid.cpp : : : <toolset>msvc:<cxxflags>/bigobj ]
[ run length.cpp ]
[ run make.cpp ]
[ run num_geometries.cpp ]
[ run num_interior_rings.cpp ]
[ run num_points.cpp ]
[ run num_segments.cpp ]
[ run overlaps.cpp : : : <toolset>msvc:<cxxflags>/bigobj ]

View File

@ -80,6 +80,20 @@ static std::string const parcel3
static std::string const parcel3_bend // of parcel_3 - clipped
= "POLYGON((120399.40000152588 461986.43000030518, 120399.47999954224 461986.43000030518, 120403 461986.76769953477, 120403 461987.777217312, 120399.90000152588 461987.47999954224, 120399.72722010587 461990, 120398.71791817161 461990, 120398.93000030518 461986.90000152588, 120398.95000076294 461986.81999969482, 120398.9700012207 461986.74000167847, 120399.00999832153 461986.66999816895, 120399.04999923706 461986.61000061035, 120399.11000061035 461986.54999923706, 120399.16999816895 461986.5, 120399.25 461986.4700012207, 120399.31999969482 461986.43999862671, 120399.40000152588 461986.43000030518))";
// Ticket 10398, fails at next distances ( /10.0 ):
// #1: 5,25,84
// #2: 5,13,45,49,60,62,66,73
// #3: 4,8,12,35,45,54
// #4: 6,19,21,23,30,43,45,66,78,91
static std::string const ticket_10398_1
= "POLYGON((897866.5 6272518.7,897882.5 6272519.2,897882.6 6272519,897883.3 6272508.7,897883.5 6272505.5,897855 6272503.5,897852.4 6272505.6,897850.1 6272517.6,897860.8 6272518.5,897866.5 6272518.7))";
static std::string const ticket_10398_2
= "POLYGON((898882.3 6271337.3,898895.7 6271339.9,898898 6271328.3,898881.6 6271325.1,898879.3 6271336.7,898882.3 6271337.3))";
static std::string const ticket_10398_3
= "POLYGON((897558.7 6272055,897552.5 6272054.2,897552.5 6272053.7,897546.1 6272052.7,897545.6 6272057.7,897560.7 6272059.6,897560.9 6272055.3,897558.7 6272055))";
static std::string const ticket_10398_4
= "POLYGON((898563.3 6272366.9,898554.7 6272379.2,898559.7 6272382.3,898561.6 6272379.4,898568.7 6272369.1,898563.8 6272366.2,898563.3 6272366.9))";
template <typename P>
@ -309,6 +323,25 @@ void test_all()
test_one<polygon_type, polygon_type>("donut_simplex3", donut_simplex, join_round, end_flat, 19.8861, -0.3);
test_one<polygon_type, polygon_type>("donut_simplex6", donut_simplex, join_miter, end_flat, 12.8920, -0.6);
test_one<polygon_type, polygon_type>("donut_simplex6", donut_simplex, join_round, end_flat, 12.9157, -0.6);
#if defined(BOOST_GEOMETRY_BUFFER_INCLUDE_FAILING_TESTS)
// Areas yet to be changed
test_one<polygon_type, polygon_type>("ticket_10398_1_5", ticket_10398_1, join_miter, end_flat, 99, 0.5);
test_one<polygon_type, polygon_type>("ticket_10398_1_25", ticket_10398_1, join_miter, end_flat, 99, 2.5);
test_one<polygon_type, polygon_type>("ticket_10398_1_84", ticket_10398_1, join_miter, end_flat, 99, 8.4);
test_one<polygon_type, polygon_type>("ticket_10398_2_45", ticket_10398_2, join_miter, end_flat, 99, 4.5);
test_one<polygon_type, polygon_type>("ticket_10398_2_62", ticket_10398_2, join_miter, end_flat, 99, 6.2);
test_one<polygon_type, polygon_type>("ticket_10398_2_73", ticket_10398_2, join_miter, end_flat, 99, 7.3);
test_one<polygon_type, polygon_type>("ticket_10398_3_12", ticket_10398_3, join_miter, end_flat, 99, 1.2);
test_one<polygon_type, polygon_type>("ticket_10398_3_35", ticket_10398_3, join_miter, end_flat, 99, 3.5);
test_one<polygon_type, polygon_type>("ticket_10398_3_54", ticket_10398_3, join_miter, end_flat, 99, 5.4);
test_one<polygon_type, polygon_type>("ticket_10398_4_30", ticket_10398_4, join_miter, end_flat, 99, 3.0);
test_one<polygon_type, polygon_type>("ticket_10398_4_66", ticket_10398_4, join_miter, end_flat, 99, 6.6);
test_one<polygon_type, polygon_type>("ticket_10398_4_91", ticket_10398_4, join_miter, end_flat, 99, 9.1);
#endif
}

View File

@ -0,0 +1,151 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Unit Test
// Copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_TEST_MODULE
#define BOOST_TEST_MODULE test_num_geometries
#endif
#include <iostream>
#include <boost/test/included/unit_test.hpp>
#include <boost/variant/variant.hpp>
#include <boost/geometry/algorithms/num_geometries.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
#include <boost/geometry/io/dsv/write.hpp>
namespace bg = boost::geometry;
typedef bg::model::point<double, 2, bg::cs::cartesian> point;
typedef bg::model::linestring<point> linestring;
typedef bg::model::segment<point> segment;
typedef bg::model::box<point> box;
typedef bg::model::ring<point> ring;
typedef bg::model::polygon<point> polygon;
typedef bg::model::multi_point<point> multi_point;
typedef bg::model::multi_linestring<linestring> multi_linestring;
typedef bg::model::multi_polygon<polygon> multi_polygon;
template <typename Geometry>
struct test_num_geometries
{
static inline void apply(Geometry const& geometry,
std::size_t expected)
{
std::size_t detected = bg::num_geometries(geometry);
BOOST_CHECK_MESSAGE( detected == expected,
"Expected: " << expected
<< " detected: " << detected
<< " wkt: " << bg::wkt(geometry) );
}
static inline void apply(std::string const& wkt,
std::size_t expected)
{
Geometry geometry;
bg::read_wkt(wkt, geometry);
apply(geometry, expected);
}
};
BOOST_AUTO_TEST_CASE( test_point )
{
test_num_geometries<point>::apply("POINT(0 0)", 1);
}
BOOST_AUTO_TEST_CASE( test_segment )
{
test_num_geometries<segment>::apply("SEGMENT(0 0,1 1)", 1);
}
BOOST_AUTO_TEST_CASE( test_box )
{
test_num_geometries<box>::apply("BOX(0 0,1 1)", 1);
}
BOOST_AUTO_TEST_CASE( test_linestring )
{
test_num_geometries<linestring>::apply("LINESTRING(0 0,1 1,2 2)", 1);
}
BOOST_AUTO_TEST_CASE( test_multipoint )
{
typedef test_num_geometries<multi_point> tester;
tester::apply("MULTIPOINT()", 0);
tester::apply("MULTIPOINT(0 0)", 1);
tester::apply("MULTIPOINT(0 0,0 0)", 2);
tester::apply("MULTIPOINT(0 0,0 0,1 1)", 3);
}
BOOST_AUTO_TEST_CASE( test_multilinestring )
{
typedef test_num_geometries<multi_linestring> tester;
tester::apply("MULTILINESTRING()", 0);
tester::apply("MULTILINESTRING((0 0,1 0))", 1);
tester::apply("MULTILINESTRING((0 0,1 0,0 1),(0 0,1 0,0 1,0 0))", 2);
tester::apply("MULTILINESTRING((),(),(0 0,1 0))", 3);
}
BOOST_AUTO_TEST_CASE( test_ring )
{
test_num_geometries<ring>::apply("POLYGON((0 0,1 0,0 1,0 0))", 1);
}
BOOST_AUTO_TEST_CASE( test_polygon )
{
typedef test_num_geometries<polygon> tester;
tester::apply("POLYGON((0 0,10 0,0 10,0 0))", 1);
tester::apply("POLYGON((0 0,10 0,0 10,0 0),(1 1,2 1,1 1))", 1);
tester::apply("POLYGON((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,2 2,1 2,1 1),(5 5,6 5,6 6,5 6,5 5))", 1);
}
BOOST_AUTO_TEST_CASE( test_multipolygon )
{
typedef test_num_geometries<multi_polygon> tester;
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,1 2,1 1)))", 1);
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,2 2,1 2,1 1),(5 5,6 5,6 6,5 6,5 5)))", 1);
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,1 2,1 1)),((100 100,110 100,110 110,100 100),(101 101,102 101,102 102,101 101)))", 2);
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,2 2,1 2,1 1),(5 5,6 5,6 6,5 6,5 5)),((100 100,110 100,110 110,100 100),(101 101,102 101,102 102,101 101),(105 105,106 105,106 106,105 106,105 105)))", 2);
}
BOOST_AUTO_TEST_CASE( test_variant )
{
typedef boost::variant
<
linestring, multi_linestring
> variant_geometry_type;
typedef test_num_geometries<variant_geometry_type> tester;
linestring ls;
bg::read_wkt("LINESTRING(0 0,1 1,2 2)", ls);
multi_linestring mls;
bg::read_wkt("MULTILINESTRING((0 0,1 1,2 2),(3 3,4 4),(5 5,6 6,7 7,8 8))",
mls);
variant_geometry_type variant_geometry;
variant_geometry = ls;
tester::apply(variant_geometry, 1);
variant_geometry = mls;
tester::apply(variant_geometry, 3);
}

View File

@ -0,0 +1,153 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Unit Test
// Copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_TEST_MODULE
#define BOOST_TEST_MODULE test_num_interior_rings
#endif
#include <iostream>
#include <boost/test/included/unit_test.hpp>
#include <boost/variant/variant.hpp>
#include <boost/geometry/algorithms/num_interior_rings.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
#include <boost/geometry/io/dsv/write.hpp>
namespace bg = boost::geometry;
typedef bg::model::point<double, 2, bg::cs::cartesian> point;
typedef bg::model::linestring<point> linestring;
typedef bg::model::segment<point> segment;
typedef bg::model::box<point> box;
typedef bg::model::ring<point> ring;
typedef bg::model::polygon<point> polygon;
typedef bg::model::multi_point<point> multi_point;
typedef bg::model::multi_linestring<linestring> multi_linestring;
typedef bg::model::multi_polygon<polygon> multi_polygon;
template <typename Geometry>
struct test_num_interior_rings
{
static inline void apply(Geometry const& geometry,
std::size_t expected)
{
std::size_t detected = bg::num_interior_rings(geometry);
BOOST_CHECK_MESSAGE( detected == expected,
"Expected: " << expected
<< " detected: " << detected
<< " wkt: " << bg::wkt(geometry) );
}
static inline void apply(std::string const& wkt,
std::size_t expected)
{
Geometry geometry;
bg::read_wkt(wkt, geometry);
apply(geometry, expected);
}
};
BOOST_AUTO_TEST_CASE( test_point )
{
test_num_interior_rings<point>::apply("POINT(0 0)", 0);
}
BOOST_AUTO_TEST_CASE( test_segment )
{
test_num_interior_rings<segment>::apply("SEGMENT(0 0,1 1)", 0);
}
BOOST_AUTO_TEST_CASE( test_box )
{
test_num_interior_rings<box>::apply("BOX(0 0,1 1)", 0);
}
BOOST_AUTO_TEST_CASE( test_linestring )
{
test_num_interior_rings<linestring>::apply("LINESTRING(0 0,1 1)", 0);
}
BOOST_AUTO_TEST_CASE( test_multipoint )
{
test_num_interior_rings<multi_point>::apply("MULTIPOINT(0 0,1 1)", 0);
}
BOOST_AUTO_TEST_CASE( test_multilinestring )
{
test_num_interior_rings
<
multi_linestring
>::apply("MULTILINESTRING((0 0,1 0,0 1),(0 0,1 0,0 1,0 0))", 0);
}
BOOST_AUTO_TEST_CASE( test_ring )
{
typedef test_num_interior_rings<ring> tester;
tester::apply("POLYGON((0 0,1 0,0 1,0 0))", 0);
tester::apply("POLYGON((0 0,1 0,1 0,0 1,0 0))", 0);
}
BOOST_AUTO_TEST_CASE( test_polygon )
{
typedef test_num_interior_rings<polygon> tester;
tester::apply("POLYGON((0 0,10 0,0 10,0 0))", 0);
tester::apply("POLYGON((0 0,10 0,0 10,0 0),(1 1,2 1,1 2,1 1))", 1);
tester::apply("POLYGON((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,2 2,1 2,1 1),(5 5,6 5,6 6,5 6,5 5))", 2);
}
BOOST_AUTO_TEST_CASE( test_multipolygon )
{
typedef test_num_interior_rings<multi_polygon> tester;
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)))", 0);
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,1 2,1 1)))", 1);
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,2 2,1 2,1 1),(5 5,6 5,6 6,5 6,5 5)))", 2);
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,1 2,1 1)),((100 100,110 100,110 110,100 100),(101 101,102 101,102 102,101 101)))", 2);
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(1 1,2 1,2 2,1 2,1 1),(5 5,6 5,6 6,5 6,5 5)),((100 100,110 100,110 110,100 100),(101 101,102 101,102 102,101 101),(105 105,106 105,106 106,105 106,105 105)))", 4);
}
BOOST_AUTO_TEST_CASE( test_variant )
{
typedef boost::variant
<
linestring, polygon, multi_polygon
> variant_geometry_type;
typedef test_num_interior_rings<variant_geometry_type> tester;
linestring ls;
bg::read_wkt("LINESTRING(0 0,1 1,2 2)", ls);
polygon poly;
bg::read_wkt("POLYGON((0 0,0 10,10 10,10 0,0 0),(1 1,9 1,9 9,1 9,1 1))", poly);
multi_polygon mpoly;
bg::read_wkt("MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0),(1 1,2 1,1 2,1 1),(5 5,6 5,6 6,5 6,5 5)))", mpoly);
variant_geometry_type variant_geometry;
variant_geometry = ls;
tester::apply(variant_geometry, 0);
variant_geometry = poly;
tester::apply(variant_geometry, 1);
variant_geometry = mpoly;
tester::apply(variant_geometry, 2);
}

View File

@ -22,6 +22,15 @@
#include <boost/geometry/io/wkt/read.hpp>
#include <boost/geometry/multi/io/wkt/read.hpp>
template <std::size_t D, typename T = double>
struct box_dD
{
typedef boost::geometry::model::box
<
boost::geometry::model::point<T, D, boost::geometry::cs::cartesian>
> type;
};
template <typename Geometry>
inline void test_num_points(std::string const& wkt, std::size_t expected)
{
@ -51,6 +60,9 @@ int test_main(int, char* [])
test_num_points<linestring>("LINESTRING(0 0,1 1)", 2u);
test_num_points<segment>("LINESTRING(0 0,1 1)", 2u);
test_num_points<box>("POLYGON((0 0,10 10))", 4u);
test_num_points<box_dD<3>::type>("BOX(0 0 0,1 1 1)", 8u);
test_num_points<box_dD<4>::type>("BOX(0 0 0 0,1 1 1 1)", 16u);
test_num_points<box_dD<5>::type>("BOX(0 0 0 0 0,1 1 1 1 1)", 32u);
test_num_points<ring>("POLYGON((0 0,1 1,0 1,0 0))", 4u);
test_num_points<polygon>("POLYGON((0 0,10 10,0 10,0 0))", 4u);
test_num_points<polygon>("POLYGON((0 0,0 10,10 10,10 0,0 0),(4 4,6 4,6 6,4 6,4 4))", 10u);

View File

@ -18,15 +18,19 @@
#include <boost/variant/variant.hpp>
#include <boost/geometry/algorithms/num_segments.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
#include <boost/geometry/algorithms/num_segments.hpp>
#include <boost/geometry/io/dsv/write.hpp>
namespace bg = boost::geometry;
typedef bg::model::point<double,2,bg::cs::cartesian> point;
typedef bg::model::point<double, 2, bg::cs::cartesian> point;
typedef bg::model::linestring<point> linestring;
typedef bg::model::segment<point> segment;
typedef bg::model::box<point> box;
@ -45,47 +49,52 @@ typedef bg::model::multi_polygon<polygon_cw_open> multi_polygon_cw_open;
typedef bg::model::multi_polygon<polygon_ccw_closed> multi_polygon_ccw_closed;
typedef bg::model::multi_polygon<polygon_ccw_open> multi_polygon_ccw_open;
template <std::size_t D, typename T = double>
struct box_dD
{
typedef boost::geometry::model::box
<
boost::geometry::model::point<T, D, boost::geometry::cs::cartesian>
> type;
};
template <typename Geometry>
template <typename Geometry, typename Tag = typename bg::tag<Geometry>::type>
struct test_num_segments
{
static inline void apply(Geometry const& geometry,
std::size_t expected_closed,
std::size_t expected_open)
static inline void apply(Geometry const& geometry, std::size_t expected)
{
std::size_t detected = bg::num_segments(geometry);
BOOST_CHECK_MESSAGE( detected == expected_closed,
"Expected: " << expected_closed
BOOST_CHECK_MESSAGE( detected == expected,
"Expected: " << expected
<< " detected: " << detected
<< " wkt: " << bg::wkt(geometry) );
detected = bg::num_segments(geometry, true);
BOOST_CHECK_MESSAGE( detected == expected_open,
"Expected (add for open): " << expected_open
<< " detected (add for open): " << detected
<< " wkt: " << bg::wkt(geometry) );
}
static inline void apply(Geometry const& geometry,
std::size_t expected_closed)
{
apply(geometry, expected_closed, expected_closed);
}
static inline void apply(std::string const& wkt,
std::size_t expected_closed,
std::size_t expected_open)
static inline void apply(std::string const& wkt, std::size_t expected)
{
Geometry geometry;
bg::read_wkt(wkt, geometry);
apply(geometry, expected_closed, expected_open);
apply(geometry, expected);
}
};
template <typename Box>
struct test_num_segments<Box, bg::box_tag>
{
static inline void apply(Box const& box, std::size_t expected)
{
std::size_t detected = bg::num_segments(box);
BOOST_CHECK_MESSAGE( detected == expected,
"Expected: " << expected
<< " detected: " << detected
<< " dsv: " << bg::dsv(box) );
}
static inline void apply(std::string const& wkt,
std::size_t expected_closed)
static inline void apply(std::string const& wkt, std::size_t expected)
{
apply(wkt, expected_closed, expected_closed);
Box box;
bg::read_wkt(wkt, box);
apply(box, expected);
}
};
@ -102,6 +111,11 @@ BOOST_AUTO_TEST_CASE( test_segment )
BOOST_AUTO_TEST_CASE( test_box )
{
test_num_segments<box>::apply("BOX(0 0,1 1)", 4);
// test higher-dimensional boxes
test_num_segments<box_dD<3>::type>::apply("BOX(0 0 0,1 1 1)", 12);
test_num_segments<box_dD<4>::type>::apply("BOX(0 0 0 0,1 1 1 1)", 32);
test_num_segments<box_dD<5>::type>::apply("BOX(0 0 0 0 0,1 1 1 1 1)", 80);
}
BOOST_AUTO_TEST_CASE( test_linestring )
@ -144,9 +158,9 @@ void test_open_ring()
tester::apply("POLYGON(())", 0);
tester::apply("POLYGON((0 0))", 0);
tester::apply("POLYGON((0 0,1 0))", 1, 2);
tester::apply("POLYGON((0 0,1 0,0 1))", 2, 3);
tester::apply("POLYGON((0 0,0 0,1 0,0 1))", 3, 4);
tester::apply("POLYGON((0 0,1 0))", 2);
tester::apply("POLYGON((0 0,1 0,0 1))", 3);
tester::apply("POLYGON((0 0,0 0,1 0,0 1))", 4);
}
template <typename ClosedRing>
@ -177,16 +191,16 @@ void test_open_polygon()
tester::apply("POLYGON(())", 0);
tester::apply("POLYGON((0 0))", 0);
tester::apply("POLYGON((0 0,10 0),(0 0))", 1, 2);
tester::apply("POLYGON((0 0,10 0),(1 1,2 1))", 2, 4);
tester::apply("POLYGON((0 0,10 0,0 10))", 2, 3);
tester::apply("POLYGON((0 0,10 0,0 10),())", 2, 3);
tester::apply("POLYGON((0 0,10 0,0 10),(1 1))", 2, 3);
tester::apply("POLYGON((0 0,10 0,0 10),(1 1,2 1))", 3, 5);
tester::apply("POLYGON((0 0,10 0,0 10),(1 1,2 1,1 2))", 4, 6);
tester::apply("POLYGON((0 0,10 0,10 10,0 10),(1 1,2 1,1 2))", 5, 7);
tester::apply("POLYGON((0 0,10 0,10 10,0 10),(1 1,2 1,2 2,1 2))", 6, 8);
tester::apply("POLYGON((0 0,10 0,10 10,0 10),(1 1,2 1,2 2,1 2),(5 5,6 5,6 6,5 6))", 9, 12);
tester::apply("POLYGON((0 0,10 0),(0 0))", 2);
tester::apply("POLYGON((0 0,10 0),(1 1,2 1))", 4);
tester::apply("POLYGON((0 0,10 0,0 10))", 3);
tester::apply("POLYGON((0 0,10 0,0 10),())", 3);
tester::apply("POLYGON((0 0,10 0,0 10),(1 1))", 3);
tester::apply("POLYGON((0 0,10 0,0 10),(1 1,2 1))", 5);
tester::apply("POLYGON((0 0,10 0,0 10),(1 1,2 1,1 2))", 6);
tester::apply("POLYGON((0 0,10 0,10 10,0 10),(1 1,2 1,1 2))", 7);
tester::apply("POLYGON((0 0,10 0,10 10,0 10),(1 1,2 1,2 2,1 2))", 8);
tester::apply("POLYGON((0 0,10 0,10 10,0 10),(1 1,2 1,2 2,1 2),(5 5,6 5,6 6,5 6))", 12);
}
template <typename ClosedPolygon>
@ -221,10 +235,10 @@ void test_open_multipolygon()
{
typedef test_num_segments<OpenMultiPolygon> tester;
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10),(1 1,2 1,1 2)))", 5, 7);
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10),(1 1,2 1,2 2,1 2),(5 5,6 5,6 6,5 6)))", 9, 12);
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10),(1 1,2 1,1 2)),((100 100,110 100,110 110),(101 101,102 101,102 102)))", 9, 13);
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10),(1 1,2 1,2 2,1 2),(5 5,6 5,6 6,5 6)),((100 100,110 100,110 110),(101 101,102 101,102 102),(105 105,106 105,106 106,105 106)))", 16, 22);
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10),(1 1,2 1,1 2)))", 7);
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10),(1 1,2 1,2 2,1 2),(5 5,6 5,6 6,5 6)))", 12);
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10),(1 1,2 1,1 2)),((100 100,110 100,110 110),(101 101,102 101,102 102)))", 13);
tester::apply("MULTIPOLYGON(((0 0,10 0,10 10,0 10),(1 1,2 1,2 2,1 2),(5 5,6 5,6 6,5 6)),((100 100,110 100,110 110),(101 101,102 101,102 102),(105 105,106 105,106 106,105 106)))", 22);
}
template <typename ClosedMultiPolygon>
@ -270,7 +284,7 @@ BOOST_AUTO_TEST_CASE( test_variant )
tester::apply(variant_geometry, 2);
variant_geometry = p_open;
tester::apply(variant_geometry, 2, 3);
tester::apply(variant_geometry, 3);
variant_geometry = p_closed;
tester::apply(variant_geometry, 4);

View File

@ -9,7 +9,7 @@
# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
project boost-geometry-algorithms-overlay-robustness
project boost-geometry-robustness-overlay-areal_areal
:
requirements
<include>.

View File

@ -170,12 +170,10 @@ void test_all(std::string const& type, int seed, int count, p_q_settings setting
{
if (type == "float")
{
settings.tolerance = 1.0e-3;
test_type<float, Clockwise, Closed>(seed, count, settings);
}
else if (type == "double")
{
settings.tolerance = 1.0e-4;
test_type<double, Clockwise, Closed>(seed, count, settings);
}
#if defined(HAVE_TTMATH)

View File

@ -45,7 +45,7 @@ struct p_q_settings
: svg(false)
, also_difference(false)
, wkt(false)
, tolerance(1.0e-6)
, tolerance(1.0e-3) // since rescaling to integer the tolerance should be less. Was originally 1.0e-6
{}
};