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] ] [[Case] [Behavior] ]
[[__point__][[qbk_ret 1]]] [[__point__][[qbk_ret 1]]]
[[__segment__][[qbk_ret 2]]] [[__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)]]] [[__range__][[qbk_ret boost::size(geometry)]]]
[[__other__][[qbk_ret the sum of the number of points of its elements]]] [[__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]]] [[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] [heading Behavior]
[table [table
[[Case] [Behavior] ] [[Case] [Behavior] ]
[[__point__][[qbk_ret 0]]] [[__0dim__][[qbk_ret 0]]]
[[__segment__][[qbk_ret 1]]] [[__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]]] [[__range__][[qbk_ret boost::size(geometry) - 1]]]
[[__other__][[qbk_ret the sum of the number of segments of its elements]]] [[__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] [heading Examples]
[num_segments] [num_segments]
[num_segments_output] [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/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/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/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/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/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 * [@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; > 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); 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: " << 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; return 0;
} }
@ -39,8 +38,7 @@ int main()
/*` /*`
Output: Output:
[pre [pre
Number of segments: 6 Number of segments: 9
Number of segments (add_to_open <- true): 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/assert.hpp>
#include <boost/range.hpp> #include <boost/range.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/core/tag.hpp> #include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp> #include <boost/geometry/core/tags.hpp>
@ -92,6 +94,13 @@ private:
m_r_tree.query(index::nearest(query_geometry, 1), &t_v); m_r_tree.query(index::nearest(query_geometry, 1), &t_v);
BOOST_ASSERT( n > 0 ); 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 comparable_return_type cd = dispatch::distance
< <

View File

@ -11,6 +11,7 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_MULTIPOLYGON_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_MULTIPOLYGON_HPP
#include <deque> #include <deque>
#include <vector>
#include <boost/iterator/filter_iterator.hpp> #include <boost/iterator/filter_iterator.hpp>
#include <boost/range.hpp> #include <boost/range.hpp>
@ -22,9 +23,12 @@
#include <boost/geometry/util/range.hpp> #include <boost/geometry/util/range.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/algorithms/within.hpp> #include <boost/geometry/algorithms/within.hpp>
#include <boost/geometry/algorithms/detail/check_iterator_range.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/has_valid_self_turns.hpp>
#include <boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp> #include <boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp>
@ -71,6 +75,7 @@ private:
TurnIterator turns_first, TurnIterator turns_first,
TurnIterator turns_beyond) TurnIterator turns_beyond)
{ {
// collect all polygons that have turns
std::set<int> multi_indices; std::set<int> multi_indices;
for (TurnIterator tit = turns_first; tit != turns_beyond; ++tit) for (TurnIterator tit = turns_first; tit != turns_beyond; ++tit)
{ {
@ -78,28 +83,28 @@ private:
multi_indices.insert(tit->operations[0].other_id.multi_index); 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; int multi_index = 0;
for (PolygonIterator it1 = polygons_first; it1 != polygons_beyond; for (PolygonIterator it = polygons_first; it != polygons_beyond;
++it1, ++multi_index) ++it, ++multi_index)
{ {
if ( multi_indices.find(multi_index) != multi_indices.end() ) if ( multi_indices.find(multi_index) == multi_indices.end() )
{ {
continue; polygon_iterators.push_back(it);
}
for (PolygonIterator it2 = polygons_first;
it2 != polygons_beyond; ++it2)
{
if ( it1 != it2
&&
geometry::within(range::front(exterior_ring(*it1)), *it2)
)
{
return false;
}
} }
} }
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 <deque>
#include <iterator> #include <iterator>
#include <set> #include <set>
#include <vector>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/range.hpp> #include <boost/range.hpp>
@ -27,11 +28,18 @@
#include <boost/geometry/util/range.hpp> #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/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/num_interior_rings.hpp>
#include <boost/geometry/algorithms/within.hpp> #include <boost/geometry/algorithms/within.hpp>
#include <boost/geometry/algorithms/detail/check_iterator_range.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/complement_graph.hpp>
#include <boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.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 template
@ -162,24 +210,30 @@ protected:
ring_indices.insert(tit->operations[0].other_id.ring_index); 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; ring_index = 0;
for (RingIterator it1 = rings_first; it1 != rings_beyond; for (RingIterator it = rings_first; it != rings_beyond;
++it1, ++ring_index) ++it, ++ring_index)
{ {
// do not examine rings that are associated with turns
if ( ring_indices.find(ring_index) == ring_indices.end() ) if ( ring_indices.find(ring_index) == ring_indices.end() )
{ {
for (RingIterator it2 = rings_first; it2 != rings_beyond; ++it2) ring_iterators.push_back(it);
{
if ( it1 != it2
&& geometry::within(range::front(*it1), *it2) )
{
return false;
}
}
} }
} }
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 template

View File

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

View File

@ -652,10 +652,6 @@ struct get_turn_info_linear_areal
if ( ip_count == 0 ) if ( ip_count == 0 )
return false; 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 ) if ( !is_p_first && !is_p_last )
return false; return false;

View File

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

View File

@ -844,15 +844,16 @@ struct linear_areal
typedef typename boost::range_iterator<range2_type>::type range2_iterator; typedef typename boost::range_iterator<range2_type>::type range2_iterator;
range2_type range2(sub_range(geometry2, turn.operations[other_op_id].seg_id)); 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); 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 seg_count2 = s2 - 1;
std::size_t const p_seg_ij = turn.operations[op_id].seg_id.segment_index; 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; 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); point1_type const& pi = range::at(range1, p_seg_ij);
point2_type const& qi = range::at(range2, q_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) // Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // 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 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@ -27,6 +32,8 @@
#include <boost/geometry/geometries/concepts/check.hpp> #include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/algorithms/detail/counting.hpp>
namespace boost { namespace geometry namespace boost { namespace geometry
{ {
@ -53,12 +60,8 @@ struct num_geometries: not_implemented<Tag>
template <typename Geometry> template <typename Geometry>
struct num_geometries<Geometry, single_tag> struct num_geometries<Geometry, single_tag>
{ : detail::counting::other_count<1>
static inline std::size_t apply(Geometry const&) {};
{
return 1;
}
};
template <typename MultiGeometry> template <typename MultiGeometry>
@ -72,7 +75,43 @@ struct num_geometries<MultiGeometry, multi_tag>
} // namespace dispatch } // 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> template <typename Geometry>
inline std::size_t num_geometries(Geometry const& geometry) inline std::size_t num_geometries(Geometry const& geometry)
{ {
concept::check<Geometry const>(); return resolve_variant::num_geometries<Geometry>::apply(geometry);
return dispatch::num_geometries<Geometry>::apply(geometry);
} }

View File

@ -1,13 +1,14 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2014. // This file was modified by Oracle on 2014.
// Modifications copyright (c) 2014, Oracle and/or its affiliates. // 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 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 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@ -23,11 +24,19 @@
#include <boost/range.hpp> #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/tag.hpp>
#include <boost/geometry/core/tags.hpp> #include <boost/geometry/core/tags.hpp>
#include <boost/geometry/core/interior_rings.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 namespace boost { namespace geometry
{ {
@ -39,12 +48,8 @@ namespace dispatch
template <typename Geometry, typename Tag = typename tag<Geometry>::type> template <typename Geometry, typename Tag = typename tag<Geometry>::type>
struct num_interior_rings struct num_interior_rings
{ : detail::counting::other_count<0>
static inline std::size_t apply(Geometry const& ) {};
{
return 0;
}
};
@ -61,28 +66,54 @@ struct num_interior_rings<Polygon, polygon_tag>
template <typename MultiPolygon> template <typename MultiPolygon>
struct num_interior_rings<MultiPolygon, multi_polygon_tag> struct num_interior_rings<MultiPolygon, multi_polygon_tag>
{ : detail::counting::multi_count
static inline std::size_t apply(MultiPolygon const& multi_polygon) <
{ num_interior_rings
std::size_t n = 0; <
for (typename boost::range_iterator<MultiPolygon const>::type typename boost::range_value<MultiPolygon const>::type
it = boost::begin(multi_polygon); >
it != boost::end(multi_polygon); >
++it) {};
{
n += num_interior_rings
<
typename boost::range_value<MultiPolygon const>::type
>::apply(*it);
}
return n;
}
};
} // namespace dispatch } // 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> template <typename Geometry>
inline std::size_t num_interior_rings(Geometry const& 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) // Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland. // 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 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@ -17,20 +22,25 @@
#include <cstddef> #include <cstddef>
#include <boost/mpl/size_t.hpp>
#include <boost/range.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/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp> #include <boost/variant/apply_visitor.hpp>
#include <boost/variant/variant_fwd.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 namespace boost { namespace geometry
{ {
@ -47,55 +57,26 @@ namespace detail { namespace num_points
{ {
template <bool AddForOpen>
struct range_count struct range_count
{ {
template <typename Range> 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); 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) return n + 1;
{
if (geometry::disjoint(*boost::begin(range), *(boost::begin(range) + n - 1)))
{
return n + 1;
}
}
} }
return n; 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 }} // namespace detail::num_points
#endif // DOXYGEN_NO_DETAIL #endif // DOXYGEN_NO_DETAIL
@ -107,46 +88,62 @@ namespace dispatch
template template
< <
typename Geometry, 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> struct num_points: not_implemented<Tag>
{}; {};
template <typename Geometry> template <typename Geometry, bool AddForOpen>
struct num_points<Geometry, point_tag> struct num_points<Geometry, AddForOpen, point_tag>
: detail::num_points::other_count<1> : detail::counting::other_count<1>
{}; {};
template <typename Geometry> template <typename Geometry, bool AddForOpen>
struct num_points<Geometry, box_tag> struct num_points<Geometry, AddForOpen, box_tag>
: detail::num_points::other_count<4> : detail::counting::other_count<(1 << geometry::dimension<Geometry>::value)>
{}; {};
template <typename Geometry> template <typename Geometry, bool AddForOpen>
struct num_points<Geometry, segment_tag> struct num_points<Geometry, AddForOpen, segment_tag>
: detail::num_points::other_count<2> : detail::counting::other_count<2>
{}; {};
template <typename Geometry> template <typename Geometry, bool AddForOpen>
struct num_points<Geometry, linestring_tag> struct num_points<Geometry, AddForOpen, linestring_tag>
: detail::num_points::range_count : detail::num_points::range_count<AddForOpen>
{}; {};
template <typename Geometry> template <typename Geometry, bool AddForOpen>
struct num_points<Geometry, ring_tag> struct num_points<Geometry, AddForOpen, ring_tag>
: detail::num_points::range_count : detail::num_points::range_count<AddForOpen>
{}; {};
template <typename Geometry> template <typename Geometry, bool AddForOpen>
struct num_points<Geometry, polygon_tag> struct num_points<Geometry, AddForOpen, polygon_tag>
: detail::num_points::polygon_count : 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 } // namespace dispatch
#endif #endif
namespace resolve_variant { namespace resolve_variant
{
template <typename Geometry> template <typename Geometry>
struct num_points struct num_points
@ -154,7 +151,11 @@ struct num_points
static inline std::size_t apply(Geometry const& geometry, static inline std::size_t apply(Geometry const& geometry,
bool add_for_open) 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) {} visitor(bool add_for_open): m_add_for_open(add_for_open) {}
template <typename Geometry> 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); 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> template <typename Geometry>
inline std::size_t num_points(Geometry const& geometry, bool add_for_open = false) 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); return resolve_variant::num_points<Geometry>::apply(geometry, add_for_open);
} }

View File

@ -12,6 +12,9 @@
#include <cstddef> #include <cstddef>
#include <boost/mpl/size_t.hpp>
#include <boost/mpl/times.hpp>
#include <boost/range.hpp> #include <boost/range.hpp>
#include <boost/variant/static_visitor.hpp> #include <boost/variant/static_visitor.hpp>
@ -19,9 +22,6 @@
#include <boost/variant/variant_fwd.hpp> #include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/core/closure.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/tag.hpp>
#include <boost/geometry/core/tags.hpp> #include <boost/geometry/core/tags.hpp>
@ -29,35 +29,14 @@
#include <boost/geometry/geometries/concepts/check.hpp> #include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
#include <boost/geometry/algorithms/disjoint.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp> #include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
#include <boost/geometry/algorithms/detail/counting.hpp>
namespace boost { namespace geometry 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 #ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace num_segments namespace detail { namespace num_segments
{ {
@ -66,72 +45,23 @@ namespace detail { namespace num_segments
struct range_count struct range_count
{ {
template <typename Range> 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); std::size_t n = boost::size(range);
if ( n <= 1 ) if ( n <= 1 )
{ {
return 0; return 0;
} }
if (add_for_open
&& geometry::closure<Range>::value == open return
&& geometry::disjoint(range::front(range), range::at(range, n - 1)) geometry::closure<Range>::value == open
) ?
{ n
return n; :
} static_cast<std::size_t>(n - 1);
return static_cast<std::size_t>(n - 1);
} }
}; };
struct polygon_count
: private range_count
{
template <typename Polygon>
static inline std::size_t apply(Polygon const& poly, bool add_for_open)
{
std::size_t n = range_count::apply(exterior_ring(poly), add_for_open);
typename interior_return_type<Polygon const>::type
rings = interior_rings(poly);
for (typename detail::interior_iterator<Polygon const>::type
it = boost::begin(rings); it != boost::end(rings); ++it)
{
n += range_count::apply(*it, add_for_open);
}
return n;
}
};
struct multi_count
{
template <typename MultiGeometry>
static inline
std::size_t apply(MultiGeometry const& geometry, bool add_for_open)
{
typedef typename boost::range_value<MultiGeometry>::type geometry_type;
typedef typename boost::range_iterator
<
MultiGeometry const
>::type iterator_type;
std::size_t n = 0;
for (iterator_type it = boost::begin(geometry);
it != boost::end(geometry); ++it)
{
n += dispatch::num_segments
<
geometry_type
>::apply(*it, add_for_open);
}
return n;
}
};
}} // namespace detail::num_segments }} // namespace detail::num_segments
#endif // DOXYGEN_NO_DETAIL #endif // DOXYGEN_NO_DETAIL
@ -141,20 +71,32 @@ struct multi_count
namespace dispatch namespace dispatch
{ {
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
template <typename Geometry> struct num_segments
struct num_segments<Geometry, point_tag> : not_implemented<Tag>
: detail::num_points::other_count<0>
{}; {};
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> template <typename Geometry>
struct num_segments<Geometry, box_tag> 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> template <typename Geometry>
struct num_segments<Geometry, segment_tag> struct num_segments<Geometry, segment_tag>
: detail::num_points::other_count<1> : detail::counting::other_count<1>
{}; {};
template <typename Geometry> template <typename Geometry>
@ -169,22 +111,28 @@ struct num_segments<Geometry, ring_tag>
template <typename Geometry> template <typename Geometry>
struct num_segments<Geometry, polygon_tag> struct num_segments<Geometry, polygon_tag>
: detail::num_segments::polygon_count : detail::counting::polygon_count<detail::num_segments::range_count>
{}; {};
template <typename Geometry> template <typename Geometry>
struct num_segments<Geometry, multi_point_tag> struct num_segments<Geometry, multi_point_tag>
: detail::num_points::other_count<0> : detail::counting::other_count<0>
{}; {};
template <typename Geometry> template <typename Geometry>
struct num_segments<Geometry, multi_linestring_tag> 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> template <typename Geometry>
struct num_segments<Geometry, multi_polygon_tag> 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> template <typename Geometry>
struct num_segments 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)> 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> 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> 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 static inline std::size_t
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry, apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
bool add_for_open)
{ {
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}. \details \details_calc{num_segments, number of segments}.
\tparam Geometry \tparam_geometry \tparam Geometry \tparam_geometry
\param geometry \param_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} \return \return_calc{number of segments}
\qbk{[include reference/algorithms/num_segments.qbk]} \qbk{[include reference/algorithms/num_segments.qbk]}
*/ */
template <typename Geometry> template <typename Geometry>
inline std::size_t num_segments(Geometry const& geometry, inline std::size_t num_segments(Geometry const& geometry)
bool add_for_open = false)
{ {
concept::check<Geometry const>(); return resolve_variant::num_segments<Geometry>::apply(geometry);
return resolve_variant::num_segments
<
Geometry
>::apply(geometry, add_for_open);
} }

View File

@ -179,68 +179,6 @@ struct union_insert
namespace detail { namespace union_ 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} \brief_calc2{union}
\ingroup union \ingroup union
@ -285,7 +223,13 @@ inline OutputIterator union_insert(Geometry1 const& geometry1,
rescale_policy_type rescale_policy_type
> strategy; > 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 // CONSIDER: separated nearest<> and path<> may be replaced by
// may be replaced by // nearest_predicate<Geometry, Tag>
// nearest_predicate<Geometry> // where Tag = point_tag | path_tag
// Geometry geometry // IMPROVEMENT: user-defined nearest predicate allowing to define
// unsigned count // all or only geometrical aspects of the search
// + point_tag, path_tag
template <typename PointOrRelation> template <typename PointOrRelation>
struct nearest 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 // 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, // Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@ -187,6 +187,33 @@ public:
rtree::apply_visitor(*this, *(it->second)); 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) inline void operator()(leaf const& n)
@ -226,6 +253,13 @@ private:
return p1.first < p2.first; 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> template <typename Distance>
static inline bool is_node_prunable(Distance const& greatest_dist, node_distance_type const& d) 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; typedef typename rtree::elements_type<internal_node>::type elements_type;
elements_type const& elements = rtree::elements(n); 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(); size_t s = elements.size();
m_archive << boost::serialization::make_nvp("s", s); m_archive << boost::serialization::make_nvp("s", s);
@ -318,10 +319,11 @@ public:
inline void operator()(leaf const& l) inline void operator()(leaf const& l)
{ {
typedef typename rtree::elements_type<leaf>::type elements_type; 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); 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(); size_t s = elements.size();
m_archive << boost::serialization::make_nvp("s", s); m_archive << boost::serialization::make_nvp("s", s);
@ -368,7 +370,12 @@ private:
{ {
//BOOST_GEOMETRY_INDEX_ASSERT(current_level <= leafs_level, "invalid parameter"); //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; size_t elements_count;
ar >> boost::serialization::make_nvp("s", elements_count); ar >> boost::serialization::make_nvp("s", elements_count);
@ -381,9 +388,6 @@ private:
node_auto_ptr auto_remover(n, allocators); node_auto_ptr auto_remover(n, allocators);
internal_node & in = rtree::get<internal_node>(*n); 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_type & elements = rtree::elements(in);
elements.reserve(elements_count); // MAY THROW (A) elements.reserve(elements_count); // MAY THROW (A)

View File

@ -1,6 +1,6 @@
// Boost.Container varray // 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. // Copyright (c) 2011-2013 Andrew Hundt.
// //
// Use, modification and distribution is subject to the Boost Software License, // Use, modification and distribution is subject to the Boost Software License,
@ -1406,7 +1406,7 @@ public:
//! //!
//! @par Complexity //! @par Complexity
//! Constant O(1). //! 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. //! @brief Returns const reverse iterator to the first element of the reversed container.
//! //!
@ -1418,7 +1418,7 @@ public:
//! //!
//! @par Complexity //! @par Complexity
//! Constant O(1). //! 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. //! @brief Returns reverse iterator to the one after the last element of the reversed container.
//! //!
@ -1442,7 +1442,7 @@ public:
//! //!
//! @par Complexity //! @par Complexity
//! Constant O(1). //! 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. //! @brief Returns const reverse iterator to the one after the last element of the reversed container.
//! //!
@ -1454,7 +1454,7 @@ public:
//! //!
//! @par Complexity //! @par Complexity
//! Constant O(1). //! 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. //! @brief Returns container's capacity.
//! //!

View File

@ -20,7 +20,6 @@ namespace detail {
template <size_t MaxElements> template <size_t MaxElements>
struct default_min_elements_s 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 raw_value = (MaxElements * 3) / 10;
static const size_t value = 1 <= raw_value ? raw_value : 1; 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 ) 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; size_t raw_value = (max_elements * 3) / 10;
return 1 <= raw_value ? raw_value : 1; 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> template <size_t MaxElements>
struct default_rstar_reinserted_elements_s struct default_rstar_reinserted_elements_s
{ {
// TODO - assert MaxElements <= (std::numeric_limits<size_t>::max)()/3
static const size_t value = (MaxElements * 3) / 10; 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 ) if ( default_rstar_reinserted_elements_d() == reinserted_elements )
{ {
// TODO - assert MaxElements <= (std::numeric_limits<size_t>::max)()/3
return (max_elements * 3) / 10; return (max_elements * 3) / 10;
} }

View File

@ -1,8 +1,13 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // 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 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@ -15,66 +20,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_POINTS_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_POINTS_HPP
#define 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> #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 #endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_POINTS_HPP

View File

@ -44,6 +44,7 @@
#include <boost/geometry/algorithms/length.hpp> #include <boost/geometry/algorithms/length.hpp>
#include <boost/geometry/algorithms/num_geometries.hpp> #include <boost/geometry/algorithms/num_geometries.hpp>
#include <boost/geometry/algorithms/num_interior_rings.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/perimeter.hpp>
#include <boost/geometry/algorithms/remove_spikes.hpp> #include <boost/geometry/algorithms/remove_spikes.hpp>
#include <boost/geometry/algorithms/reverse.hpp> #include <boost/geometry/algorithms/reverse.hpp>
@ -52,8 +53,6 @@
#include <boost/geometry/algorithms/unique.hpp> #include <boost/geometry/algorithms/unique.hpp>
#include <boost/geometry/algorithms/within.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/point_on_border.hpp>
#include <boost/geometry/algorithms/detail/for_each_range.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. // 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 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 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@ -22,10 +23,10 @@
#include <cmath> #include <cmath>
#include <limits> #include <limits>
#include <boost/type_traits/is_fundamental.hpp>
#include <boost/math/constants/constants.hpp> #include <boost/math/constants/constants.hpp>
#include <boost/math/special_functions/round.hpp>
#include <boost/numeric/conversion/cast.hpp> #include <boost/numeric/conversion/cast.hpp>
#include <boost/type_traits/is_fundamental.hpp>
#include <boost/geometry/util/select_most_precise.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) static inline Result apply(Source const& v)
{ {
return v < 0 namespace bmp = boost::math::policies;
? boost::numeric_cast<Result>(ceil(v - 0.5f)) // ignore rounding errors for backward compatibility
: boost::numeric_cast<Result>(floor(v + 0.5f)); 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 // Boost.Geometry.Index varray
// Unit Test // Unit Test
// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland. // Copyright (c) 2012-2014 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2012-2013 Andrew Hundt. // Copyright (c) 2012-2013 Andrew Hundt.
// Use, modification and distribution is subject to the Boost Software License, // 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()); s.assign(v.rbegin(), v.rend());
test_compare_ranges(s.begin(), s.end(), v.rbegin(), v.rend()); test_compare_ranges(s.cbegin(), s.cend(), v.rbegin(), v.rend());
test_compare_ranges(s.rbegin(), s.rend(), v.begin(), v.end()); 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> 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 is_valid.cpp : : : <toolset>msvc:<cxxflags>/bigobj ]
[ run length.cpp ] [ run length.cpp ]
[ run make.cpp ] [ run make.cpp ]
[ run num_geometries.cpp ]
[ run num_interior_rings.cpp ]
[ run num_points.cpp ] [ run num_points.cpp ]
[ run num_segments.cpp ] [ run num_segments.cpp ]
[ run overlaps.cpp : : : <toolset>msvc:<cxxflags>/bigobj ] [ 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 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))"; = "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> 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_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_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); 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/io/wkt/read.hpp>
#include <boost/geometry/multi/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> template <typename Geometry>
inline void test_num_points(std::string const& wkt, std::size_t expected) 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<linestring>("LINESTRING(0 0,1 1)", 2u);
test_num_points<segment>("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>("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<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,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); 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/variant/variant.hpp>
#include <boost/geometry/algorithms/num_segments.hpp>
#include <boost/geometry/core/closure.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/geometries/geometries.hpp>
#include <boost/geometry/io/wkt/wkt.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; 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::linestring<point> linestring;
typedef bg::model::segment<point> segment; typedef bg::model::segment<point> segment;
typedef bg::model::box<point> box; 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_closed> multi_polygon_ccw_closed;
typedef bg::model::multi_polygon<polygon_ccw_open> multi_polygon_ccw_open; 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 struct test_num_segments
{ {
static inline void apply(Geometry const& geometry, static inline void apply(Geometry const& geometry, std::size_t expected)
std::size_t expected_closed,
std::size_t expected_open)
{ {
std::size_t detected = bg::num_segments(geometry); std::size_t detected = bg::num_segments(geometry);
BOOST_CHECK_MESSAGE( detected == expected_closed, BOOST_CHECK_MESSAGE( detected == expected,
"Expected: " << expected_closed "Expected: " << expected
<< " detected: " << detected << " detected: " << detected
<< " wkt: " << bg::wkt(geometry) ); << " 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, static inline void apply(std::string const& wkt, std::size_t expected)
std::size_t expected_closed)
{
apply(geometry, expected_closed, expected_closed);
}
static inline void apply(std::string const& wkt,
std::size_t expected_closed,
std::size_t expected_open)
{ {
Geometry geometry; Geometry geometry;
bg::read_wkt(wkt, 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, static inline void apply(std::string const& wkt, std::size_t expected)
std::size_t expected_closed)
{ {
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 ) BOOST_AUTO_TEST_CASE( test_box )
{ {
test_num_segments<box>::apply("BOX(0 0,1 1)", 4); 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 ) BOOST_AUTO_TEST_CASE( test_linestring )
@ -144,9 +158,9 @@ void test_open_ring()
tester::apply("POLYGON(())", 0); tester::apply("POLYGON(())", 0);
tester::apply("POLYGON((0 0))", 0); tester::apply("POLYGON((0 0))", 0);
tester::apply("POLYGON((0 0,1 0))", 1, 2); tester::apply("POLYGON((0 0,1 0))", 2);
tester::apply("POLYGON((0 0,1 0,0 1))", 2, 3); tester::apply("POLYGON((0 0,1 0,0 1))", 3);
tester::apply("POLYGON((0 0,0 0,1 0,0 1))", 3, 4); tester::apply("POLYGON((0 0,0 0,1 0,0 1))", 4);
} }
template <typename ClosedRing> template <typename ClosedRing>
@ -177,16 +191,16 @@ void test_open_polygon()
tester::apply("POLYGON(())", 0); tester::apply("POLYGON(())", 0);
tester::apply("POLYGON((0 0))", 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),(0 0))", 2);
tester::apply("POLYGON((0 0,10 0),(1 1,2 1))", 2, 4); tester::apply("POLYGON((0 0,10 0),(1 1,2 1))", 4);
tester::apply("POLYGON((0 0,10 0,0 10))", 2, 3); tester::apply("POLYGON((0 0,10 0,0 10))", 3);
tester::apply("POLYGON((0 0,10 0,0 10),())", 2, 3); tester::apply("POLYGON((0 0,10 0,0 10),())", 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))", 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))", 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,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))", 5, 7); 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))", 6, 8); 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))", 9, 12); 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> template <typename ClosedPolygon>
@ -221,10 +235,10 @@ void test_open_multipolygon()
{ {
typedef test_num_segments<OpenMultiPolygon> tester; 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,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)))", 9, 12); 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)))", 9, 13); 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)))", 16, 22); 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> template <typename ClosedMultiPolygon>
@ -270,7 +284,7 @@ BOOST_AUTO_TEST_CASE( test_variant )
tester::apply(variant_geometry, 2); tester::apply(variant_geometry, 2);
variant_geometry = p_open; variant_geometry = p_open;
tester::apply(variant_geometry, 2, 3); tester::apply(variant_geometry, 3);
variant_geometry = p_closed; variant_geometry = p_closed;
tester::apply(variant_geometry, 4); tester::apply(variant_geometry, 4);

View File

@ -9,7 +9,7 @@
# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at # Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt) # http://www.boost.org/LICENSE_1_0.txt)
project boost-geometry-algorithms-overlay-robustness project boost-geometry-robustness-overlay-areal_areal
: :
requirements requirements
<include>. <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") if (type == "float")
{ {
settings.tolerance = 1.0e-3;
test_type<float, Clockwise, Closed>(seed, count, settings); test_type<float, Clockwise, Closed>(seed, count, settings);
} }
else if (type == "double") else if (type == "double")
{ {
settings.tolerance = 1.0e-4;
test_type<double, Clockwise, Closed>(seed, count, settings); test_type<double, Clockwise, Closed>(seed, count, settings);
} }
#if defined(HAVE_TTMATH) #if defined(HAVE_TTMATH)

View File

@ -45,7 +45,7 @@ struct p_q_settings
: svg(false) : svg(false)
, also_difference(false) , also_difference(false)
, wkt(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
{} {}
}; };