Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r78712 - in branches/release: boost/geometry boost/geometry/algorithms boost/geometry/algorithms/detail boost/geometry/algorithms/detail/overlay boost/geometry/algorithms/detail/sections boost/geometry/arithmetic boost/geometry/core boost/geometry/geometries boost/geometry/io boost/geometry/io/dsv boost/geometry/iterators boost/geometry/multi boost/geometry/multi/algorithms/detail boost/geometry/multi/algorithms/detail/overlay boost/geometry/multi/algorithms/detail/sections boost/geometry/multi/io/wkt boost/geometry/policies boost/geometry/policies/relate boost/geometry/strategies boost/geometry/strategies/cartesian boost/geometry/util boost/geometry/views libs/geometry/doc libs/geometry/doc/concept libs/geometry/doc/doxy libs/geometry/doc/generated libs/geometry/doc/html libs/geometry/doc/reference libs/geometry/doc/reference/algorithms libs/geometry/doc/src libs/geometry/example libs/geometry/test libs/geometry/test/algorithms libs/geometry/test/algorithms/overlay libs/geometry/test/algorithms/overlay/robustness libs/geometry/test/core libs/geometry/test/geometries libs/geometry/test/multi libs/geometry/test/multi/algorithms libs/geometry/test/multi/algorithms/overlay libs/geometry/test/multi/io/wkt libs/geometry/test/robustness/common libs/geometry/test/robustness/convex_hull libs/geometry/test/robustness/overlay libs/geometry/test/robustness/overlay/buffer libs/geometry/test/robustness/overlay/linear_areal libs/geometry/test/strategies libs/geometry/test/views
From: barend.gehrels_at_[hidden]
Date: 2012-05-28 07:29:24


Author: barendgehrels
Date: 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
New Revision: 78712
URL: http://svn.boost.org/trac/boost/changeset/78712

Log:
[geometry] merged since r77001
Added:
   branches/release/boost/geometry/algorithms/detail/get_left_turns.hpp
      - copied unchanged from r78710, /trunk/boost/geometry/algorithms/detail/get_left_turns.hpp
   branches/release/boost/geometry/algorithms/detail/occupation_info.hpp
      - copied, changed from r77247, /trunk/boost/geometry/algorithms/detail/occupation_info.hpp
   branches/release/boost/geometry/algorithms/touches.hpp
      - copied unchanged from r78710, /trunk/boost/geometry/algorithms/touches.hpp
   branches/release/libs/geometry/doc/reference/algorithms/touches.qbk
      - copied unchanged from r78710, /trunk/libs/geometry/doc/reference/algorithms/touches.qbk
   branches/release/libs/geometry/test/algorithms/test_touches.hpp
      - copied unchanged from r78710, /trunk/libs/geometry/test/algorithms/test_touches.hpp
   branches/release/libs/geometry/test/algorithms/touches.cpp
      - copied unchanged from r78710, /trunk/libs/geometry/test/algorithms/touches.cpp
   branches/release/libs/geometry/test/algorithms/touches.vcproj
      - copied unchanged from r78710, /trunk/libs/geometry/test/algorithms/touches.vcproj
   branches/release/libs/geometry/test/multi/algorithms/multi_disjoint.cpp
      - copied unchanged from r78710, /trunk/libs/geometry/test/multi/algorithms/multi_disjoint.cpp
   branches/release/libs/geometry/test/multi/algorithms/multi_disjoint.vcproj
      - copied unchanged from r78710, /trunk/libs/geometry/test/multi/algorithms/multi_disjoint.vcproj
   branches/release/libs/geometry/test/multi/algorithms/multi_touches.cpp
      - copied unchanged from r78710, /trunk/libs/geometry/test/multi/algorithms/multi_touches.cpp
   branches/release/libs/geometry/test/multi/algorithms/multi_touches.vcproj
      - copied unchanged from r78710, /trunk/libs/geometry/test/multi/algorithms/multi_touches.vcproj
   branches/release/libs/geometry/test/robustness/common/
      - copied from r77181, /trunk/libs/geometry/test/robustness/common/
   branches/release/libs/geometry/test/robustness/common/common_settings.hpp
      - copied unchanged from r77181, /trunk/libs/geometry/test/robustness/common/common_settings.hpp
   branches/release/libs/geometry/test/robustness/common/make_square_polygon.hpp
      - copied unchanged from r77181, /trunk/libs/geometry/test/robustness/common/make_square_polygon.hpp
   branches/release/libs/geometry/test/robustness/convex_hull/Jamfile.v2
      - copied unchanged from r77181, /trunk/libs/geometry/test/robustness/convex_hull/Jamfile.v2
   branches/release/libs/geometry/test/robustness/overlay/
      - copied from r77181, /trunk/libs/geometry/test/robustness/overlay/
   branches/release/libs/geometry/test/robustness/overlay/buffer/
      - copied from r77319, /trunk/libs/geometry/test/robustness/overlay/buffer/
   branches/release/libs/geometry/test/robustness/overlay/buffer/Jamfile.v2
      - copied unchanged from r77319, /trunk/libs/geometry/test/robustness/overlay/buffer/Jamfile.v2
   branches/release/libs/geometry/test/robustness/overlay/buffer/recursive_polygons_buffer.cpp
      - copied unchanged from r77319, /trunk/libs/geometry/test/robustness/overlay/buffer/recursive_polygons_buffer.cpp
   branches/release/libs/geometry/test/robustness/overlay/buffer/recursive_polygons_buffer.sln
      - copied unchanged from r77319, /trunk/libs/geometry/test/robustness/overlay/buffer/recursive_polygons_buffer.sln
   branches/release/libs/geometry/test/robustness/overlay/buffer/recursive_polygons_buffer.vcproj
      - copied unchanged from r77319, /trunk/libs/geometry/test/robustness/overlay/buffer/recursive_polygons_buffer.vcproj
   branches/release/libs/geometry/test/robustness/overlay/linear_areal/
      - copied from r77181, /trunk/libs/geometry/test/robustness/overlay/linear_areal/
   branches/release/libs/geometry/test/robustness/overlay/linear_areal/Jamfile.v2
      - copied unchanged from r77181, /trunk/libs/geometry/test/robustness/overlay/linear_areal/Jamfile.v2
   branches/release/libs/geometry/test/robustness/overlay/linear_areal/recursive_polygons_linear_areal.cpp
      - copied unchanged from r77181, /trunk/libs/geometry/test/robustness/overlay/linear_areal/recursive_polygons_linear_areal.cpp
   branches/release/libs/geometry/test/robustness/overlay/linear_areal/recursive_polygons_linear_areal.sln
      - copied unchanged from r77181, /trunk/libs/geometry/test/robustness/overlay/linear_areal/recursive_polygons_linear_areal.sln
   branches/release/libs/geometry/test/robustness/overlay/linear_areal/recursive_polygons_linear_areal.vcproj
      - copied unchanged from r77181, /trunk/libs/geometry/test/robustness/overlay/linear_areal/recursive_polygons_linear_areal.vcproj
   branches/release/libs/geometry/test/strategies/transform_cs.cpp
      - copied unchanged from r77181, /trunk/libs/geometry/test/strategies/transform_cs.cpp
   branches/release/libs/geometry/test/strategies/transform_cs.vcproj
      - copied unchanged from r77181, /trunk/libs/geometry/test/strategies/transform_cs.vcproj
Properties modified:
   branches/release/boost/geometry/algorithms/ (props changed)
   branches/release/boost/geometry/arithmetic/ (props changed)
   branches/release/boost/geometry/core/ (props changed)
   branches/release/boost/geometry/geometries/ (props changed)
   branches/release/boost/geometry/geometry.hpp (props changed)
   branches/release/boost/geometry/io/ (props changed)
   branches/release/boost/geometry/io/dsv/ (props changed)
   branches/release/boost/geometry/iterators/ (props changed)
   branches/release/boost/geometry/multi/ (props changed)
   branches/release/boost/geometry/policies/ (props changed)
   branches/release/boost/geometry/strategies/ (props changed)
   branches/release/boost/geometry/util/ (props changed)
   branches/release/boost/geometry/views/ (props changed)
   branches/release/libs/geometry/doc/ (props changed)
   branches/release/libs/geometry/doc/Jamfile.v2 (props changed)
   branches/release/libs/geometry/doc/about_documentation.qbk (props changed)
   branches/release/libs/geometry/doc/acknowledgments.qbk (contents, props changed)
   branches/release/libs/geometry/doc/compiling.qbk (props changed)
   branches/release/libs/geometry/doc/concept/ (props changed)
   branches/release/libs/geometry/doc/copyright_note_policy.txt (props changed)
   branches/release/libs/geometry/doc/design_rationale.qbk (props changed)
   branches/release/libs/geometry/doc/doxy/ (props changed)
   branches/release/libs/geometry/doc/generated/ (props changed)
   branches/release/libs/geometry/doc/geometry.qbk (props changed)
   branches/release/libs/geometry/doc/html/ (props changed)
   branches/release/libs/geometry/doc/imports.qbk (props changed)
   branches/release/libs/geometry/doc/introduction.qbk (props changed)
   branches/release/libs/geometry/doc/make_qbk.py (props changed)
   branches/release/libs/geometry/doc/matrix.qbk (props changed)
   branches/release/libs/geometry/doc/quickref.xml (props changed)
   branches/release/libs/geometry/doc/quickstart.qbk (props changed)
   branches/release/libs/geometry/doc/readme.txt (props changed)
   branches/release/libs/geometry/doc/reference/ (props changed)
   branches/release/libs/geometry/doc/reference.qbk (props changed)
   branches/release/libs/geometry/doc/release_notes.qbk (contents, props changed)
   branches/release/libs/geometry/doc/src/ (props changed)
   branches/release/libs/geometry/example/ (props changed)
   branches/release/libs/geometry/test/ (props changed)
Text files modified:
   branches/release/boost/geometry/algorithms/area.hpp | 2
   branches/release/boost/geometry/algorithms/detail/for_each_range.hpp | 1
   branches/release/boost/geometry/algorithms/detail/occupation_info.hpp | 156 +++++++++++-
   branches/release/boost/geometry/algorithms/detail/overlay/add_rings.hpp | 28 ++
   branches/release/boost/geometry/algorithms/detail/overlay/assign_parents.hpp | 7
   branches/release/boost/geometry/algorithms/detail/overlay/calculate_distance_policy.hpp | 13
   branches/release/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp | 4
   branches/release/boost/geometry/algorithms/detail/overlay/copy_segments.hpp | 6
   branches/release/boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp | 2
   branches/release/boost/geometry/algorithms/detail/overlay/follow.hpp | 2
   branches/release/boost/geometry/algorithms/detail/overlay/get_ring.hpp | 2
   branches/release/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp | 202 +++++++++++++--
   branches/release/boost/geometry/algorithms/detail/overlay/turn_info.hpp | 16 +
   branches/release/boost/geometry/algorithms/detail/partition.hpp | 12
   branches/release/boost/geometry/algorithms/detail/sections/sectionalize.hpp | 2
   branches/release/boost/geometry/algorithms/disjoint.hpp | 63 +++-
   branches/release/boost/geometry/algorithms/distance.hpp | 2
   branches/release/boost/geometry/algorithms/within.hpp | 2
   branches/release/boost/geometry/iterators/ever_circling_iterator.hpp | 126 +++++++---
   branches/release/boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp | 2
   branches/release/boost/geometry/multi/algorithms/detail/overlay/copy_segments.hpp | 2
   branches/release/boost/geometry/multi/algorithms/detail/overlay/get_ring.hpp | 2
   branches/release/boost/geometry/multi/algorithms/detail/point_on_border.hpp | 16
   branches/release/boost/geometry/multi/algorithms/detail/sections/range_by_section.hpp | 2
   branches/release/boost/geometry/multi/io/wkt/read.hpp | 66 +++++
   branches/release/boost/geometry/policies/relate/direction.hpp | 2
   branches/release/boost/geometry/policies/relate/intersection_points.hpp | 41 --
   branches/release/boost/geometry/policies/relate/tupled.hpp | 6
   branches/release/boost/geometry/strategies/cartesian/cart_intersect.hpp | 490 +++++++++++++++++++++++++++++----------
   branches/release/boost/geometry/strategies/cartesian/distance_projected_point.hpp | 22 +
   branches/release/boost/geometry/strategies/side_info.hpp | 87 ++++++
   branches/release/boost/geometry/strategies/strategy_transform.hpp | 34 ++
   branches/release/boost/geometry/util/math.hpp | 56 ++++
   branches/release/libs/geometry/doc/acknowledgments.qbk | 3
   branches/release/libs/geometry/doc/release_notes.qbk | 28 ++
   branches/release/libs/geometry/example/Jamfile.v2 | 1
   branches/release/libs/geometry/test/algorithms/Jamfile.v2 | 1
   branches/release/libs/geometry/test/algorithms/algorithms_tests.sln | 6
   branches/release/libs/geometry/test/algorithms/difference.cpp | 31 +
   branches/release/libs/geometry/test/algorithms/disjoint.cpp | 6
   branches/release/libs/geometry/test/algorithms/distance.cpp | 4
   branches/release/libs/geometry/test/algorithms/intersection.cpp | 36 ++
   branches/release/libs/geometry/test/algorithms/overlay/get_turn_info.cpp | 14
   branches/release/libs/geometry/test/algorithms/overlay/get_turns.cpp | 4
   branches/release/libs/geometry/test/algorithms/overlay/overlay_cases.hpp | 95 +++++++
   branches/release/libs/geometry/test/algorithms/overlay/robustness/test_overlay_p_q.hpp | 15 +
   branches/release/libs/geometry/test/algorithms/overlay/traverse.cpp | 67 ++++-
   branches/release/libs/geometry/test/algorithms/test_union.hpp | 20
   branches/release/libs/geometry/test/algorithms/union.cpp | 116 +++++++-
   branches/release/libs/geometry/test/core/ring.cpp | 8
   branches/release/libs/geometry/test/geometries/adapted.cpp | 2
   branches/release/libs/geometry/test/geometries/custom_linestring.cpp | 6
   branches/release/libs/geometry/test/multi/algorithms/Jamfile.v2 | 2
   branches/release/libs/geometry/test/multi/algorithms/multi_difference.cpp | 13 +
   branches/release/libs/geometry/test/multi/algorithms/multi_intersection.cpp | 1
   branches/release/libs/geometry/test/multi/algorithms/multi_union.cpp | 3
   branches/release/libs/geometry/test/multi/algorithms/overlay/multi_overlay_cases.hpp | 2
   branches/release/libs/geometry/test/multi/io/wkt/wkt.cpp | 21 +
   branches/release/libs/geometry/test/multi/io/wkt/wkt.vcproj | 8
   branches/release/libs/geometry/test/multi/multi_tests.sln | 12
   branches/release/libs/geometry/test/robustness/convex_hull/random_multi_points.cpp | 2
   branches/release/libs/geometry/test/strategies/Jamfile.v2 | 1
   branches/release/libs/geometry/test/strategies/projected_point.cpp | 71 ++++-
   branches/release/libs/geometry/test/strategies/strategies_tests.sln | 6
   branches/release/libs/geometry/test/views/closeable_view.cpp | 2
   65 files changed, 1647 insertions(+), 436 deletions(-)

Modified: branches/release/boost/geometry/algorithms/area.hpp
==============================================================================
--- branches/release/boost/geometry/algorithms/area.hpp (original)
+++ branches/release/boost/geometry/algorithms/area.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -92,7 +92,7 @@
         // An open ring has at least three points,
         // A closed ring has at least four points,
         // if not, there is no (zero) area
- if (boost::size(ring)
+ if (int(boost::size(ring))
                 < core_detail::closure::minimum_ring_size<Closure>::value)
         {
             return type();

Modified: branches/release/boost/geometry/algorithms/detail/for_each_range.hpp
==============================================================================
--- branches/release/boost/geometry/algorithms/detail/for_each_range.hpp (original)
+++ branches/release/boost/geometry/algorithms/detail/for_each_range.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -22,6 +22,7 @@
 #include <boost/geometry/core/tag_cast.hpp>
 
 #include <boost/geometry/util/add_const_if_c.hpp>
+#include <boost/geometry/views/box_view.hpp>
 
 
 namespace boost { namespace geometry

Copied: branches/release/boost/geometry/algorithms/detail/occupation_info.hpp (from r77247, /trunk/boost/geometry/algorithms/detail/occupation_info.hpp)
==============================================================================
--- /trunk/boost/geometry/algorithms/detail/occupation_info.hpp (original)
+++ branches/release/boost/geometry/algorithms/detail/occupation_info.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -9,6 +9,9 @@
 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OCCUPATION_INFO_HPP
 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OCCUPATION_INFO_HPP
 
+#if ! defined(NDEBUG)
+ #define BOOST_GEOMETRY_DEBUG_BUFFER_OCCUPATION
+#endif
 
 #include <algorithm>
 #include <boost/range.hpp>
@@ -19,6 +22,8 @@
 #include <boost/geometry/algorithms/equals.hpp>
 #include <boost/geometry/iterators/closing_iterator.hpp>
 
+#include <boost/geometry/algorithms/detail/get_left_turns.hpp>
+
 
 namespace boost { namespace geometry
 {
@@ -28,6 +33,52 @@
 namespace detail
 {
 
+template <typename P>
+class relaxed_less
+{
+ typedef typename geometry::coordinate_type<P>::type coordinate_type;
+
+ coordinate_type epsilon;
+
+public :
+
+ inline relaxed_less()
+ {
+ // TODO: adapt for ttmath, and maybe build the map in another way
+ // (e.g. exact constellations of segment-id's), maybe adaptive.
+ epsilon = std::numeric_limits<double>::epsilon() * 100.0;
+ }
+
+ inline bool operator()(P const& a, P const& b) const
+ {
+ coordinate_type const dx = math::abs(geometry::get<0>(a) - geometry::get<0>(b));
+ coordinate_type const dy = math::abs(geometry::get<1>(a) - geometry::get<1>(b));
+
+
+ if (dx < epsilon && dy < epsilon)
+ {
+ return false;
+ }
+ if (dx < epsilon)
+ {
+ return geometry::get<1>(a) < geometry::get<1>(b);
+ }
+
+ return geometry::get<0>(a) < geometry::get<0>(b);
+ }
+
+ inline bool equals(P const& a, P const& b) const
+ {
+ typedef typename geometry::coordinate_type<P>::type coordinate_type;
+
+ coordinate_type const dx = math::abs(geometry::get<0>(a) - geometry::get<0>(b));
+ coordinate_type const dy = math::abs(geometry::get<1>(a) - geometry::get<1>(b));
+
+ return dx < epsilon && dy < epsilon;
+ };
+};
+
+
 template <typename T, typename P1, typename P2>
 inline T calculate_angle(P1 const& from_point, P2 const& to_point)
 {
@@ -38,25 +89,35 @@
 }
 
 template <typename Iterator, typename Vector>
-inline Iterator advance_circular(Iterator it, Vector const& vector, bool forward = true)
+inline Iterator advance_circular(Iterator it, Vector const& vector, segment_identifier& seg_id, bool forward = true)
 {
         int const increment = forward ? 1 : -1;
         if (it == boost::begin(vector) && increment < 0)
         {
                 it = boost::end(vector);
+ seg_id.segment_index = boost::size(vector);
         }
         it += increment;
+ seg_id.segment_index += increment;
         if (it == boost::end(vector))
         {
+ seg_id.segment_index = 0;
                 it = boost::begin(vector);
         }
         return it;
 }
 
-template <typename T>
+template <typename Point, typename T>
 struct angle_info
 {
         typedef T angle_type;
+ typedef Point point_type;
+
+ segment_identifier seg_id;
+ int turn_index;
+ int operation_index;
+ Point intersection_point;
+ Point direction_point;
     T angle;
     bool incoming;
 };
@@ -79,7 +140,9 @@
                 }
         };
 
+public :
     collection_type angles;
+private :
     bool m_occupied;
         bool m_calculated;
 
@@ -115,12 +178,26 @@
                 , m_calculated(false)
     {}
 
- template <typename Point1, typename Point2>
- inline void add(Point1 const& point1, Point2 const& point2, bool incoming)
+ template <typename PointC, typename Point1, typename Point2>
+ inline void add(PointC const& map_point, Point1 const& direction_point, Point2 const& intersection_point,
+ int turn_index, int operation_index,
+ segment_identifier const& seg_id, bool incoming)
         {
+ //std::cout << "-> adding angle " << geometry::wkt(direction_point) << " .. " << geometry::wkt(intersection_point) << " " << int(incoming) << std::endl;
+ if (geometry::equals(direction_point, intersection_point))
+ {
+ //std::cout << "EQUAL! Skipping" << std::endl;
+ return;
+ }
+
         AngleInfo info;
         info.incoming = incoming;
- info.angle = calculate_angle<typename AngleInfo::angle_type>(point1, point2);
+ info.angle = calculate_angle<typename AngleInfo::angle_type>(direction_point, map_point);
+ info.seg_id = seg_id;
+ info.turn_index = turn_index;
+ info.operation_index = operation_index;
+ info.intersection_point = intersection_point;
+ info.direction_point = direction_point;
         angles.push_back(info);
 
                 m_calculated = false;
@@ -136,12 +213,23 @@
                 return m_occupied;
         }
 
+ template <typename Turns, typename TurnSegmentIndices>
+ inline void get_left_turns(
+ Turns& turns, TurnSegmentIndices const& turn_segment_indices,
+ std::set<int>& keep_indices)
+ {
+ std::sort(angles.begin(), angles.end(), angle_sort());
+ calculate_left_turns<AngleInfo>(angles, turns, turn_segment_indices, keep_indices);
+ }
 };
 
 
 template <typename Point, typename Ring, typename Info>
-inline void add_incoming_and_outgoing_angles(Point const& point,
- Ring const& ring, int segment_index,
+inline void add_incoming_and_outgoing_angles(Point const& map_point, Point const& intersection_point,
+ Ring const& ring,
+ int turn_index,
+ int operation_index,
+ segment_identifier seg_id,
                 Info& info)
 {
     typedef typename boost::range_iterator
@@ -150,29 +238,42 @@
>::type iterator_type;
 
         int const n = boost::size(ring);
- if (segment_index >= n || segment_index < 0)
+ if (seg_id.segment_index >= n || seg_id.segment_index < 0)
         {
                 return;
         }
 
- iterator_type it = boost::begin(ring) + segment_index;
+ segment_identifier real_seg_id = seg_id;
+ iterator_type it = boost::begin(ring) + seg_id.segment_index;
+
+ // TODO: if we use turn-info ("to", "middle"), we know if to advance without resorting to equals
+ relaxed_less<Point> comparator;
 
- if (geometry::equals(point, *it))
+ if (comparator.equals(intersection_point, *it))
     {
- it = advance_circular(it, ring, false);
+ // It should be equal only once. But otherwise we skip it (in "add")
+ it = advance_circular(it, ring, seg_id, false);
     }
 
- info.add(*it, point, true);
+ info.add(map_point, *it, intersection_point, turn_index, operation_index, real_seg_id, true);
 
- it = advance_circular(it, ring);
+ if (comparator.equals(intersection_point, *it))
+ {
+ it = advance_circular(it, ring, real_seg_id);
+ }
+ else
+ {
+ // Don't upgrade the ID
+ it = advance_circular(it, ring, seg_id);
+ }
     for (int defensive_check = 0;
- geometry::equals(point, *it) && defensive_check < n;
+ comparator.equals(intersection_point, *it) && defensive_check < n;
                 defensive_check++)
     {
- it = advance_circular(it, ring);
+ it = advance_circular(it, ring, real_seg_id);
     }
 
- info.add(*it, point, false);
+ info.add(map_point, *it, intersection_point, turn_index, operation_index, real_seg_id, false);
 }
 
 
@@ -183,10 +284,12 @@
 class occupation_map
 {
 public :
- typedef std::map<Point, OccupationInfo, geometry::less<Point> > map_type;
+ typedef std::map<Point, OccupationInfo, relaxed_less<Point> > map_type;
+
     map_type map;
+ std::set<int> turn_indices;
 
- OccupationInfo& find_or_insert(Point point)
+ inline OccupationInfo& find_or_insert(Point const& point, Point& mapped_point)
     {
         typename map_type::iterator it = map.find(point);
         if (it == boost::end(map))
@@ -195,10 +298,25 @@
                         = map.insert(std::make_pair(point, OccupationInfo()));
             it = pair.first;
         }
-
+ mapped_point = it->first;
         return it->second;
     }
 
+ inline bool contains(Point const& point) const
+ {
+ typename map_type::const_iterator it = map.find(point);
+ return it != boost::end(map);
+ }
+
+ inline bool contains_turn_index(int index) const
+ {
+ return turn_indices.count(index) > 0;
+ }
+
+ inline void insert_turn_index(int index)
+ {
+ turn_indices.insert(index);
+ }
 };
 
 

Modified: branches/release/boost/geometry/algorithms/detail/overlay/add_rings.hpp
==============================================================================
--- branches/release/boost/geometry/algorithms/detail/overlay/add_rings.hpp (original)
+++ branches/release/boost/geometry/algorithms/detail/overlay/add_rings.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -9,6 +9,8 @@
 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP
 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP
 
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/algorithms/area.hpp>
 #include <boost/geometry/algorithms/detail/overlay/convert_ring.hpp>
 #include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
 
@@ -73,6 +75,21 @@
             OutputIterator out)
 {
     typedef typename SelectionMap::const_iterator iterator;
+ typedef typename SelectionMap::mapped_type property_type;
+ typedef typename property_type::area_type area_type;
+
+ area_type const zero = 0;
+ std::size_t const min_num_points = core_detail::closure::minimum_ring_size
+ <
+ geometry::closure
+ <
+ typename boost::range_value
+ <
+ RingCollection const
+ >::type
+ >::value
+ >::value;
+
 
     for (iterator it = boost::begin(map);
         it != boost::end(map);
@@ -99,7 +116,16 @@
                             *child_it, mit->second.reversed, true);
                 }
             }
- *out++ = result;
+
+ // Only add rings if they satisfy minimal requirements.
+ // This cannot be done earlier (during traversal), not
+ // everything is figured out yet (sum of positive/negative rings)
+ // TODO: individual rings can still contain less than 3 points.
+ if (geometry::num_points(result) >= min_num_points
+ && math::larger(geometry::area(result), zero))
+ {
+ *out++ = result;
+ }
         }
     }
     return out;

Modified: branches/release/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
==============================================================================
--- branches/release/boost/geometry/algorithms/detail/overlay/assign_parents.hpp (original)
+++ branches/release/boost/geometry/algorithms/detail/overlay/assign_parents.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -130,7 +130,7 @@
             return;
         }
 
- if (outer.real_area > 0)
+ if (math::larger(outer.real_area, 0))
         {
             if (inner.real_area < 0 || m_check_for_orientation)
             {
@@ -317,13 +317,14 @@
>
 inline void assign_parents(Geometry const& geometry,
             RingCollection const& collection,
- RingMap& ring_map)
+ RingMap& ring_map,
+ bool check_for_orientation)
 {
     // Call it with an empty geometry
     // (ring_map should be empty for source_id==1)
 
     Geometry empty;
- assign_parents(geometry, empty, collection, ring_map, true);
+ assign_parents(geometry, empty, collection, ring_map, check_for_orientation);
 }
 
 

Modified: branches/release/boost/geometry/algorithms/detail/overlay/calculate_distance_policy.hpp
==============================================================================
--- branches/release/boost/geometry/algorithms/detail/overlay/calculate_distance_policy.hpp (original)
+++ branches/release/boost/geometry/algorithms/detail/overlay/calculate_distance_policy.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -32,9 +32,18 @@
 {
     static bool const include_no_turn = false;
     static bool const include_degenerate = false;
+ static bool const include_opposite = false;
 
- template <typename Point1, typename Point2, typename Info>
- static inline void apply(Info& info, Point1 const& p1, Point2 const& p2)
+ template
+ <
+ typename Info,
+ typename Point1,
+ typename Point2,
+ typename IntersectionInfo,
+ typename DirInfo
+ >
+ static inline void apply(Info& info, Point1 const& p1, Point2 const& p2,
+ IntersectionInfo const&, DirInfo const&)
     {
         info.operations[0].enriched.distance
                     = geometry::comparable_distance(info.point, p1);

Modified: branches/release/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp
==============================================================================
--- branches/release/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp (original)
+++ branches/release/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -55,14 +55,14 @@
         if (second)
         {
             index++;
- if (index >= boost::size(range))
+ if (index >= int(boost::size(range)))
             {
                 index = 0;
             }
         }
 
         // Exception?
- if (index >= boost::size(range))
+ if (index >= int(boost::size(range)))
         {
             return false;
         }

Modified: branches/release/boost/geometry/algorithms/detail/overlay/copy_segments.hpp
==============================================================================
--- branches/release/boost/geometry/algorithms/detail/overlay/copy_segments.hpp (original)
+++ branches/release/boost/geometry/algorithms/detail/overlay/copy_segments.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -78,7 +78,7 @@
         int const from_index = seg_id.segment_index + 1;
 
         // Sanity check
- BOOST_ASSERT(from_index < boost::size(view));
+ BOOST_ASSERT(from_index < int(boost::size(view)));
 
         ec_iterator it(boost::begin(view), boost::end(view),
                     boost::begin(view) + from_index);
@@ -89,7 +89,7 @@
         typedef typename boost::range_difference<Ring>::type size_type;
         size_type const count = from_index <= to_index
             ? to_index - from_index + 1
- : boost::size(view) - from_index + to_index + 1;
+ : int(boost::size(view)) - from_index + to_index + 1;
 
         for (size_type i = 0; i < count; ++i, ++it)
         {
@@ -117,7 +117,7 @@
         int const from_index = seg_id.segment_index + 1;
 
         // Sanity check
- if (from_index > to_index || from_index < 0 || to_index >= boost::size(ls))
+ if (from_index > to_index || from_index < 0 || to_index >= int(boost::size(ls)))
         {
             return;
         }

Modified: branches/release/boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp
==============================================================================
--- branches/release/boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp (original)
+++ branches/release/boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -28,6 +28,7 @@
         case method_touch_interior : return 'm';
         case method_collinear : return 'c';
         case method_equal : return 'e';
+ case method_error : return '!';
         default : return '?';
     }
 }
@@ -42,6 +43,7 @@
         case operation_intersection : return 'i';
         case operation_blocked : return 'x';
         case operation_continue : return 'c';
+ case operation_opposite : return 'o';
         default : return '?';
     }
 }

Modified: branches/release/boost/geometry/algorithms/detail/overlay/follow.hpp
==============================================================================
--- branches/release/boost/geometry/algorithms/detail/overlay/follow.hpp (original)
+++ branches/release/boost/geometry/algorithms/detail/overlay/follow.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -279,12 +279,12 @@
     {
         // In case of turn point at the same location, we want to have continue/blocked LAST
         // because that should be followed (intersection) or skipped (difference).
- // By chance the enumeration is ordered like that but we keep the safe way here.
         inline int operation_order(Turn const& turn) const
         {
             operation_type const& operation = turn.operations[0].operation;
             switch(operation)
             {
+ case operation_opposite : return 0;
                 case operation_none : return 0;
                 case operation_union : return 1;
                 case operation_intersection : return 2;

Modified: branches/release/boost/geometry/algorithms/detail/overlay/get_ring.hpp
==============================================================================
--- branches/release/boost/geometry/algorithms/detail/overlay/get_ring.hpp (original)
+++ branches/release/boost/geometry/algorithms/detail/overlay/get_ring.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -83,7 +83,7 @@
         BOOST_ASSERT
             (
                 id.ring_index >= -1
- && id.ring_index < boost::size(interior_rings(polygon))
+ && id.ring_index < int(boost::size(interior_rings(polygon)))
             );
         return id.ring_index < 0
             ? exterior_ring(polygon)

Modified: branches/release/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp
==============================================================================
--- branches/release/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp (original)
+++ branches/release/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -250,9 +250,15 @@
             int const side_pk_q2 = SideStrategy::apply(qj, qk, pk);
             int const side_pk_p = SideStrategy::apply(pi, pj, pk);
             int const side_qk_q = SideStrategy::apply(qi, qj, qk);
+
+ bool const both_continue = side_pk_p == 0 && side_qk_q == 0;
+ bool const robustness_issue_in_continue = both_continue && side_pk_q2 != 0;
+
             bool const q_turns_left = side_qk_q == 1;
             bool const block_q = side_qk_p1 == 0
- && ! same(side_qi_p1, side_qk_q);
+ && ! same(side_qi_p1, side_qk_q)
+ && ! robustness_issue_in_continue
+ ;
 
             // If Pk at same side as Qi/Qk
             // (the "or" is for collinear case)
@@ -278,7 +284,7 @@
                 if (side_pk_q1 == 0)
                 {
                     ti.operations[0].operation = operation_blocked;
- // Q turns right -> union (both independant),
+ // Q turns right -> union (both independent),
                     // Q turns left -> intersection
                     ti.operations[1].operation = block_q ? operation_blocked
                         : q_turns_left ? operation_intersection
@@ -466,6 +472,45 @@
 template
 <
     typename TurnInfo,
+ typename AssignPolicy
+>
+struct equal_opposite : public base_turn_handler
+{
+ template
+ <
+ typename Point1,
+ typename Point2,
+ typename OutputIterator,
+ typename IntersectionInfo,
+ typename DirInfo
+ >
+ static inline void apply(Point1 const& pi, Point2 const& qi,
+ /* by value: */ TurnInfo tp,
+ OutputIterator& out,
+ IntersectionInfo const& intersection_info,
+ DirInfo const& dir_info)
+ {
+ // For equal-opposite segments, normally don't do anything.
+ if (AssignPolicy::include_opposite)
+ {
+ tp.method = method_equal;
+ for (int i = 0; i < 2; i++)
+ {
+ tp.operations[i].operation = operation_opposite;
+ }
+ for (unsigned int i = 0; i < intersection_info.count; i++)
+ {
+ geometry::convert(intersection_info.intersections[i], tp.point);
+ AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
+ *out++ = tp;
+ }
+ }
+ }
+};
+
+template
+<
+ typename TurnInfo,
     typename SideStrategy
>
 struct collinear : public base_turn_handler
@@ -494,6 +539,13 @@
          - if P arrives and P turns right: intersection for P
          - if Q arrives and Q turns left: union for Q (=intersection for P)
          - if Q arrives and Q turns right: intersection for Q (=union for P)
+
+ ROBUSTNESS: p and q are collinear, so you would expect
+ that side qk//p1 == pk//q1. But that is not always the case
+ in near-epsilon ranges. Then decision logic is different.
+ If p arrives, q is further, so the angle qk//p1 is (normally)
+ more precise than pk//p1
+
     */
     template
     <
@@ -516,12 +568,18 @@
         // Should not be 0, this is checked before
         BOOST_ASSERT(arrival != 0);
 
+ int const side_p = SideStrategy::apply(pi, pj, pk);
+ int const side_q = SideStrategy::apply(qi, qj, qk);
+
         // If p arrives, use p, else use q
         int const side_p_or_q = arrival == 1
- ? SideStrategy::apply(pi, pj, pk)
- : SideStrategy::apply(qi, qj, qk)
+ ? side_p
+ : side_q
             ;
 
+ int const side_pk = SideStrategy::apply(qi, qj, pk);
+ int const side_qk = SideStrategy::apply(pi, pj, qk);
+
         // See comments above,
         // resulting in a strange sort of mathematic rule here:
         // The arrival-info multiplied by the relevant side
@@ -529,7 +587,15 @@
 
         int const product = arrival * side_p_or_q;
 
- if(product == 0)
+ // Robustness: side_p is supposed to be equal to side_pk (because p/q are collinear)
+ // and side_q to side_qk
+ bool const robustness_issue = side_pk != side_p || side_qk != side_q;
+
+ if (robustness_issue)
+ {
+ handle_robustness(ti, arrival, side_p, side_q, side_pk, side_qk);
+ }
+ else if(product == 0)
         {
             both(ti, operation_continue);
         }
@@ -538,6 +604,38 @@
             ui_else_iu(product == 1, ti);
         }
     }
+
+ static inline void handle_robustness(TurnInfo& ti, int arrival,
+ int side_p, int side_q, int side_pk, int side_qk)
+ {
+ // We take the longer one, i.e. if q arrives in p (arrival == -1),
+ // then p exceeds q and we should take p for a union...
+
+ bool use_p_for_union = arrival == -1;
+
+ // ... unless one of the sides consistently directs to the other side
+ int const consistent_side_p = side_p == side_pk ? side_p : 0;
+ int const consistent_side_q = side_q == side_qk ? side_q : 0;
+ if (arrival == -1 && (consistent_side_p == -1 || consistent_side_q == 1))
+ {
+ use_p_for_union = false;
+ }
+ if (arrival == 1 && (consistent_side_p == 1 || consistent_side_q == -1))
+ {
+ use_p_for_union = true;
+ }
+
+ //std::cout << "ROBUSTNESS -> Collinear "
+ // << " arr: " << arrival
+ // << " dir: " << side_p << " " << side_q
+ // << " rev: " << side_pk << " " << side_qk
+ // << " cst: " << cside_p << " " << cside_q
+ // << std::boolalpha << " " << use_p_for_union
+ // << std::endl;
+
+ ui_else_iu(use_p_for_union, ti);
+ }
+
 };
 
 template
@@ -583,6 +681,7 @@
                 TurnInfo& tp, IntersectionInfo const& intersection_info)
     {
         int const side_rk_r = SideStrategy::apply(ri, rj, rk);
+ operation_type blocked = operation_blocked;
         switch(side_rk_r)
         {
 
@@ -596,15 +695,24 @@
                 break;
             case 0 :
                 // No turn on opposite collinear: block, do not traverse
- // But this "xx" is ignored here, it is useless to include
- // two operation blocked, so the whole point does not need
+ // But this "xx" is usually ignored, it is useless to include
+ // two operations blocked, so the whole point does not need
                 // to be generated.
                 // So return false to indicate nothing is to be done.
- return false;
+ if (AssignPolicy::include_opposite)
+ {
+ tp.operations[Index].operation = operation_opposite;
+ blocked = operation_opposite;
+ }
+ else
+ {
+ return false;
+ }
+ break;
         }
 
         // The other direction is always blocked when collinear opposite
- tp.operations[1 - Index].operation = operation_blocked;
+ tp.operations[1 - Index].operation = blocked;
 
         // If P arrives within Q, set info on P (which is done above, index=0),
         // this turn-info belongs to the second intersection point, index=1
@@ -633,32 +741,45 @@
                 IntersectionInfo const& intersection_info,
                 DirInfo const& dir_info)
     {
- /*
- std::cout << "arrivals: "
- << dir_info.arrival[0]
- << "/" << dir_info.arrival[1]
- << std::endl;
- */
-
         TurnInfo tp = tp_model;
 
         tp.method = method_collinear;
 
- // If P arrives within Q, there is a turn dependant on P
+ // If P arrives within Q, there is a turn dependent on P
         if (dir_info.arrival[0] == 1
             && set_tp<0>(pi, pj, pk, tp, intersection_info))
         {
- AssignPolicy::apply(tp, pi, qi);
+ AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
             *out++ = tp;
         }
 
- // If Q arrives within P, there is a turn dependant on Q
+ // If Q arrives within P, there is a turn dependent on Q
         if (dir_info.arrival[1] == 1
             && set_tp<1>(qi, qj, qk, tp, intersection_info))
         {
- AssignPolicy::apply(tp, pi, qi);
+ AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
             *out++ = tp;
         }
+
+ if (AssignPolicy::include_opposite)
+ {
+ // Handle cases not yet handled above
+ if ((dir_info.arrival[1] == -1 && dir_info.arrival[0] == 0)
+ || (dir_info.arrival[0] == -1 && dir_info.arrival[1] == 0))
+ {
+ for (int i = 0; i < 2; i++)
+ {
+ tp.operations[i].operation = operation_opposite;
+ }
+ for (unsigned int i = 0; i < intersection_info.count; i++)
+ {
+ geometry::convert(intersection_info.intersections[i], tp.point);
+ AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
+ *out++ = tp;
+ }
+ }
+ }
+
     }
 };
 
@@ -722,9 +843,17 @@
 {
     static bool const include_no_turn = false;
     static bool const include_degenerate = false;
+ static bool const include_opposite = false;
 
- template <typename Point1, typename Point2, typename Info>
- static inline void apply(Info& , Point1 const& , Point2 const& )
+ template
+ <
+ typename Info,
+ typename Point1,
+ typename Point2,
+ typename IntersectionInfo,
+ typename DirInfo
+ >
+ static inline void apply(Info& , Point1 const& , Point2 const&, IntersectionInfo const&, DirInfo const&)
     {}
 
 };
@@ -763,8 +892,9 @@
 
     typedef typename si::segment_intersection_strategy_type strategy;
 
-
-
+ // Intersect pi-pj with qi-qj
+ // The points pk and qk are only used do determine more information
+ // about the turn.
     template <typename OutputIterator>
     static inline OutputIterator apply(
                 Point1 const& pi, Point1 const& pj, Point1 const& pk,
@@ -796,7 +926,7 @@
                 {
                     only_convert<TurnInfo>::apply(tp,
                                 result.template get<0>());
- AssignPolicy::apply(tp, pi, qi);
+ AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
                     *out++ = tp;
                 }
                 break;
@@ -824,7 +954,7 @@
                     policy::template apply<1>(qi, qj, qk, pi, pj, pk,
                                 tp, result.template get<0>(), result.template get<1>());
                 }
- AssignPolicy::apply(tp, pi, qi);
+ AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
                 *out++ = tp;
             }
             break;
@@ -838,7 +968,7 @@
 
                 policy::apply(pi, pj, pk, qi, qj, qk,
                     tp, result.template get<0>(), result.template get<1>());
- AssignPolicy::apply(tp, pi, qi);
+ AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
                 *out++ = tp;
             }
             break;
@@ -853,7 +983,7 @@
 
                 policy::apply(pi, pj, pk, qi, qj, qk,
                     tp, result.template get<0>(), result.template get<1>());
- AssignPolicy::apply(tp, pi, qi);
+ AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
                 *out++ = tp;
             }
             break;
@@ -871,10 +1001,18 @@
 
                     policy::apply(pi, pj, pk, qi, qj, qk,
                         tp, result.template get<0>(), result.template get<1>());
- AssignPolicy::apply(tp, pi, qi);
+ AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
                     *out++ = tp;
                 }
- // If they ARE opposite, don't do anything.
+ else
+ {
+ equal_opposite
+ <
+ TurnInfo,
+ AssignPolicy
+ >::apply(pi, qi,
+ tp, out, result.template get<0>(), result.template get<1>());
+ }
             }
             break;
             case 'c' :
@@ -906,7 +1044,7 @@
                                 tp, result.template get<0>(), result.template get<1>());
                     }
 
- AssignPolicy::apply(tp, pi, qi);
+ AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
                     *out++ = tp;
                 }
                 else
@@ -927,7 +1065,7 @@
                 if (AssignPolicy::include_degenerate)
                 {
                     only_convert<TurnInfo>::apply(tp, result.template get<0>());
- AssignPolicy::apply(tp, pi, qi);
+ AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
                     *out++ = tp;
                 }
             }

Modified: branches/release/boost/geometry/algorithms/detail/overlay/turn_info.hpp
==============================================================================
--- branches/release/boost/geometry/algorithms/detail/overlay/turn_info.hpp (original)
+++ branches/release/boost/geometry/algorithms/detail/overlay/turn_info.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -28,7 +28,8 @@
     operation_union,
     operation_intersection,
     operation_blocked,
- operation_continue
+ operation_continue,
+ operation_opposite
 };
 
 
@@ -102,6 +103,12 @@
     {
         return has12(type, type);
     }
+
+ inline bool has(operation_type type) const
+ {
+ return this->operations[0].operation == type
+ || this->operations[1].operation == type;
+ }
 
     inline bool combination(operation_type type1, operation_type type2) const
     {
@@ -114,10 +121,13 @@
     {
         return both(operation_blocked);
     }
+ inline bool opposite() const
+ {
+ return both(operation_opposite);
+ }
     inline bool any_blocked() const
     {
- return this->operations[0].operation == operation_blocked
- || this->operations[1].operation == operation_blocked;
+ return has(operation_blocked);
     }
 
 

Modified: branches/release/boost/geometry/algorithms/detail/partition.hpp
==============================================================================
--- branches/release/boost/geometry/algorithms/detail/partition.hpp (original)
+++ branches/release/boost/geometry/algorithms/detail/partition.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -153,7 +153,7 @@
     static inline void next_level(Box const& box,
             InputCollection const& collection,
             index_vector_type const& input,
- int level, int min_elements,
+ int level, std::size_t min_elements,
             Policy& policy, VisitBoxPolicy& box_policy)
     {
         if (boost::size(input) > 0)
@@ -176,7 +176,7 @@
             InputCollection const& collection,
             index_vector_type const& input,
             int level,
- int min_elements,
+ std::size_t min_elements,
             Policy& policy, VisitBoxPolicy& box_policy)
     {
         box_policy.apply(box, level);
@@ -230,7 +230,7 @@
             index_vector_type const& input1,
             InputCollection const& collection2,
             index_vector_type const& input2,
- int level, int min_elements,
+ int level, std::size_t min_elements,
             Policy& policy, VisitBoxPolicy& box_policy)
     {
         if (boost::size(input1) > 0 && boost::size(input2) > 0)
@@ -257,7 +257,7 @@
             InputCollection const& collection1, index_vector_type const& input1,
             InputCollection const& collection2, index_vector_type const& input2,
             int level,
- int min_elements,
+ std::size_t min_elements,
             Policy& policy, VisitBoxPolicy& box_policy)
     {
         box_policy.apply(box, level);
@@ -335,7 +335,7 @@
     template <typename InputCollection, typename VisitPolicy>
     static inline void apply(InputCollection const& collection,
             VisitPolicy& visitor,
- int min_elements = 16,
+ std::size_t min_elements = 16,
             VisitBoxPolicy box_visitor = visit_no_policy()
             )
     {
@@ -377,7 +377,7 @@
     static inline void apply(InputCollection const& collection1,
                 InputCollection const& collection2,
                 VisitPolicy& visitor,
- int min_elements = 16,
+ std::size_t min_elements = 16,
                 VisitBoxPolicy box_visitor = visit_no_policy()
                 )
     {

Modified: branches/release/boost/geometry/algorithms/detail/sections/sectionalize.hpp
==============================================================================
--- branches/release/boost/geometry/algorithms/detail/sections/sectionalize.hpp (original)
+++ branches/release/boost/geometry/algorithms/detail/sections/sectionalize.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -254,7 +254,7 @@
                 Range const& range,
                 ring_identifier ring_id)
     {
- if (boost::size(range) <= index)
+ if (int(boost::size(range)) <= index)
         {
             return;
         }

Modified: branches/release/boost/geometry/algorithms/disjoint.hpp
==============================================================================
--- branches/release/boost/geometry/algorithms/disjoint.hpp (original)
+++ branches/release/boost/geometry/algorithms/disjoint.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -27,6 +27,7 @@
 #include <boost/geometry/core/reverse_dispatch.hpp>
 
 #include <boost/geometry/algorithms/detail/disjoint.hpp>
+#include <boost/geometry/algorithms/detail/for_each_range.hpp>
 #include <boost/geometry/algorithms/detail/point_on_border.hpp>
 #include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
 #include <boost/geometry/algorithms/within.hpp>
@@ -44,15 +45,57 @@
 namespace detail { namespace disjoint
 {
 
+template<typename Geometry>
+struct check_each_ring_for_within
+{
+ bool has_within;
+ Geometry const& m_geometry;
+
+ inline check_each_ring_for_within(Geometry const& g)
+ : has_within(false)
+ , m_geometry(g)
+ {}
+
+ template <typename Range>
+ inline void apply(Range const& range)
+ {
+ typename geometry::point_type<Range>::type p;
+ geometry::point_on_border(p, range);
+ if (geometry::within(p, m_geometry))
+ {
+ has_within = true;
+ }
+ }
+};
+
+template <typename FirstGeometry, typename SecondGeometry>
+inline bool rings_containing(FirstGeometry const& geometry1,
+ SecondGeometry const& geometry2)
+{
+ check_each_ring_for_within<FirstGeometry> checker(geometry1);
+ geometry::detail::for_each_range(geometry2, checker);
+ return checker.has_within;
+}
+
+
 struct assign_disjoint_policy
 {
     // We want to include all points:
     static bool const include_no_turn = true;
     static bool const include_degenerate = true;
+ static bool const include_opposite = true;
 
     // We don't assign extra info:
- template <typename Point1, typename Point2, typename Info>
- static inline void apply(Info& , Point1 const& , Point2 const& )
+ template
+ <
+ typename Info,
+ typename Point1,
+ typename Point2,
+ typename IntersectionInfo,
+ typename DirInfo
+ >
+ static inline void apply(Info& , Point1 const& , Point2 const&,
+ IntersectionInfo const&, DirInfo const&)
     {}
 };
    
@@ -107,8 +150,6 @@
     }
 };
 
-
-
 template <typename Geometry1, typename Geometry2>
 struct general_areal
 {
@@ -119,20 +160,10 @@
             return false;
         }
 
- typedef typename geometry::point_type<Geometry1>::type point_type;
-
         // If there is no intersection of segments, they might located
         // inside each other
- point_type p1;
- geometry::point_on_border(p1, geometry1);
- if (geometry::within(p1, geometry2))
- {
- return false;
- }
-
- typename geometry::point_type<Geometry1>::type p2;
- geometry::point_on_border(p2, geometry2);
- if (geometry::within(p2, geometry1))
+ if (rings_containing(geometry1, geometry2)
+ || rings_containing(geometry2, geometry1))
         {
             return false;
         }

Modified: branches/release/boost/geometry/algorithms/distance.hpp
==============================================================================
--- branches/release/boost/geometry/algorithms/distance.hpp (original)
+++ branches/release/boost/geometry/algorithms/distance.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -130,7 +130,7 @@
         // check if other segments are closer
         for (++prev, ++it; it != boost::end(view); ++prev, ++it)
         {
- return_type const ds = ps_strategy.apply(point, *prev, *it);
+ return_type const ds = eps_strategy.apply(point, *prev, *it);
             if (geometry::math::equals(ds, zero))
             {
                 return ds;

Modified: branches/release/boost/geometry/algorithms/within.hpp
==============================================================================
--- branches/release/boost/geometry/algorithms/within.hpp (original)
+++ branches/release/boost/geometry/algorithms/within.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -65,7 +65,7 @@
     static inline int apply(Point const& point, Ring const& ring,
             Strategy const& strategy)
     {
- if (boost::size(ring)
+ if (int(boost::size(ring))
                 < core_detail::closure::minimum_ring_size<Closure>::value)
         {
             return -1;

Modified: branches/release/boost/geometry/iterators/ever_circling_iterator.hpp
==============================================================================
--- branches/release/boost/geometry/iterators/ever_circling_iterator.hpp (original)
+++ branches/release/boost/geometry/iterators/ever_circling_iterator.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -95,67 +95,115 @@
     bool m_skip_first;
 };
 
-
-
 template <typename Range>
-class ever_circling_range_iterator
- : public boost::iterator_adaptor
- <
- ever_circling_range_iterator<Range>,
- typename boost::range_iterator<Range>::type
- >
+struct ever_circling_range_iterator
+ : public boost::iterator_facade
+ <
+ ever_circling_range_iterator<Range>,
+ typename boost::range_value<Range>::type const,
+ boost::random_access_traversal_tag
+ >
 {
-public :
- typedef typename boost::range_iterator<Range>::type iterator_type;
+ /// Constructor including the range it is based on
+ explicit inline ever_circling_range_iterator(Range& range)
+ : m_range(&range)
+ , m_iterator(boost::begin(range))
+ , m_size(boost::size(range))
+ , m_index(0)
+ {}
+
+ /// Default constructor
+ explicit inline ever_circling_range_iterator()
+ : m_range(NULL)
+ , m_size(0)
+ , m_index(0)
+ {}
 
- explicit inline ever_circling_range_iterator(Range& range,
- bool skip_first = false)
- : m_range(range)
- , m_skip_first(skip_first)
+ inline ever_circling_range_iterator<Range>& operator=(ever_circling_range_iterator<Range> const& source)
     {
- this->base_reference() = boost::begin(m_range);
+ m_range = source.m_range;
+ m_iterator = source.m_iterator;
+ m_size = source.m_size;
+ m_index = source.m_index;
+ return *this;
     }
 
- explicit inline ever_circling_range_iterator(Range& range, iterator_type start,
- bool skip_first = false)
- : m_range(range)
- , m_skip_first(skip_first)
+ typedef std::ptrdiff_t difference_type;
+
+private:
+ friend class boost::iterator_core_access;
+
+ inline typename boost::range_value<Range>::type const& dereference() const
     {
- this->base_reference() = start;
+ return *m_iterator;
     }
 
- /// Navigate to a certain position, should be in [start .. end], if at end
- /// it will circle again.
- inline void moveto(iterator_type it)
+ inline difference_type distance_to(ever_circling_range_iterator<Range> const& other) const
     {
- this->base_reference() = it;
- check_end();
+ return other.m_index - this->m_index;
     }
 
-private:
+ inline bool equal(ever_circling_range_iterator<Range> const& other) const
+ {
+ return this->m_range == other.m_range
+ && this->m_index == other.m_index;
+ }
 
- friend class boost::iterator_core_access;
+ inline void increment()
+ {
+ ++m_index;
+ if (m_index >= 0 && m_index < m_size)
+ {
+ ++m_iterator;
+ }
+ else
+ {
+ update_iterator();
+ }
+ }
+
+ inline void decrement()
+ {
+ --m_index;
+ if (m_index >= 0 && m_index < m_size)
+ {
+ --m_iterator;
+ }
+ else
+ {
+ update_iterator();
+ }
+ }
 
- inline void increment(bool possibly_skip = true)
+ inline void advance(difference_type n)
     {
- (this->base_reference())++;
- check_end(possibly_skip);
+ if (m_index >= 0 && m_index < m_size
+ && m_index + n >= 0 && m_index + n < m_size)
+ {
+ m_index += n;
+ m_iterator += n;
+ }
+ else
+ {
+ m_index += n;
+ update_iterator();
+ }
     }
 
- inline void check_end(bool possibly_skip = true)
+ inline void update_iterator()
     {
- if (this->base_reference() == boost::end(m_range))
+ while (m_index < 0)
         {
- this->base_reference() = boost::begin(m_range);
- if (m_skip_first && possibly_skip)
- {
- increment(false);
- }
+ m_index += m_size;
         }
+ m_index = m_index % m_size;
+ this->m_iterator = boost::begin(*m_range) + m_index;
     }
 
- Range& m_range;
- bool m_skip_first;
+ Range* m_range;
+ typename boost::range_iterator<Range>::type m_iterator;
+ difference_type m_size;
+ difference_type m_index;
 };
 
 

Modified: branches/release/boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp
==============================================================================
--- branches/release/boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp (original)
+++ branches/release/boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -42,7 +42,7 @@
         BOOST_ASSERT
             (
                 seg_id.multi_index >= 0
- && seg_id.multi_index < boost::size(multi)
+ && seg_id.multi_index < int(boost::size(multi))
             );
 
         // Call the single-version

Modified: branches/release/boost/geometry/multi/algorithms/detail/overlay/copy_segments.hpp
==============================================================================
--- branches/release/boost/geometry/multi/algorithms/detail/overlay/copy_segments.hpp (original)
+++ branches/release/boost/geometry/multi/algorithms/detail/overlay/copy_segments.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -44,7 +44,7 @@
         BOOST_ASSERT
             (
                 seg_id.multi_index >= 0
- && seg_id.multi_index < boost::size(multi_geometry)
+ && seg_id.multi_index < int(boost::size(multi_geometry))
             );
 
         // Call the single-version

Modified: branches/release/boost/geometry/multi/algorithms/detail/overlay/get_ring.hpp
==============================================================================
--- branches/release/boost/geometry/multi/algorithms/detail/overlay/get_ring.hpp (original)
+++ branches/release/boost/geometry/multi/algorithms/detail/overlay/get_ring.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -35,7 +35,7 @@
         BOOST_ASSERT
             (
                 id.multi_index >= 0
- && id.multi_index < boost::size(multi_polygon)
+ && id.multi_index < int(boost::size(multi_polygon))
             );
         return get_ring<polygon_tag>::apply(id,
                     multi_polygon[id.multi_index]);

Modified: branches/release/boost/geometry/multi/algorithms/detail/point_on_border.hpp
==============================================================================
--- branches/release/boost/geometry/multi/algorithms/detail/point_on_border.hpp (original)
+++ branches/release/boost/geometry/multi/algorithms/detail/point_on_border.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -31,13 +31,13 @@
 
 template
 <
- typename MultiGeometry,
     typename Point,
+ typename MultiGeometry,
     typename Policy
>
 struct point_on_multi
 {
- static inline bool apply(MultiGeometry const& multi, Point& point)
+ static inline bool apply(Point& point, MultiGeometry const& multi, bool midpoint)
     {
         // Take a point on the first multi-geometry
         // (i.e. the first that is not empty)
@@ -48,7 +48,7 @@
             it != boost::end(multi);
             ++it)
         {
- if (Policy::apply(*it, point))
+ if (Policy::apply(point, *it, midpoint))
             {
                 return true;
             }
@@ -69,16 +69,16 @@
 {
 
 
-template<typename Multi, typename Point>
-struct point_on_border<multi_polygon_tag, Multi, Point>
+template<typename Point, typename Multi>
+struct point_on_border<multi_polygon_tag, Point, Multi>
     : detail::point_on_border::point_on_multi
         <
- Multi,
             Point,
+ Multi,
             detail::point_on_border::point_on_polygon
                 <
- typename boost::range_value<Multi>::type,
- Point
+ Point,
+ typename boost::range_value<Multi>::type
>
>
 {};

Modified: branches/release/boost/geometry/multi/algorithms/detail/sections/range_by_section.hpp
==============================================================================
--- branches/release/boost/geometry/multi/algorithms/detail/sections/range_by_section.hpp (original)
+++ branches/release/boost/geometry/multi/algorithms/detail/sections/range_by_section.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -46,7 +46,7 @@
         BOOST_ASSERT
             (
                 section.ring_id.multi_index >= 0
- && section.ring_id.multi_index < boost::size(multi)
+ && section.ring_id.multi_index < int(boost::size(multi))
             );
 
         return Policy::apply(multi[section.ring_id.multi_index], section);

Modified: branches/release/boost/geometry/multi/io/wkt/read.hpp
==============================================================================
--- branches/release/boost/geometry/multi/io/wkt/read.hpp (original)
+++ branches/release/boost/geometry/multi/io/wkt/read.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -58,6 +58,69 @@
 
             handle_close_parenthesis(it, tokens.end(), wkt);
         }
+
+ check_end(it, tokens.end(), wkt);
+ }
+};
+
+template <typename P>
+struct noparenthesis_point_parser
+{
+ static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+ std::string const& wkt, P& point)
+ {
+ parsing_assigner<P, 0, dimension<P>::value>::apply(it, end, point, wkt);
+ }
+};
+
+template <typename MultiGeometry, typename PrefixPolicy>
+struct multi_point_parser
+{
+ static inline void apply(std::string const& wkt, MultiGeometry& geometry)
+ {
+ traits::clear<MultiGeometry>::apply(geometry);
+
+ tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+ tokenizer::iterator it;
+
+ if (initialize<MultiGeometry>(tokens, PrefixPolicy::apply(), wkt, it))
+ {
+ handle_open_parenthesis(it, tokens.end(), wkt);
+
+ // If first point definition starts with "(" then parse points as (x y)
+ // otherwise as "x y"
+ bool using_brackets = (it != tokens.end() && *it == "(");
+
+ while(it != tokens.end() && *it != ")")
+ {
+ traits::resize<MultiGeometry>::apply(geometry, boost::size(geometry) + 1);
+
+ if (using_brackets)
+ {
+ point_parser
+ <
+ typename boost::range_value<MultiGeometry>::type
+ >::apply(it, tokens.end(), wkt, geometry.back());
+ }
+ else
+ {
+ noparenthesis_point_parser
+ <
+ typename boost::range_value<MultiGeometry>::type
+ >::apply(it, tokens.end(), wkt, geometry.back());
+ }
+
+ if (it != tokens.end() && *it == ",")
+ {
+ // Skip "," after point is parsed
+ ++it;
+ }
+ }
+
+ handle_close_parenthesis(it, tokens.end(), wkt);
+ }
+
+ check_end(it, tokens.end(), wkt);
     }
 };
 
@@ -69,10 +132,9 @@
 
 template <typename MultiGeometry>
 struct read_wkt<multi_point_tag, MultiGeometry>
- : detail::wkt::multi_parser
+ : detail::wkt::multi_point_parser
             <
                 MultiGeometry,
- detail::wkt::point_parser,
                 detail::wkt::prefix_multipoint
>
 {};

Modified: branches/release/boost/geometry/policies/relate/direction.hpp
==============================================================================
--- branches/release/boost/geometry/policies/relate/direction.hpp (original)
+++ branches/release/boost/geometry/policies/relate/direction.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -126,7 +126,9 @@
     typedef typename select_most_precise<coordinate_type, double>::type rtype;
 
 
+ template <typename R>
     static inline return_type segments_intersect(side_info const& sides,
+ R const&,
                     coordinate_type const& dx1, coordinate_type const& dy1,
                     coordinate_type const& dx2, coordinate_type const& dy2,
                     S1 const& s1, S2 const& s2)

Modified: branches/release/boost/geometry/policies/relate/intersection_points.hpp
==============================================================================
--- branches/release/boost/geometry/policies/relate/intersection_points.hpp (original)
+++ branches/release/boost/geometry/policies/relate/intersection_points.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -36,56 +36,33 @@
     typedef ReturnType return_type;
     typedef S1 segment_type1;
     typedef S2 segment_type2;
+
     typedef typename select_calculation_type
         <
             S1, S2, CalculationType
>::type coordinate_type;
 
+ template <typename R>
     static inline return_type segments_intersect(side_info const&,
+ R const& r,
                     coordinate_type const& dx1, coordinate_type const& dy1,
                     coordinate_type const& dx2, coordinate_type const& dy2,
                     S1 const& s1, S2 const& s2)
     {
- return_type result;
         typedef typename geometry::coordinate_type
             <
                 typename return_type::point_type
- >::type coordinate_type;
-
- // Get the same type, but at least a double (also used for divisions)
- typedef typename select_most_precise
- <
- coordinate_type, double
- >::type promoted_type;
-
- promoted_type const s1x = get<0, 0>(s1);
- promoted_type const s1y = get<0, 1>(s1);
+ >::type return_coordinate_type;
 
- // Calculate other determinants - Cramers rule
- promoted_type const wx = get<0, 0>(s1) - get<0, 0>(s2);
- promoted_type const wy = get<0, 1>(s1) - get<0, 1>(s2);
- promoted_type const d = detail::determinant<promoted_type>(dx1, dy1, dx2, dy2);
- promoted_type const da = detail::determinant<promoted_type>(dx2, dy2, wx, wy);
-
- // r: ratio 0-1 where intersection divides A/B
- promoted_type r = da / d;
- promoted_type const zero = promoted_type();
- promoted_type const one = 1;
- // Handle robustness issues
- if (r < zero)
- {
- r = zero;
- }
- else if (r > one)
- {
- r = one;
- }
+ coordinate_type const s1x = get<0, 0>(s1);
+ coordinate_type const s1y = get<0, 1>(s1);
 
+ return_type result;
         result.count = 1;
         set<0>(result.intersections[0],
- boost::numeric_cast<coordinate_type>(s1x + r * promoted_type(dx1)));
+ boost::numeric_cast<return_coordinate_type>(R(s1x) + r * R(dx1)));
         set<1>(result.intersections[0],
- boost::numeric_cast<coordinate_type>(s1y + r * promoted_type(dy1)));
+ boost::numeric_cast<return_coordinate_type>(R(s1y) + r * R(dy1)));
 
         return result;
     }

Modified: branches/release/boost/geometry/policies/relate/tupled.hpp
==============================================================================
--- branches/release/boost/geometry/policies/relate/tupled.hpp (original)
+++ branches/release/boost/geometry/policies/relate/tupled.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -49,16 +49,18 @@
     // Get the same type, but at least a double
     typedef typename select_most_precise<coordinate_type, double>::type rtype;
 
+ template <typename R>
     static inline return_type segments_intersect(side_info const& sides,
+ R const& r,
                     coordinate_type const& dx1, coordinate_type const& dy1,
                     coordinate_type const& dx2, coordinate_type const& dy2,
                     segment_type1 const& s1, segment_type2 const& s2)
     {
         return boost::make_tuple
             (
- Policy1::segments_intersect(sides,
+ Policy1::segments_intersect(sides, r,
                     dx1, dy1, dx2, dy2, s1, s2),
- Policy2::segments_intersect(sides,
+ Policy2::segments_intersect(sides, r,
                     dx1, dy1, dx2, dy2, s1, s2)
             );
     }

Modified: branches/release/boost/geometry/strategies/cartesian/cart_intersect.hpp
==============================================================================
--- branches/release/boost/geometry/strategies/cartesian/cart_intersect.hpp (original)
+++ branches/release/boost/geometry/strategies/cartesian/cart_intersect.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -41,21 +41,17 @@
 namespace detail
 {
 
-template <typename Segment, size_t Dimension>
-struct segment_arrange
+template <std::size_t Dimension, typename Segment, typename T>
+static inline void segment_arrange(Segment const& s, T& s_1, T& s_2, bool& swapped)
 {
- template <typename T>
- static inline void apply(Segment const& s, T& s_1, T& s_2, bool& swapped)
+ s_1 = get<0, Dimension>(s);
+ s_2 = get<1, Dimension>(s);
+ if (s_1 > s_2)
     {
- s_1 = get<0, Dimension>(s);
- s_2 = get<1, Dimension>(s);
- if (s_1 > s_2)
- {
- std::swap(s_1, s_2);
- swapped = true;
- }
+ std::swap(s_1, s_2);
+ swapped = true;
     }
-};
+}
 
 template <std::size_t Index, typename Segment>
 inline typename geometry::point_type<Segment>::type get_from_index(
@@ -121,34 +117,20 @@
             coordinate_type const& dx_a, coordinate_type const& dy_a,
             coordinate_type const& dx_b, coordinate_type const& dy_b)
     {
- // 1) Handle "disjoint", common case.
- // per dimension, 2 cases: a_1----------a_2 b_1-------b_2 or B left of A
- coordinate_type ax_1, ax_2, bx_1, bx_2;
- bool ax_swapped = false, bx_swapped = false;
- detail::segment_arrange<segment_type1, 0>::apply(a, ax_1, ax_2, ax_swapped);
- detail::segment_arrange<segment_type2, 0>::apply(b, bx_1, bx_2, bx_swapped);
- if (ax_2 < bx_1 || ax_1 > bx_2)
- {
- return Policy::disjoint();
- }
-
- // 1b) In Y-dimension
- coordinate_type ay_1, ay_2, by_1, by_2;
- bool ay_swapped = false, by_swapped = false;
- detail::segment_arrange<segment_type1, 1>::apply(a, ay_1, ay_2, ay_swapped);
- detail::segment_arrange<segment_type2, 1>::apply(b, by_1, by_2, by_swapped);
- if (ay_2 < by_1 || ay_1 > by_2)
- {
- return Policy::disjoint();
- }
-
         typedef side::side_by_triangle<coordinate_type> side;
         side_info sides;
 
- // 2) Calculate sides
- // Note: Do NOT yet calculate the determinant here, but use the SIDE strategy.
- // Determinant calculation is not robust; side (orient) can be made robust
- // (and is much robuster even without measures)
+ bool collinear_use_first = math::abs(dx_a) + math::abs(dx_b) >= math::abs(dy_a) + math::abs(dy_b);
+
+ sides.set<0>
+ (
+ side::apply(detail::get_from_index<0>(b)
+ , detail::get_from_index<1>(b)
+ , detail::get_from_index<0>(a)),
+ side::apply(detail::get_from_index<0>(b)
+ , detail::get_from_index<1>(b)
+ , detail::get_from_index<1>(a))
+ );
         sides.set<1>
             (
                 side::apply(detail::get_from_index<0>(a)
@@ -159,26 +141,18 @@
                     , detail::get_from_index<1>(b))
             );
 
- if (sides.same<1>())
- {
- // Both points are at same side of other segment, we can leave
- return Policy::disjoint();
- }
+ bool collinear = sides.collinear();
 
- // 2b) For other segment
- sides.set<0>
- (
- side::apply(detail::get_from_index<0>(b)
- , detail::get_from_index<1>(b)
- , detail::get_from_index<0>(a)),
- side::apply(detail::get_from_index<0>(b)
- , detail::get_from_index<1>(b)
- , detail::get_from_index<1>(a))
- );
+ robustness_verify_collinear(a, b, sides, collinear);
+ robustness_verify_meeting(a, b, sides, collinear, collinear_use_first);
 
- if (sides.same<0>())
+ if (sides.same<0>() || sides.same<1>())
         {
- return Policy::disjoint();
+ // Both points are at same side of other segment, we can leave
+ if (robustness_verify_same_side(a, b, sides))
+ {
+ return Policy::disjoint();
+ }
         }
 
         // Degenerate cases: segments of single point, lying on other segment, non disjoint
@@ -192,81 +166,342 @@
             return Policy::degenerate(b, false);
         }
 
- bool collinear = sides.collinear();
-
- // Get the same type, but at least a double (also used for divisions)
         typedef typename select_most_precise
             <
                 coordinate_type, double
>::type promoted_type;
 
- // Calculate the determinant/2D cross product
- // (Note, because we only check on zero,
- // the order a/b does not care)
- promoted_type const d = geometry::detail::determinant
- <
- promoted_type
- >(dx_a, dy_a, dx_b, dy_b);
+ // r: ratio 0-1 where intersection divides A/B
+ // (only calculated for non-collinear segments)
+ promoted_type r;
+ if (! collinear)
+ {
+ // Calculate determinants - Cramers rule
+ coordinate_type const wx = get<0, 0>(a) - get<0, 0>(b);
+ coordinate_type const wy = get<0, 1>(a) - get<0, 1>(b);
+ coordinate_type const d = geometry::detail::determinant<coordinate_type>(dx_a, dy_a, dx_b, dy_b);
+ coordinate_type const da = geometry::detail::determinant<coordinate_type>(dx_b, dy_b, wx, wy);
+
+ coordinate_type const zero = coordinate_type();
+ if (math::equals(d, zero))
+ {
+ // This is still a collinear case (because of FP imprecision this can occur here)
+ // sides.debug();
+ sides.set<0>(0,0);
+ sides.set<1>(0,0);
+ collinear = true;
+ }
+ else
+ {
+ r = da / d;
 
- // Determinant d should be nonzero.
- // If it is zero, we have an robustness issue here,
- // (and besides that we cannot divide by it)
- promoted_type const pt_zero = promoted_type();
- if(math::equals(d, pt_zero) && ! collinear)
- {
-#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
- std::cout << "Determinant zero? Type : "
- << typeid(coordinate_type).name()
- << std::endl;
-
- std::cout << " dx_a : " << dx_a << std::endl;
- std::cout << " dy_a : " << dy_a << std::endl;
- std::cout << " dx_b : " << dx_b << std::endl;
- std::cout << " dy_b : " << dy_b << std::endl;
-
- std::cout << " side a <-> b.first : " << sides.get<0,0>() << std::endl;
- std::cout << " side a <-> b.second: " << sides.get<0,1>() << std::endl;
- std::cout << " side b <-> a.first : " << sides.get<1,0>() << std::endl;
- std::cout << " side b <-> a.second: " << sides.get<1,1>() << std::endl;
-#endif
+ if (! robustness_verify_r(a, b, r))
+ {
+ return Policy::disjoint();
+ }
+
+ robustness_handle_meeting(a, b, sides, dx_a, dy_a, wx, wy, d, r);
+
+ if (robustness_verify_disjoint_at_one_collinear(a, b, sides))
+ {
+ return Policy::disjoint();
+ }
+
+ }
+ }
+
+ if(collinear)
+ {
+ if (collinear_use_first)
+ {
+ return relate_collinear<0>(a, b);
+ }
+ else
+ {
+ // Y direction contains larger segments (maybe dx is zero)
+ return relate_collinear<1>(a, b);
+ }
+ }
+
+ return Policy::segments_intersect(sides, r,
+ dx_a, dy_a, dx_b, dy_b,
+ a, b);
+ }
+
+private :
+
+
+ // Ratio should lie between 0 and 1
+ // Also these three conditions might be of FP imprecision, the segments were actually (nearly) collinear
+ template <typename T>
+ static inline bool robustness_verify_r(
+ segment_type1 const& a, segment_type2 const& b,
+ T& r)
+ {
+ T const zero = 0;
+ T const one = 1;
+ if (r < zero || r > one)
+ {
+ if (verify_disjoint<0>(a, b) || verify_disjoint<1>(a, b))
+ {
+ // Can still be disjoint (even if not one is left or right from another)
+ // This is e.g. in case #snake4 of buffer test.
+ return false;
+ }
+
+ //std::cout << "ROBUSTNESS: correction of r " << r << std::endl;
+ // sides.debug();
+
+ // ROBUSTNESS: the r value can in epsilon-cases much larger than 1, while (with perfect arithmetic)
+ // it should be one. It can be 1.14 or even 1.98049 or 2 (while still intersecting)
+
+ // If segments are crossing (we can see that with the sides)
+ // and one is inside the other, there must be an intersection point.
+ // We correct for that.
+ // This is (only) in case #ggl_list_20110820_christophe in unit tests
+
+ // If segments are touching (two sides zero), of course they should intersect
+ // This is (only) in case #buffer_rt_i in the unit tests)
 
- if (sides.as_collinear())
+ // If one touches in the middle, they also should intersect (#buffer_rt_j)
+
+ // Note that even for ttmath r is occasionally > 1, e.g. 1.0000000000000000000000036191231203575
+
+ if (r > one)
+ {
+ r = one;
+ }
+ else if (r < zero)
+ {
+ r = zero;
+ }
+ }
+ return true;
+ }
+
+ static inline void robustness_verify_collinear(
+ segment_type1 const& a, segment_type2 const& b,
+ side_info& sides,
+ bool& collinear)
+ {
+ if ((sides.zero<0>() && ! sides.zero<1>()) || (sides.zero<1>() && ! sides.zero<0>()))
+ {
+ // If one of the segments is collinear, the other must be as well.
+ // So handle it as collinear.
+ // (In float/double epsilon margins it can easily occur that one or two of them are -1/1)
+ // sides.debug();
+ sides.set<0>(0,0);
+ sides.set<1>(0,0);
+ collinear = true;
+ }
+ }
+
+ static inline void robustness_verify_meeting(
+ segment_type1 const& a, segment_type2 const& b,
+ side_info& sides,
+ bool& collinear, bool& collinear_use_first)
+ {
+ if (sides.meeting())
+ {
+ // If two segments meet each other at their segment-points, two sides are zero,
+ // the other two are not (unless collinear but we don't mean those here).
+ // However, in near-epsilon ranges it can happen that two sides are zero
+ // but they do not meet at their segment-points.
+ // In that case they are nearly collinear and handled as such.
+ if (! point_equals
+ (
+ select(sides.zero_index<0>(), a),
+ select(sides.zero_index<1>(), b)
+ )
+ )
             {
                 sides.set<0>(0,0);
                 sides.set<1>(0,0);
                 collinear = true;
+
+ if (collinear_use_first && analyse_equal<0>(a, b))
+ {
+ collinear_use_first = false;
+ }
+ else if (! collinear_use_first && analyse_equal<1>(a, b))
+ {
+ collinear_use_first = true;
+ }
+
             }
- else
+ }
+ }
+
+ // Verifies and if necessary correct missed touch because of robustness
+ // This is the case at multi_polygon_buffer unittest #rt_m
+ static inline bool robustness_verify_same_side(
+ segment_type1 const& a, segment_type2 const& b,
+ side_info& sides)
+ {
+ int corrected = 0;
+ if (sides.one_touching<0>())
+ {
+ if (point_equals(
+ select(sides.zero_index<0>(), a),
+ select(0, b)
+ ))
             {
- return Policy::error("Determinant zero!");
+ sides.correct_to_zero<1, 0>();
+ corrected = 1;
+ }
+ if (point_equals
+ (
+ select(sides.zero_index<0>(), a),
+ select(1, b)
+ ))
+ {
+ sides.correct_to_zero<1, 1>();
+ corrected = 2;
             }
         }
-
- if(collinear)
+ else if (sides.one_touching<1>())
         {
- // Segments are collinear. We'll find out how.
- if (math::equals(dx_b, zero))
+ if (point_equals(
+ select(sides.zero_index<1>(), b),
+ select(0, a)
+ ))
             {
- // Vertical -> Check y-direction
- return relate_collinear(a, b,
- ay_1, ay_2, by_1, by_2,
- ay_swapped, by_swapped);
+ sides.correct_to_zero<0, 0>();
+ corrected = 3;
             }
- else
+ if (point_equals
+ (
+ select(sides.zero_index<1>(), b),
+ select(1, a)
+ ))
             {
- // Check x-direction
- return relate_collinear(a, b,
- ax_1, ax_2, bx_1, bx_2,
- ax_swapped, bx_swapped);
+ sides.correct_to_zero<0, 1>();
+ corrected = 4;
             }
         }
 
- return Policy::segments_intersect(sides,
- dx_a, dy_a, dx_b, dy_b,
- a, b);
+ return corrected == 0;
     }
 
-private :
+ static inline bool robustness_verify_disjoint_at_one_collinear(
+ segment_type1 const& a, segment_type2 const& b,
+ side_info const& sides)
+ {
+ if (sides.one_of_all_zero())
+ {
+ if (verify_disjoint<0>(a, b) || verify_disjoint<1>(a, b))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ // If r is one, or zero, segments should meet and their endpoints.
+ // Robustness issue: check if this is really the case.
+ // It turns out to be no problem, see buffer test #rt_s1 (and there are many cases generated)
+ // It generates an "ends in the middle" situation which is correct.
+ template <typename T, typename R>
+ static inline void robustness_handle_meeting(segment_type1 const& a, segment_type2 const& b,
+ side_info& sides,
+ T const& dx_a, T const& dy_a, T const& wx, T const& wy,
+ T const& d, R const& r)
+ {
+ return;
+
+ T const db = geometry::detail::determinant<T>(dx_a, dy_a, wx, wy);
+
+ R const zero = 0;
+ R const one = 1;
+ if (math::equals(r, zero) || math::equals(r, one))
+ {
+ R rb = db / d;
+ if (rb <= 0 || rb >= 1 || math::equals(rb, 0) || math::equals(rb, 1))
+ {
+ if (sides.one_zero<0>() && ! sides.one_zero<1>()) // or vice versa
+ {
+#if defined(BOOST_GEOMETRY_COUNT_INTERSECTION_EQUAL)
+ extern int g_count_intersection_equal;
+ g_count_intersection_equal++;
+#endif
+ sides.debug();
+ std::cout << "E r=" << r << " r.b=" << rb << " ";
+ }
+ }
+ }
+ }
+
+ template <std::size_t Dimension>
+ static inline bool verify_disjoint(segment_type1 const& a,
+ segment_type2 const& b)
+ {
+ coordinate_type a_1, a_2, b_1, b_2;
+ bool a_swapped = false, b_swapped = false;
+ detail::segment_arrange<Dimension>(a, a_1, a_2, a_swapped);
+ detail::segment_arrange<Dimension>(b, b_1, b_2, b_swapped);
+ return math::smaller(a_2, b_1) || math::larger(a_1, b_2);
+ }
+
+ template <typename Segment>
+ static inline typename point_type<Segment>::type select(int index, Segment const& segment)
+ {
+ return index == 0
+ ? detail::get_from_index<0>(segment)
+ : detail::get_from_index<1>(segment)
+ ;
+ }
+
+ // We cannot use geometry::equals here. Besides that this will be changed
+ // to compare segment-coordinate-values directly (not necessary to retrieve point first)
+ template <typename Point1, typename Point2>
+ static inline bool point_equals(Point1 const& point1, Point2 const& point2)
+ {
+ return math::equals(get<0>(point1), get<0>(point2))
+ && math::equals(get<1>(point1), get<1>(point2))
+ ;
+ }
+
+ // We cannot use geometry::equals here. Besides that this will be changed
+ // to compare segment-coordinate-values directly (not necessary to retrieve point first)
+ template <typename Point1, typename Point2>
+ static inline bool point_equality(Point1 const& point1, Point2 const& point2,
+ bool& equals_0, bool& equals_1)
+ {
+ equals_0 = math::equals(get<0>(point1), get<0>(point2));
+ equals_1 = math::equals(get<1>(point1), get<1>(point2));
+ return equals_0 && equals_1;
+ }
+
+ template <std::size_t Dimension>
+ static inline bool analyse_equal(segment_type1 const& a, segment_type2 const& b)
+ {
+ coordinate_type const a_1 = geometry::get<0, Dimension>(a);
+ coordinate_type const a_2 = geometry::get<1, Dimension>(a);
+ coordinate_type const b_1 = geometry::get<0, Dimension>(b);
+ coordinate_type const b_2 = geometry::get<1, Dimension>(b);
+ return math::equals(a_1, b_1)
+ || math::equals(a_2, b_1)
+ || math::equals(a_1, b_2)
+ || math::equals(a_2, b_2)
+ ;
+ }
+
+ template <std::size_t Dimension>
+ static inline return_type relate_collinear(segment_type1 const& a,
+ segment_type2 const& b)
+ {
+ coordinate_type a_1, a_2, b_1, b_2;
+ bool a_swapped = false, b_swapped = false;
+ detail::segment_arrange<Dimension>(a, a_1, a_2, a_swapped);
+ detail::segment_arrange<Dimension>(b, b_1, b_2, b_swapped);
+ if (math::smaller(a_2, b_1) || math::larger(a_1, b_2))
+ //if (a_2 < b_1 || a_1 > b_2)
+ {
+ return Policy::disjoint();
+ }
+ return relate_collinear(a, b, a_1, a_2, b_1, b_2, a_swapped, b_swapped);
+ }
 
     /// Relate segments known collinear
     static inline return_type relate_collinear(segment_type1 const& a
@@ -296,33 +531,36 @@
 
         // Handle "equal", in polygon neighbourhood comparisons a common case
 
- // Check if segments are equal...
- bool const a1_eq_b1 = math::equals(get<0, 0>(a), get<0, 0>(b))
- && math::equals(get<0, 1>(a), get<0, 1>(b));
- bool const a2_eq_b2 = math::equals(get<1, 0>(a), get<1, 0>(b))
- && math::equals(get<1, 1>(a), get<1, 1>(b));
- if (a1_eq_b1 && a2_eq_b2)
- {
- return Policy::segment_equal(a, false);
- }
-
- // ... or opposite equal
- bool const a1_eq_b2 = math::equals(get<0, 0>(a), get<1, 0>(b))
- && math::equals(get<0, 1>(a), get<1, 1>(b));
- bool const a2_eq_b1 = math::equals(get<1, 0>(a), get<0, 0>(b))
- && math::equals(get<1, 1>(a), get<0, 1>(b));
- if (a1_eq_b2 && a2_eq_b1)
+ bool const opposite = a_swapped ^ b_swapped;
+ bool const both_swapped = a_swapped && b_swapped;
+
+ // Check if segments are equal or opposite equal...
+ bool const swapped_a1_eq_b1 = math::equals(a_1, b_1);
+ bool const swapped_a2_eq_b2 = math::equals(a_2, b_2);
+
+ if (swapped_a1_eq_b1 && swapped_a2_eq_b2)
         {
- return Policy::segment_equal(a, true);
+ return Policy::segment_equal(a, opposite);
         }
 
+ bool const swapped_a2_eq_b1 = math::equals(a_2, b_1);
+ bool const swapped_a1_eq_b2 = math::equals(a_1, b_2);
+
+ bool const a1_eq_b1 = both_swapped ? swapped_a2_eq_b2 : a_swapped ? swapped_a2_eq_b1 : b_swapped ? swapped_a1_eq_b2 : swapped_a1_eq_b1;
+ bool const a2_eq_b2 = both_swapped ? swapped_a1_eq_b1 : a_swapped ? swapped_a1_eq_b2 : b_swapped ? swapped_a2_eq_b1 : swapped_a2_eq_b2;
+
+ bool const a1_eq_b2 = both_swapped ? swapped_a2_eq_b1 : a_swapped ? swapped_a2_eq_b2 : b_swapped ? swapped_a1_eq_b1 : swapped_a1_eq_b2;
+ bool const a2_eq_b1 = both_swapped ? swapped_a1_eq_b2 : a_swapped ? swapped_a1_eq_b1 : b_swapped ? swapped_a2_eq_b2 : swapped_a2_eq_b1;
+
+
+
 
         // The rest below will return one or two intersections.
         // The delegated class can decide which is the intersection point, or two, build the Intersection Matrix (IM)
         // For IM it is important to know which relates to which. So this information is given,
         // without performance penalties to intersection calculation
 
- bool const has_common_points = a1_eq_b1 || a1_eq_b2 || a2_eq_b1 || a2_eq_b2;
+ bool const has_common_points = swapped_a1_eq_b1 || swapped_a1_eq_b2 || swapped_a2_eq_b1 || swapped_a2_eq_b2;
 
 
         // "Touch" -> one intersection point -> one but not two common points
@@ -342,7 +580,7 @@
         // #4: a2<----a1 b1--->b2 (no arrival at all)
         // Where the arranged forms have two forms:
         // a_1-----a_2/b_1-------b_2 or reverse (B left of A)
- if (has_common_points && (math::equals(a_2, b_1) || math::equals(b_2, a_1)))
+ if ((swapped_a2_eq_b1 || swapped_a1_eq_b2) && ! swapped_a1_eq_b1 && ! swapped_a2_eq_b2)
         {
             if (a2_eq_b1) return Policy::collinear_touch(get<1, 0>(a), get<1, 1>(a), 0, -1);
             if (a1_eq_b2) return Policy::collinear_touch(get<0, 0>(a), get<0, 1>(a), -1, 0);
@@ -402,7 +640,6 @@
             if (a1_eq_b1) return Policy::collinear_interior_boundary_intersect(a_in_b ? a : b, a_in_b, arrival_a, -arrival_a, false);
         }
 
- bool const opposite = a_swapped ^ b_swapped;
 
 
         // "Inside", a completely within b or b completely within a
@@ -464,7 +701,6 @@
           the picture might seem wrong but it (supposed to be) is right.
         */
 
- bool const both_swapped = a_swapped && b_swapped;
         if (b_1 < a_2 && a_2 < b_2)
         {
             // Left column, from bottom to top
@@ -486,7 +722,7 @@
                 ;
         }
         // Nothing should goes through. If any we have made an error
- // Robustness: it can occur here...
+ // std::cout << "Robustness issue, non-logical behaviour" << std::endl;
         return Policy::error("Robustness issue, non-logical behaviour");
     }
 };

Modified: branches/release/boost/geometry/strategies/cartesian/distance_projected_point.hpp
==============================================================================
--- branches/release/boost/geometry/strategies/cartesian/distance_projected_point.hpp (original)
+++ branches/release/boost/geometry/strategies/cartesian/distance_projected_point.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -75,23 +75,27 @@
 class projected_point
 {
 public :
- typedef typename strategy::distance::services::return_type<Strategy>::type calculation_type;
-
-private :
-
     // The three typedefs below are necessary to calculate distances
     // from segments defined in integer coordinates.
 
     // Integer coordinates can still result in FP distances.
     // There is a division, which must be represented in FP.
     // So promote.
- typedef typename promote_floating_point<calculation_type>::type fp_type;
+ typedef typename promote_floating_point
+ <
+ typename strategy::distance::services::return_type
+ <
+ Strategy
+ >::type
+ >::type calculation_type;
+
+private :
 
     // A projected point of points in Integer coordinates must be able to be
     // represented in FP.
     typedef model::point
         <
- fp_type,
+ calculation_type,
             dimension<PointOfSegment>::value,
             typename coordinate_system<PointOfSegment>::type
> fp_point_type;
@@ -139,19 +143,19 @@
         boost::ignore_unused_variable_warning(strategy);
 
         calculation_type const zero = calculation_type();
- fp_type const c1 = dot_product(w, v);
+ calculation_type const c1 = dot_product(w, v);
         if (c1 <= zero)
         {
             return strategy.apply(p, p1);
         }
- fp_type const c2 = dot_product(v, v);
+ calculation_type const c2 = dot_product(v, v);
         if (c2 <= c1)
         {
             return strategy.apply(p, p2);
         }
 
         // See above, c1 > 0 AND c2 > c1 so: c2 != 0
- fp_type const b = c1 / c2;
+ calculation_type const b = c1 / c2;
 
         fp_strategy_type fp_strategy
             = strategy::distance::services::get_similar

Modified: branches/release/boost/geometry/strategies/side_info.hpp
==============================================================================
--- branches/release/boost/geometry/strategies/side_info.hpp (original)
+++ branches/release/boost/geometry/strategies/side_info.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -45,6 +45,19 @@
     }
 
     template <int Which, int Index>
+ inline void correct_to_zero()
+ {
+ if (Index == 0)
+ {
+ sides[Which].first = 0;
+ }
+ else
+ {
+ sides[Which].second = 0;
+ }
+ }
+
+ template <int Which, int Index>
     inline int get() const
     {
         return Index == 0 ? sides[Which].first : sides[Which].second;
@@ -67,21 +80,81 @@
             && sides[1].second == 0;
     }
 
- // If one of the segments is collinear, the other must be as well.
- // So handle it as collinear.
- // (In floating point margins it can occur that one of them is 1!)
- inline bool as_collinear() const
+ inline bool crossing() const
+ {
+ return sides[0].first * sides[0].second == -1
+ && sides[1].first * sides[1].second == -1;
+ }
+
+ inline bool touching() const
+ {
+ return (sides[0].first * sides[1].first == -1
+ && sides[0].second == 0 && sides[1].second == 0)
+ || (sides[1].first * sides[0].first == -1
+ && sides[1].second == 0 && sides[0].second == 0);
+ }
+
+ template <int Which>
+ inline bool one_touching() const
+ {
+ // This is normally a situation which can't occur:
+ // If one is completely left or right, the other cannot touch
+ return one_zero<Which>()
+ && sides[1 - Which].first * sides[1 - Which].second == 1;
+ }
+
+ inline bool meeting() const
+ {
+ // Two of them (in each segment) zero, two not
+ return one_zero<0>() && one_zero<1>();
+ }
+
+ template <int Which>
+ inline bool zero() const
     {
- return sides[0].first * sides[0].second == 0
- || sides[1].first * sides[1].second == 0;
+ return sides[Which].first == 0 && sides[Which].second == 0;
     }
 
+ template <int Which>
+ inline bool one_zero() const
+ {
+ return (sides[Which].first == 0 && sides[Which].second != 0)
+ || (sides[Which].first != 0 && sides[Which].second == 0);
+ }
+
+ inline bool one_of_all_zero() const
+ {
+ int const sum = std::abs(sides[0].first)
+ + std::abs(sides[0].second)
+ + std::abs(sides[1].first)
+ + std::abs(sides[1].second);
+ return sum == 3;
+ }
+
+
+ template <int Which>
+ inline int zero_index() const
+ {
+ return sides[Which].first == 0 ? 0 : 1;
+ }
+
+
+ inline void debug() const
+ {
+ std::cout << sides[0].first << " "
+ << sides[0].second << " "
+ << sides[1].first << " "
+ << sides[1].second
+ << std::endl;
+ }
+
+
     inline void reverse()
     {
         std::swap(sides[0], sides[1]);
     }
 
-private :
+//private :
     std::pair<int, int> sides[2];
 
 };

Modified: branches/release/boost/geometry/strategies/strategy_transform.hpp
==============================================================================
--- branches/release/boost/geometry/strategies/strategy_transform.hpp (original)
+++ branches/release/boost/geometry/strategies/strategy_transform.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -23,7 +23,9 @@
 #include <boost/geometry/algorithms/convert.hpp>
 #include <boost/geometry/arithmetic/arithmetic.hpp>
 #include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/radian_access.hpp>
 #include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/strategies/transform.hpp>
 
 #include <boost/geometry/util/math.hpp>
 #include <boost/geometry/util/select_coordinate_type.hpp>
@@ -251,6 +253,23 @@
         return false;
     }
 
+ template <typename P, typename T>
+ inline bool cartesian_to_spherical_equatorial3(T x, T y, T z, P& p)
+ {
+ assert_dimension<P, 3>();
+
+ // http://en.wikipedia.org/wiki/List_of_canonical_coordinate_transformations#From_Cartesian_coordinates
+ T const r = sqrt(x * x + y * y + z * z);
+ set<2>(p, r);
+ set_from_radian<0>(p, atan2(y, x));
+ if (r > 0.0)
+ {
+ set_from_radian<1>(p, asin(z / r));
+ return true;
+ }
+ return false;
+ }
+
 } // namespace detail
 #endif // DOXYGEN_NO_DETAIL
 
@@ -361,6 +380,16 @@
     }
 };
 
+template <typename P1, typename P2>
+struct from_cartesian_3_to_spherical_equatorial_3
+{
+ inline bool apply(P1 const& p1, P2& p2) const
+ {
+ assert_dimension<P1, 3>();
+ return detail::cartesian_to_spherical_equatorial3(get<0>(p1), get<1>(p1), get<2>(p1), p2);
+ }
+};
+
 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
 
 namespace services
@@ -454,6 +483,11 @@
 {
     typedef from_cartesian_3_to_spherical_polar_3<P1, P2> type;
 };
+template <typename CoordSys1, typename CoordSys2, typename P1, typename P2>
+struct default_strategy<cartesian_tag, spherical_equatorial_tag, CoordSys1, CoordSys2, 3, 3, P1, P2>
+{
+ typedef from_cartesian_3_to_spherical_equatorial_3<P1, P2> type;
+};
 
 
 } // namespace services

Modified: branches/release/boost/geometry/util/math.hpp
==============================================================================
--- branches/release/boost/geometry/util/math.hpp (original)
+++ branches/release/boost/geometry/util/math.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -44,11 +44,43 @@
 template <typename Type>
 struct equals<Type, true>
 {
+ static inline Type get_max(Type const& a, Type const& b, Type const& c)
+ {
+ return (std::max)((std::max)(a, b), c);
+ }
+
     static inline bool apply(Type const& a, Type const& b)
     {
+ if (a == b)
+ {
+ return true;
+ }
+
         // See http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17,
         // FUTURE: replace by some boost tool or boost::test::close_at_tolerance
- return std::abs(a - b) <= std::numeric_limits<Type>::epsilon() * std::abs(a);
+ return std::abs(a - b) <= std::numeric_limits<Type>::epsilon() * get_max(std::abs(a), std::abs(b), 1.0);
+ }
+};
+
+template <typename Type, bool IsFloatingPoint>
+struct smaller
+{
+ static inline bool apply(Type const& a, Type const& b)
+ {
+ return a < b;
+ }
+};
+
+template <typename Type>
+struct smaller<Type, true>
+{
+ static inline bool apply(Type const& a, Type const& b)
+ {
+ if (equals<Type, true>::apply(a, b))
+ {
+ return false;
+ }
+ return a < b;
     }
 };
 
@@ -116,6 +148,28 @@
>::apply(a, b);
 }
 
+template <typename T1, typename T2>
+inline bool smaller(T1 const& a, T2 const& b)
+{
+ typedef typename select_most_precise<T1, T2>::type select_type;
+ return detail::smaller
+ <
+ select_type,
+ boost::is_floating_point<select_type>::type::value
+ >::apply(a, b);
+}
+
+template <typename T1, typename T2>
+inline bool larger(T1 const& a, T2 const& b)
+{
+ typedef typename select_most_precise<T1, T2>::type select_type;
+ return detail::smaller
+ <
+ select_type,
+ boost::is_floating_point<select_type>::type::value
+ >::apply(b, a);
+}
+
 
 
 double const d2r = geometry::math::pi<double>() / 180.0;

Modified: branches/release/libs/geometry/doc/acknowledgments.qbk
==============================================================================
--- branches/release/libs/geometry/doc/acknowledgments.qbk (original)
+++ branches/release/libs/geometry/doc/acknowledgments.qbk 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -28,6 +28,9 @@
 or at osgeo) about __boost_geometry__, in preview stage, or in review stage,
 or after that.
 
+Furthermore we are thankful to people supplying patches: Arnold Metselaar,
+Aleksey Tulinov, Christophe Henry
+
 Finally I (Barend) would like to thank my former employer, Geodan. They
 allowed me to start a geographic library in 1995, which after a number of
 incarnations, redesigns, refactorings, previews, a review and even more

Modified: branches/release/libs/geometry/doc/release_notes.qbk
==============================================================================
--- branches/release/libs/geometry/doc/release_notes.qbk (original)
+++ branches/release/libs/geometry/doc/release_notes.qbk 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -13,6 +13,34 @@
 [section:release_notes Release Notes]
 
 [/=================]
+[heading Boost 1.50]
+[/=================]
+
+[*Breaking changes]
+
+[*Bugfixes]
+* the return type of comparable projected point strategy for integer points was wrong (integer), fixed
+* several robustness issues in intersection of segments and polygons, fixed
+* invalid intersection output is filtered out
+* disjoint for multi_polygon's might incorrectly return true, fixed
+
+[*Solved tickets]
+
+* [@https://svn.boost.org/trac/boost/ticket/6585 6585] patch for alternative syntax multipoint, applied
+* [@https://svn.boost.org/trac/boost/ticket/6584 6584] patch for bug in distance, applied
+* [@https://svn.boost.org/trac/boost/ticket/5730 5730] same issue as 6584, fixed
+* [@https://svn.boost.org/trac/boost/ticket/6166 6166] patch for missing transformation, applied
+* [@https://svn.boost.org/trac/boost/ticket/6696 6696] invalid intersection output, was (by chance) already fixed in Trunk before reported
+
+[*Additional functionality]
+* added algorithm "touches" (OGC SF compliant) for *polygon/*polygon
+
+[*Documentation]
+
+[*Internal changes]
+
+
+[/=================]
 [heading Boost 1.49]
 [/=================]
 

Modified: branches/release/libs/geometry/example/Jamfile.v2
==============================================================================
--- branches/release/libs/geometry/example/Jamfile.v2 (original)
+++ branches/release/libs/geometry/example/Jamfile.v2 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -29,6 +29,7 @@
 exe c03_custom_linestring_example : c03_custom_linestring_example.cpp ;
 exe c04_a_custom_triangle_example : c04_a_custom_triangle_example.cpp ;
 exe c04_b_custom_triangle_example : c04_b_custom_triangle_example.cpp ;
+exe c05_custom_point_pointer_example : c05_custom_point_pointer_example.cpp ;
 exe c06_custom_polygon_example : c06_custom_polygon_example.cpp ;
 exe c07_custom_ring_pointer_example : c07_custom_ring_pointer_example.cpp ;
 exe c08_custom_non_std_example : c08_custom_non_std_example.cpp ;

Modified: branches/release/libs/geometry/test/algorithms/Jamfile.v2
==============================================================================
--- branches/release/libs/geometry/test/algorithms/Jamfile.v2 (original)
+++ branches/release/libs/geometry/test/algorithms/Jamfile.v2 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -35,6 +35,7 @@
     [ run perimeter.cpp ]
     [ run reverse.cpp ]
     [ run simplify.cpp ]
+ [ run touches.cpp ]
     [ run transform.cpp ]
     [ run union.cpp ]
     [ run unique.cpp ]

Modified: branches/release/libs/geometry/test/algorithms/algorithms_tests.sln
==============================================================================
--- branches/release/libs/geometry/test/algorithms/algorithms_tests.sln (original)
+++ branches/release/libs/geometry/test/algorithms/algorithms_tests.sln 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -58,6 +58,8 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "covered_by", "covered_by.vcproj", "{5ABF0B56-F9F1-4D93-B15A-E3972F45D97B}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "touches", "touches.vcproj", "{8359726E-9F03-4300-8F63-1FEAC84251D0}"
+EndProject
 Global
         GlobalSection(SolutionConfigurationPlatforms) = preSolution
                 Debug|Win32 = Debug|Win32
@@ -180,6 +182,10 @@
                 {5ABF0B56-F9F1-4D93-B15A-E3972F45D97B}.Debug|Win32.Build.0 = Debug|Win32
                 {5ABF0B56-F9F1-4D93-B15A-E3972F45D97B}.Release|Win32.ActiveCfg = Release|Win32
                 {5ABF0B56-F9F1-4D93-B15A-E3972F45D97B}.Release|Win32.Build.0 = Release|Win32
+ {8359726E-9F03-4300-8F63-1FEAC84251D0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8359726E-9F03-4300-8F63-1FEAC84251D0}.Debug|Win32.Build.0 = Debug|Win32
+ {8359726E-9F03-4300-8F63-1FEAC84251D0}.Release|Win32.ActiveCfg = Release|Win32
+ {8359726E-9F03-4300-8F63-1FEAC84251D0}.Release|Win32.Build.0 = Release|Win32
         EndGlobalSection
         GlobalSection(SolutionProperties) = preSolution
                 HideSolutionNode = FALSE

Modified: branches/release/libs/geometry/test/algorithms/difference.cpp
==============================================================================
--- branches/release/libs/geometry/test/algorithms/difference.cpp (original)
+++ branches/release/libs/geometry/test/algorithms/difference.cpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -7,6 +7,8 @@
 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 
+#define TEST_ISOVIST
+
 //#define BOOST_GEOMETRY_CHECK_WITH_POSTGIS
 
 //#define BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER
@@ -258,12 +260,17 @@
     ***/
 
 #ifdef _MSC_VER
- // Isovist (submitted by Brandon during Formal Review)
+#ifdef TEST_ISOVIST
     test_one<polygon, polygon, polygon>("isovist",
         isovist1[0], isovist1[1],
- 4, 0, 0.279121891701124,
- 4, 0, 224.889211358929,
- 0.01);
+ if_typed_tt<ct>(4, 2), 0, 0.279121891701124,
+ if_typed_tt<ct>(4, 3), 0, if_typed_tt<ct>(224.889211358929, 223.777),
+ if_typed_tt<ct>(0.001, 0.2));
+
+ // SQL Server gives: 0.279121891701124 and 224.889211358929
+ // PostGIS gives: 0.279121991127244 and 224.889205853156
+
+#endif
 
     test_one<polygon, polygon, polygon>("ggl_list_20110306_javier",
         ggl_list_20110306_javier[0], ggl_list_20110306_javier[1],
@@ -277,11 +284,14 @@
         1, 0, 3200.4,
         0.01);
 
- test_one<polygon, polygon, polygon>("ggl_list_20110716_enrico",
- ggl_list_20110716_enrico[0], ggl_list_20110716_enrico[1],
- 3, 0, 35723.8506317139,
- 1, 0, 58456.4964294434
- );
+ if (! boost::is_same<ct, float>::value)
+ {
+ test_one<polygon, polygon, polygon>("ggl_list_20110716_enrico",
+ ggl_list_20110716_enrico[0], ggl_list_20110716_enrico[1],
+ 3, 0, 35723.8506317139,
+ 1, 0, 58456.4964294434
+ );
+ }
 
     test_one<polygon, polygon, polygon>("ggl_list_20110820_christophe",
         ggl_list_20110820_christophe[0], ggl_list_20110820_christophe[1],
@@ -300,7 +310,7 @@
     // Because we cannot predict this, we only test for MSVC
     test_one<polygon, polygon, polygon>("ggl_list_20110627_phillip",
         ggl_list_20110627_phillip[0], ggl_list_20110627_phillip[1],
- if_typed<ct, double>(0, 1), 0,
+ if_typed_tt<ct>(1, 0), 0,
             if_typed_tt<ct>(0.0000000000001105367, 0.0),
         1, 0, 3577.40960816756,
         0.01
@@ -465,6 +475,7 @@
     test_all<bg::model::d2::point_xy<float> >();
 
 #ifdef HAVE_TTMATH
+ std::cout << "Testing TTMATH" << std::endl;
     test_all<bg::model::d2::point_xy<ttmath_big> >();
     //test_difference_parcel_precision<ttmath_big>();
 #endif

Modified: branches/release/libs/geometry/test/algorithms/disjoint.cpp
==============================================================================
--- branches/release/libs/geometry/test/algorithms/disjoint.cpp (original)
+++ branches/release/libs/geometry/test/algorithms/disjoint.cpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -113,6 +113,12 @@
     test_disjoint<segment, segment>("s/s 1", "linestring(0 0,1 1)", "linestring(1 0,0 1)", false);
     test_disjoint<segment, segment>("s/s 2", "linestring(0 0,1 1)", "linestring(1 0,2 1)", true);
 
+ // Collinear opposite
+ test_disjoint<ls, ls>("ls/ls co", "linestring(0 0,2 2)", "linestring(1 1,0 0)", false);
+ // Collinear opposite and equal
+ test_disjoint<ls, ls>("ls/ls co-e", "linestring(0 0,1 1)", "linestring(1 1,0 0)", false);
+
+
     // Degenerate linestrings
     {
         // Submitted by Zachary on the Boost.Geometry Mailing List, on 2012-01-29

Modified: branches/release/libs/geometry/test/algorithms/distance.cpp
==============================================================================
--- branches/release/libs/geometry/test/algorithms/distance.cpp (original)
+++ branches/release/libs/geometry/test/algorithms/distance.cpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -194,7 +194,11 @@
     test_geometry<P, P>("POINT(0 3)", "POINT(4 0)", 5.0);
     test_geometry<P, bg::model::linestring<P> >("POINT(1 3)", "LINESTRING(1 1,4 4)", sqrt(2.0));
     test_geometry<P, bg::model::linestring<P> >("POINT(3 1)", "LINESTRING(1 1,4 4)", sqrt(2.0));
+ test_geometry<P, bg::model::linestring<P> >("POINT(50 50)", "LINESTRING(50 40, 40 50)", sqrt(50.0));
+ test_geometry<P, bg::model::linestring<P> >("POINT(50 50)", "LINESTRING(50 40, 40 50, 0 90)", sqrt(50.0));
     test_geometry<bg::model::linestring<P>, P>("LINESTRING(1 1,4 4)", "POINT(1 3)", sqrt(2.0));
+ test_geometry<bg::model::linestring<P>, P>("LINESTRING(50 40, 40 50)", "POINT(50 50)", sqrt(50.0));
+ test_geometry<bg::model::linestring<P>, P>("LINESTRING(50 40, 40 50, 0 90)", "POINT(50 50)", sqrt(50.0));
 
     // Rings
     test_geometry<P, bg::model::ring<P> >("POINT(1 3)", "POLYGON((1 1,4 4,5 0,1 1))", sqrt(2.0));

Modified: branches/release/libs/geometry/test/algorithms/intersection.cpp
==============================================================================
--- branches/release/libs/geometry/test/algorithms/intersection.cpp (original)
+++ branches/release/libs/geometry/test/algorithms/intersection.cpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -15,6 +15,9 @@
 #include <iostream>
 #include <string>
 
+#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
+#define TEST_ISOVIST
+
 //#define BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER
 //#define BOOST_GEOMETRY_DEBUG_INTERSECTION
 //#define BOOST_GEOMETRY_DEBUG_TRAVERSE
@@ -164,14 +167,17 @@
 
     typedef typename bg::coordinate_type<Polygon>::type ct;
 
+#ifdef TEST_ISOVIST
 #ifdef _MSC_VER
- // Isovist (submitted by Brandon during Formal Review)
     test_one<Polygon, Polygon, Polygon>("isovist",
         isovist1[0], isovist1[1],
- 1,
- if_typed<ct, float>(19, if_typed<ct, double>(20, 20)),
- 88.19203,
- if_typed<ct, float>(0.5, if_typed<ct, double>(0.1, 0.01)));
+ 1, 20, 88.19203,
+ if_typed_tt<ct>(0.01, 0.1));
+
+ // SQL Server gives: 88.1920416352664
+ // PostGIS gives: 88.19203677911
+
+#endif
 #endif
 
     //std::cout << typeid(ct).name() << std::endl;
@@ -191,13 +197,22 @@
         1, if_typed_tt<ct>(6, 5), 11151.6618);
 
 #ifdef _MSC_VER // gcc/linux behaves differently
- test_one<Polygon, Polygon, Polygon>("ggl_list_20110716_enrico",
- ggl_list_20110716_enrico[0], ggl_list_20110716_enrico[1],
- 3,
- if_typed<ct, float>(19, if_typed<ct, double>(22, 21)),
- 35723.8506317139);
+ if (! boost::is_same<ct, float>::value)
+ {
+ test_one<Polygon, Polygon, Polygon>("ggl_list_20110716_enrico",
+ ggl_list_20110716_enrico[0], ggl_list_20110716_enrico[1],
+ 3,
+ if_typed<ct, float>(19, if_typed<ct, double>(22, 21)),
+ 35723.8506317139);
+ }
 #endif
 
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_f", buffer_rt_f[0], buffer_rt_f[1],
+ 1, 4, 0.00029437899183903937, 0.01);
+
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_g", buffer_rt_g[0], buffer_rt_g[1],
+ 1, 0, 2.914213562373);
+
     return;
 
 
@@ -496,6 +511,7 @@
     test_all<bg::model::d2::point_xy<float> >();
 
 #if defined(HAVE_TTMATH)
+ std::cout << "Testing TTMATH" << std::endl;
     test_all<bg::model::d2::point_xy<ttmath_big> >();
 #endif
 

Modified: branches/release/libs/geometry/test/algorithms/overlay/get_turn_info.cpp
==============================================================================
--- branches/release/libs/geometry/test/algorithms/overlay/get_turn_info.cpp (original)
+++ branches/release/libs/geometry/test/algorithms/overlay/get_turn_info.cpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -807,14 +807,12 @@
             4, 3, 2, 3, 0, 3, // q
             method_touch, 2, 3, "xx");
 
- /***
- TODO, work this out further / check this
- // Case where
- test_both<P, double>("issue_buffer_mill",
- 5.1983614873206241 , 6.7259025813913107 , 5.0499999999999998 , 6.4291796067500622 , 5.1983614873206241 , 6.7259025813913107, // p
- 5.0499999999999998 , 6.4291796067500622 , 5.0499999999999998 , 6.4291796067500622 , 5.1983614873206241 , 6.7259025813913107, // q
- method_collinear, 2, 0, "tt");
- ***/
+ // BSG 2012-05-26 to be decided what's the problem here and what it tests...
+ // Anyway, test results are not filled out.
+ //test_both<P, double>("issue_buffer_mill",
+ // 5.1983614873206241 , 6.7259025813913107 , 5.0499999999999998 , 6.4291796067500622 , 5.1983614873206241 , 6.7259025813913107, // p
+ // 5.0499999999999998 , 6.4291796067500622 , 5.0499999999999998 , 6.4291796067500622 , 5.1983614873206241 , 6.7259025813913107, // q
+ // method_collinear, 2, 0, "tt");
 
 }
 

Modified: branches/release/libs/geometry/test/algorithms/overlay/get_turns.cpp
==============================================================================
--- branches/release/libs/geometry/test/algorithms/overlay/get_turns.cpp (original)
+++ branches/release/libs/geometry/test/algorithms/overlay/get_turns.cpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -54,7 +54,7 @@
 {
     template<typename G1, typename G2>
     static void apply(std::string const& id,
- int expected_count,
+ std::size_t expected_count,
             G1 const& g1, G2 const& g2, double precision)
     {
             typedef bg::detail::overlay::turn_info
@@ -133,7 +133,7 @@
 template<typename G1, typename G2>
 struct test_get_turns
 {
- inline static void apply(std::string const& id, int expected_count,
+ inline static void apply(std::string const& id, std::size_t expected_count,
                 std::string const& wkt1, std::string const& wkt2,
                 double precision = 0.001)
     {

Modified: branches/release/libs/geometry/test/algorithms/overlay/overlay_cases.hpp
==============================================================================
--- branches/release/libs/geometry/test/algorithms/overlay/overlay_cases.hpp (original)
+++ branches/release/libs/geometry/test/algorithms/overlay/overlay_cases.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -480,6 +480,7 @@
     "POLYGON((184861.118 606901.158,184893.787 606898.483,184925.043 606913.4,184927.174 606951.759,184912.9 606987.146,184877.87 606989.232,184885.103 607023.774,184899.058 607022.743,184906.008 607044.948,184966.465 607025.02,184968.442 606961.3,185024.768 606947.402,185024.544 606941.355,185027.007 606937.323,185030.366 606934.187,185035.516 606933.963,185040.442 606935.531,185042.905 606939.115,185088.364 606931.385,185089.139 607015.509,185095.2 607011.3,185118.827 606995.545,185126.813 606991.995,185177.727 606973.799,185181.482 606966.676,185193.571 606977.795,185193.711 606960.3,185189.352 606779.02,185167.515 606783.844,185086.96 606801.241,185011.707 606817.809,185000 606819.304,184994.034 606819.794,184976.398 606819.572,184956.654 606817.131,184934.913 606813.137,184893.097 606804.927,184884.445 606831.555,184866.919 606883.481,184861.118 606901.158),(184907.556 607013.301,184905.782 607009.972,184906.004 607005.978,184908.444 606998.877,184912.215 606994.218,184919.314 606993.996,184922.42 6069
95.771,184925.747 606998.877,184926.413 607002.872,184925.747 607007.753,184922.42 607012.191,184917.096 607015.298,184911.771 607015.298,184907.556 607013.301))"};
 
 
+// Isovist (submitted by Brandon during Formal Review)
 static std::string isovist[2] =
     {
     "POLYGON((37.29449462890625 1.7902572154998779, 46.296027072709599 -2.4984308554828116, 45.389434814453125 -4.5143837928771973, 47.585065917176543 -6.1314922196594779, 46.523914387974358 -8.5152102535033496, 42.699958801269531 -4.4278755187988281, 42.577877044677734 -4.4900407791137695, 42.577911376953125 -4.4901103973388672, 40.758884429931641 -5.418975830078125, 40.6978759765625 -5.4500408172607422, 41.590042114257813 -7.2021245956420898, 57.297810222148939 -37.546793343968417, 50.974888957147442 -30.277285722290763, 37.140213012695313 1.3446992635726929, 37.000419616699219 1.664225697517395, 37.29449462890625 1.7902572154998779))",
@@ -559,5 +560,99 @@
     "POLYGON((-95269304 222758,-95260668 419862,-95234760 615696,-95192088 808228,-95132906 996442,-95057214 1178814,-94966028 1354074,-94860110 1520444,-94739968 1676908,-94606618 1822450,-94999048 2214880,-95165164 2033778,-95314770 1838706,-95446850 1631442,-95560388 1413510,-95654368 1186434,-95728282 951992,-95781368 711962,-95813626 468376,-95824294 222758,-95269304 222758))"
     };
 
+static std::string ggl_list_20120229_volker[3] =
+ {
+ "POLYGON((1716 1554,2076 2250,2436 2352,2796 1248,3156 2484,3516 2688,3516 2688,3156 2484,2796 1248,2436 2352,2076 2250, 1716 1554))",
+ "POLYGON((2500 1600,2500 2300,3200 2300,3200 1600,2500 1600))",
+ "POLYGON((1716 1554,2076 2250,2436 2352,2796 1248,3156 2484,3516 2688,3156 2483,2796 1247,2436 2351,2076 2249, 1716 1554))",
+ };
+
+static std::string buffer_rt_a[2] =
+ {
+ "POLYGON((1 7,1 8,1.0012 8.04907,1.00482 8.09802,1.01082 8.14673,1.01921 8.19509,1.02997 8.24298,1.04306 8.29028,1.05846 8.33689,1.07612 8.38268,1.09601 8.42756,1.11808 8.4714,1.14227 8.5141,1.16853 8.55557,1.19679 8.5957,1.22699 8.63439,1.25905 8.67156,1.29289 8.70711,1.32844 8.74095,1.36561 8.77301,1.4043 8.80321,1.44443 8.83147,1.4859 8.85773,1.5286 8.88192,1.57244 8.90399,1.61732 8.92388,1.66311 8.94154,1.70972 8.95694,1.75702 8.97003,1.80491 8.98079,1.85327 8.98918,1.90198 8.99518,1.95093 8.9988,2 9,3 9,3.04907 8.9988,3.09802 8.99518,3.14673 8.98918,3.19509 8.98079,3.24298 8.97003,3.29028 8.95694,3.33689 8.94154,3.38268 8.92388,3.42756 8.90399,3.4714 8.88192,3.5141 8.85773,3.55557 8.83147,3.5957 8.80321,3.63439 8.77301,3.67156 8.74095,3.70711 8.70711,3.74095 8.67156,3.77301 8.63439,3.80321 8.5957,3.83147 8.55557,3.85773 8.5141,3.88192 8.4714,3.90399 8.42756,3.92388 8.38268,3.94154 8.33689,3.95694 8.29028,3.97003 8.24298,3.98079 8.19509,3.98918 8.14673,3.99518 8.09802,3.9988 8.04907,4 8,4 7,3.9988 6
.95093,3.99518 6.90198,3.98918 6.85327,3.98079 6.80491,3.97003 6.75702,3.95694 6.70972,3.94154 6.66311,3.92388 6.61732,3.90399 6.57244,3.88192 6.5286,3.85773 6.4859,3.83147 6.44443,3.80321 6.4043,3.77301 6.36561,3.74095 6.32844,3.70711 6.29289,3.67156 6.25905,3.63439 6.22699,3.5957 6.19679,3.55557 6.16853,3.5141 6.14227,3.4714 6.11808,3.42756 6.09601,3.38268 6.07612,3.33689 6.05846,3.29028 6.04306,3.24298 6.02997,3.19509 6.01921,3.14673 6.01082,3.09802 6.00482,3.04907 6.0012,3 6,2 6,1.95093 6.0012,1.90198 6.00482,1.85327 6.01082,1.80491 6.01921,1.75702 6.02997,1.70972 6.04306,1.66311 6.05846,1.61732 6.07612,1.57244 6.09601,1.5286 6.11808,1.4859 6.14227,1.44443 6.16853,1.4043 6.19679,1.36561 6.22699,1.32844 6.25905,1.29289 6.29289,1.25905 6.32844,1.22699 6.36561,1.19679 6.4043,1.16853 6.44443,1.14227 6.4859,1.11808 6.5286,1.09601 6.57244,1.07612 6.61732,1.05846 6.66311,1.04306 6.70972,1.02997 6.75702,1.01921 6.80491,1.01082 6.85327,1.00482 6.90198,1.0012 6.95093,1 7))",
+ "POLYGON((3 6,4 6,4.04907 5.9988,4.09802 5.99518,4.14673 5.98918,4.19509 5.98079,4.24298 5.97003,4.29028 5.95694,4.33689 5.94154,4.38268 5.92388,4.42756 5.90399,4.4714 5.88192,4.5141 5.85773,4.55557 5.83147,4.5957 5.80321,4.63439 5.77301,4.67156 5.74095,4.70711 5.70711,4.74095 5.67156,4.77301 5.63439,4.80321 5.5957,4.83147 5.55557,4.85773 5.5141,4.88192 5.4714,4.90399 5.42756,4.92388 5.38268,4.94154 5.33689,4.95694 5.29028,4.97003 5.24298,4.98079 5.19509,4.98918 5.14673,4.99518 5.09802,4.9988 5.04907,5 5,5 4,4.9988 3.95093,4.99518 3.90198,4.98918 3.85327,4.98079 3.80491,4.97003 3.75702,4.95694 3.70972,4.94154 3.66311,4.92388 3.61732,4.90399 3.57244,4.88192 3.5286,4.85773 3.4859,4.83147 3.44443,4.80321 3.4043,4.77301 3.36561,4.74095 3.32844,4.70711 3.29289,4.67156 3.25905,4.63439 3.22699,4.5957 3.19679,4.55557 3.16853,4.5141 3.14227,4.4714 3.11808,4.42756 3.09601,4.38268 3.07612,4.33689 3.05846,4.29028 3.04306,4.24298 3.02997,4.19509 3.01921,4.14673 3.01082,4.09802 3.00482,4.04907 3.0012,4 3,3 3,3 3,2 3,
1.95093 3.0012,1.90198 3.00482,1.85327 3.01082,1.80491 3.01921,1.75702 3.02997,1.70972 3.04306,1.66311 3.05846,1.61732 3.07612,1.57244 3.09601,1.5286 3.11808,1.4859 3.14227,1.44443 3.16853,1.4043 3.19679,1.36561 3.22699,1.32844 3.25905,1.29289 3.29289,1.25905 3.32844,1.22699 3.36561,1.19679 3.4043,1.16853 3.44443,1.14227 3.4859,1.11808 3.5286,1.09601 3.57244,1.07612 3.61732,1.05846 3.66311,1.04306 3.70972,1.02997 3.75702,1.01921 3.80491,1.01082 3.85327,1.00482 3.90198,1.0012 3.95093,1 4,1 5,1.0012 5.04907,1.00482 5.09802,1.01082 5.14673,1.01921 5.19509,1.02997 5.24298,1.04306 5.29028,1.05846 5.33689,1.07612 5.38268,1.09601 5.42756,1.11808 5.4714,1.14227 5.5141,1.16853 5.55557,1.19679 5.5957,1.22699 5.63439,1.25905 5.67156,1.29289 5.70711,1.32844 5.74095,1.36561 5.77301,1.4043 5.80321,1.44443 5.83147,1.4859 5.85773,1.5286 5.88192,1.57244 5.90399,1.61732 5.92388,1.66311 5.94154,1.70972 5.95694,1.75702 5.97003,1.80491 5.98079,1.85327 5.98918,1.90198 5.99518,1.95093 5.9988,2 6,3 6,3 6,3 6,3 6,3 6,3 6,3 6,3 6,3 6
,3 6,3 6,3 6,3 6,3 6,3 6,3 6,3 6,3 6,3 6,3 6,3 6,3 6,3 6,3 6,3 6,3 6,3 6,3 6,3 6,3 6,3 6,3 6,3 6))"
+ };
+
+static std::string buffer_rt_f[2] =
+ {
+ "POLYGON((-0.29999999999999999 6.0000000000000000,-0.29999999999999999 7.0000000000000000,-0.30000000000000027 7.7242640687119302,0.21213203435596423 7.2121320343559638,1.2121320343559643 6.2121320343559638,1.7242640687119293 5.7000000000000002,1.0000000000000000 5.7000000000000002,0.00000000000000000 5.7000000000000002,-0.30000000000000027 5.7000000000000002,-0.29999999999999999 6.0000000000000000))",
+ "POLYGON((1.3000000000000000 9.0000000000000000,1.3000000000000000 8.0000000000000000,1.3000000000000007 7.7000000000000002,1.0000000000000000 7.7000000000000002,0.00000000000000000 7.7000000000000002,-0.29999999999999982 7.7000000000000002,-0.29999999999999999 8.0000000000000000,-0.29999999999999999 9.0000000000000000,-0.29999999999999982 9.3000000000000007,0.00000000000000000 9.3000000000000007,1.0000000000000000 9.3000000000000007,1.3000000000000007 9.3000000000000007,1.3000000000000000 9.0000000000000000))"
+ };
+
+static std::string buffer_rt_g[2] =
+ {
+ "POLYGON((2.0 8.0,2.0 9.0,2.0 10.0,3.0 10.0,4.0 10.0,6.4142135623730958 10.0,4.7071067811865479 8.2928932188134521,3.7071067811865475 7.2928932188134521,2.0 5.5857864376269051,2.0 8.0))",
+ "POLYGON((0.0 6.0,0.0 7.0,0.0 8.0,1.0 8.0,2.0 8.0,4.4142135623730958 8.0,2.7071067811865475 6.2928932188134521,1.7071067811865475 5.2928932188134521,-0.0 3.5857864376269042,0.0 6.0))"
+ };
+
+static std::string buffer_rt_g_boxes[5] =
+ {
+ "POLYGON((0 0,0 4,4 4,4 0,0 0))",
+ "POLYGON((2 2,2 4,6 4,6 2,2 2))",
+ "POLYGON((2 2,2 4,6 4,8 4,8 2,2 2))",
+ "POLYGON((2 2,2 4,6 4,6 6,8 6,8 2,2 2))",
+
+ "POLYGON((0 0,0 4,4 4,4 5,5 5,5 1,4 1,4 0,0 0))"
+ };
+
+// From buffer-robustness-test with segment-intersection "touching" with r ~ 1.16
+static std::string buffer_rt_i[2] =
+ {
+ "POLYGON((1.0 1.0,1.0 2.0,1.0 3.0,2.0 3.0,3.0 3.0,5.4142135623730949 3.0,3.7071067811865475 1.2928932188134525,2.7071067811865475 0.29289321881345254,1.0 -1.4142135623730949,1.0 1.0))",
+ "POLYGON((2.0 2.0,2.0 3.0,2.0 4.0,3.0 4.0,4.0 4.0,6.4142135623730958 4.0,4.7071067811865479 2.2928932188134525,3.7071067811865475 1.2928932188134525,2.0 -0.41421356237309387,2.0 2.0))"
+ };
+
+// Idem, but with a touch-in-the-middle
+static std::string buffer_rt_j[2] =
+ {
+ "POLYGON((1.0 4.0,1.0 5.0,1.0 6.0,2.0 6.0,3.0 6.0,5.4142135623730967 6.0,3.7071067811865475 4.2928932188134521,2.7071067811865475 3.2928932188134525,1.0 1.5857864376269055,1.0 4.0))",
+ "POLYGON((-1.0 2.0,-1.0 3.0,-1.0 4.0,0.00 4.0,1.0 4.0,3.4142135623730949 4.0,1.7071067811865475 2.2928932188134525,0.70710678118654746 1.2928932188134525,-1.0 -0.41421356237309492,-1.0 2.0))"
+ };
+
+// Nearly-collinear (two segments as-if meeting but not really)
+static std::string buffer_rt_l[2] =
+ {
+ "POLYGON((1.0 5.0,1.0 6.0,1.0 8.4142135623730958,2.7071067811865475 6.7071067811865479,3.7071067811865475 5.7071067811865479,5.4142135623730958 4.0,3.0 4.0,2.0 4.0,1.0 4.0,1.0 5.0))",
+ "POLYGON((5.0 1.0,5.0 2.0,5.0 4.4142135623730958,6.7071067811865479 2.7071067811865475,7.7071067811865479 1.7071067811865475,9.4142135623730958 0.00,7.0 0.0,6.0 0.0,5.0 0.0,5.0 1.0))"
+ };
+
+static std::string buffer_rt_m1[2] =
+ {
+ "POLYGON((3.0 2.0,3.0 3.0,3.0 5.4142135623730940,4.7071067811865479 3.7071067811865475,5.7071067811865479 2.7071067811865475,7.4142135623730940 1.0,5.0 1.0,4.0 1.0,3.0 1.0,3.0 2.0))",
+ "POLYGON((0.29289321881345254 2.7071067811865475,1.2928932188134525 3.7071067811865475,3.0 5.4142135623730949,3.0 3.0,3.0 2.0,3.0 1.0,2.0 1.0,1.0 1.0,-1.4142135623730949 1.0,0.29289321881345254 2.7071067811865475))"
+ };
+
+static std::string buffer_rt_m2[2] =
+ {
+ "POLYGON((-0.70710678118654746 3.7071067811865475,0.29289321881345254 4.7071067811865479,2.0 6.4142135623730967,2.0 4.0,2.0 3.0,2.0 2.0,1.0 2.0,0.00 2.0,-2.4142135623730949 2.0,-0.70710678118654746 3.7071067811865475))",
+ "POLYGON((2.2928932188134525 6.7071067811865479,3.2928932188134525 7.7071067811865479,5.0 9.4142135623730958,5.0 7.0,5.0 6.0,5.0 6.0,5.0 5.0,5.0 4.0,4.0 4.0,3.0 4.0,2.0 4.0,2.0 5.0,2.0 6.0,2.0 6.4142135623730958,2.2928932188134525 6.7071067811865479))"
+ };
+
+
+static std::string buffer_rt_n[2] =
+ {
+ "POLYGON((-0.70710678118654746 0.70710678118654746,0.29289321881345254 1.7071067811865475,2.0 3.4142135623730949,2.0 1.0,2.0 0.0,2.0 -1.0,1.0 -1.0,0.00 -1.0,-2.4142135623730949 -1.0,-0.70710678118654746 0.70710678118654746))",
+ "POLYGON((2.2928932188134525 3.7071067811865475,3.2928932188134525 4.7071067811865479,5.0 6.4142135623730958,5.0 4.0,5.0 3.0,5.0 2.0,4.0 2.0,3.0 2.0,0.58578643762690574 2.0,2.2928932188134525 3.7071067811865475))"
+ };
+
+static std::string buffer_rt_q[2] =
+ {
+ "POLYGON((6.0 6.0,7.0 6.0,9.4142135623730958 6.0,7.7071067811865479 4.2928932188134521,6.7071067811865479 3.2928932188134525,6.4142135623730949 3.0,6.0 3.0,5.0 3.0,4.0 3.0,4.0 4.0,4.0 5.0,4.0 6.0,5.0 6.0,6.0 6.0))",
+ "POLYGON((3.0 2.0,3.0 3.0,3.0 4.0,4.0 4.0,5.0 4.0,7.4142135623730958 4.0,5.7071067811865479 2.2928932188134525,4.7071067811865479 1.2928932188134525,3.0 -0.41421356237309581,3.0 2.0))"
+ };
+
+static std::string buffer_rt_r[2] =
+ {
+ "POLYGON((3.7071067811865475 0.29289321881345254,2.7071067811865475 -0.70710678118654746,2.0 -1.4142135623730949,1.2928932188134525 -0.70710678118654746,0.29289321881345254 0.29289321881345254,-0.41421356237309492 1.0,0.29289321881345254 1.7071067811865475,1.2928932188134525 2.7071067811865475,2.0000000000000004 3.4142135623730954,2.7071067811865475 2.7071067811865475,3.7071067811865475 1.7071067811865475,4.4142135623730958 1.0000000000000004,3.7071067811865475 0.29289321881345254))",
+ "POLYGON((5.7071067811865479 2.2928932188134525,4.7071067811865479 1.2928932188134525,4.4142135623730958 1.0,4.0 1.0,3.0 1.0,1.3819660112501053 1.0,2.1055728090000843 2.4472135954999579,3.1055728090000843 4.4472135954999583,3.7260485282911020 5.6881650340819956,4.7071067811865479 4.7071067811865479,5.7071067811865479 3.7071067811865475,6.4142135623730958 3.0,5.7071067811865479 2.2928932188134525))"
+ };
+
+
+static std::string buffer_rt_t[2] =
+ {
+ "POLYGON((0.00000000000000000 3.0,0.00000000000000000 4.0,0.00000000000000000 6.4142135623730958,1.7071067811865475 4.7071067811865479,2.7071067811865475 3.7071067811865475,4.4142135623730940 2.0,2.0 2.0,1.0 2.0,-0.00000000000000000 2.0,0.00000000000000000 3.0))",
+ "POLYGON((1.7071067811865475 3.2928932188134525,0.70710678118654746 2.2928932188134525,-1.0 0.58578643762690508,-1.0 3.0,-1.0 4.0,-1.0 4.0,-1.0 5.0,-1.0 7.4142135623730958,0.70710678118654746 5.7071067811865479,1.7071067811865475 4.7071067811865479,2.4142135623730954 4.0,1.7071067811865475 3.2928932188134525))"
+ };
+
 
 #endif // BOOST_GEOMETRY_TEST_OVERLAY_CASES_HPP

Modified: branches/release/libs/geometry/test/algorithms/overlay/robustness/test_overlay_p_q.hpp
==============================================================================
--- branches/release/libs/geometry/test/algorithms/overlay/robustness/test_overlay_p_q.hpp (original)
+++ branches/release/libs/geometry/test/algorithms/overlay/robustness/test_overlay_p_q.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -31,6 +31,8 @@
 #include <boost/geometry/extensions/io/svg/svg_mapper.hpp>
 
 #include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
+#include <boost/geometry/algorithms/intersects.hpp>
+#include <boost/geometry/algorithms/touches.hpp>
 
 struct p_q_settings
 {
@@ -103,6 +105,19 @@
         }
     }
 
+ if (true)
+ {
+ if ((area_i > 0 && bg::touches(p, q))
+ || (area_i <= 0 && bg::intersects(p, q) && ! bg::touches(p, q)))
+ {
+ std::cout << "Wrong 'touch'! "
+ << " Intersection area: " << area_i
+ << " Touch gives: " << std::boolalpha << bg::touches(p, q)
+ << std::endl;
+ wrong = true;
+ }
+ }
+
     bool svg = settings.svg;
 
     if (wrong || settings.wkt)

Modified: branches/release/libs/geometry/test/algorithms/overlay/traverse.cpp
==============================================================================
--- branches/release/libs/geometry/test/algorithms/overlay/traverse.cpp (original)
+++ branches/release/libs/geometry/test/algorithms/overlay/traverse.cpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -7,6 +7,9 @@
 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 
+#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
+// #define BOOST_GEOMETRY_OVERLAY_NO_THROW
+// #define TEST_WITH_SVG
 
 #include <iostream>
 #include <iomanip>
@@ -83,7 +86,7 @@
 {
 
     static void apply(std::string const& id,
- int expected_count, double expected_area,
+ std::size_t expected_count, double expected_area,
             G1 const& g1, G2 const& g2,
             double precision)
     {
@@ -353,7 +356,7 @@
             G1, G2, Direction, Reverse1, Reverse2
> detail_test_traverse;
 
- inline static void apply(std::string const& id, int expected_count, double expected_area,
+ inline static void apply(std::string const& id, std::size_t expected_count, double expected_area,
                 std::string const& wkt1, std::string const& wkt2,
                 double precision = 0.001)
     {
@@ -823,22 +826,11 @@
     }
 
     {
- // Note: values are checked with SQL Server,
- /*
- select geometry::STGeomFromText('POLYGON((...))', 0)
- .STIntersection(geometry::STGeomFromText('...))', 0))
- .STArea()
-
- and STUnion
- */
-
- // Boost.List during Formal Review, isovists Brandon
- // For FP, they may deviate more.
         test_traverse<polygon, polygon, operation_intersection>::apply("isov",
- 1, 88.1920416352664, isovist[0], isovist[1],
+ 1, 88.1920, isovist[0], isovist[1],
                 float_might_deviate_more);
         test_traverse<polygon, polygon, operation_union>::apply("isov",
- 1, 313.360374193241, isovist[0], isovist[1],
+ 1, 313.3604, isovist[0], isovist[1],
                 float_might_deviate_more);
     }
 
@@ -907,6 +899,51 @@
             1, 67.3550722317627,
             ggl_list_20110820_christophe[0], ggl_list_20110820_christophe[1]);
     }
+
+ test_traverse<polygon, polygon, operation_union>::apply("buffer_rt_f",
+ 1, 4.60853,
+ buffer_rt_f[0], buffer_rt_f[1]);
+ test_traverse<polygon, polygon, operation_intersection>::apply("buffer_rt_f",
+ 1, 0.0002943725152286,
+ buffer_rt_f[0], buffer_rt_f[1]);
+
+ test_traverse<polygon, polygon, operation_union>::apply("buffer_rt_g",
+ 1, 16.571,
+ buffer_rt_g[0], buffer_rt_g[1]);
+
+ test_traverse<polygon, polygon, operation_union>::apply("buffer_rt_g_boxes1",
+ 1, 20,
+ buffer_rt_g_boxes[0], buffer_rt_g_boxes[1]);
+ test_traverse<polygon, polygon, operation_union>::apply("buffer_rt_g_boxes2",
+ 1, 24,
+ buffer_rt_g_boxes[0], buffer_rt_g_boxes[2]);
+ test_traverse<polygon, polygon, operation_union>::apply("buffer_rt_g_boxes3",
+ 1, 28,
+ buffer_rt_g_boxes[0], buffer_rt_g_boxes[3]);
+
+ test_traverse<polygon, polygon, operation_union>::apply("buffer_rt_g_boxes43",
+ 1, 30,
+ buffer_rt_g_boxes[4], buffer_rt_g_boxes[3]);
+
+#ifdef BOOST_GEOMETRY_OVERLAY_NO_THROW
+ {
+ // NOTE: currently throws (normally)
+ std::string caseid = "ggl_list_20120229_volker";
+ test_traverse<polygon, polygon, operation_union>::apply(caseid,
+ 1, 99,
+ ggl_list_20120229_volker[0], ggl_list_20120229_volker[1]);
+ test_traverse<polygon, polygon, operation_intersection>::apply(caseid,
+ 1, 99,
+ ggl_list_20120229_volker[0], ggl_list_20120229_volker[1]);
+ caseid = "ggl_list_20120229_volker_2";
+ test_traverse<polygon, polygon, operation_union>::apply(caseid,
+ 1, 99,
+ ggl_list_20120229_volker[2], ggl_list_20120229_volker[1]);
+ test_traverse<polygon, polygon, operation_intersection>::apply(caseid,
+ 1, 99,
+ ggl_list_20120229_volker[2], ggl_list_20120229_volker[1]);
+ }
+#endif
 }
 
 template <typename T>

Modified: branches/release/libs/geometry/test/algorithms/test_union.hpp
==============================================================================
--- branches/release/libs/geometry/test/algorithms/test_union.hpp (original)
+++ branches/release/libs/geometry/test/algorithms/test_union.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -38,7 +38,7 @@
 template <typename OutputType, typename G1, typename G2>
 void test_union(std::string const& caseid, G1 const& g1, G2 const& g2,
         std::size_t expected_count, std::size_t expected_hole_count,
- std::size_t expected_point_count, double expected_area,
+ int expected_point_count, double expected_area,
         double percentage)
 {
     typedef typename bg::coordinate_type<G1>::type coordinate_type;
@@ -90,13 +90,15 @@
         << std::endl;
     ***/
 
- BOOST_CHECK_MESSAGE(std::size_t(n) == expected_point_count,
- "union: " << caseid
- << " #points expected: " << expected_point_count
- << " detected: " << n
- << " type: " << string_from_type<coordinate_type>::name()
- );
-
+ if (expected_point_count >= 0)
+ {
+ BOOST_CHECK_MESSAGE(n == std::size_t(expected_point_count),
+ "union: " << caseid
+ << " #points expected: " << expected_point_count
+ << " detected: " << n
+ << " type: " << string_from_type<coordinate_type>::name()
+ );
+ }
 
     BOOST_CHECK_EQUAL(clip.size(), expected_count);
     BOOST_CHECK_EQUAL(holes, expected_hole_count);
@@ -149,7 +151,7 @@
 template <typename OutputType, typename G1, typename G2>
 void test_one(std::string const& caseid, std::string const& wkt1, std::string const& wkt2,
         std::size_t expected_count, std::size_t expected_hole_count,
- std::size_t expected_point_count, double expected_area,
+ int expected_point_count, double expected_area,
         double percentage = 0.001)
 {
     G1 g1;

Modified: branches/release/libs/geometry/test/algorithms/union.cpp
==============================================================================
--- branches/release/libs/geometry/test/algorithms/union.cpp (original)
+++ branches/release/libs/geometry/test/algorithms/union.cpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -15,6 +15,9 @@
 #include <iostream>
 #include <string>
 
+#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
+#define TEST_ISOVIST
+
 //#define BOOST_GEOMETRY_DEBUG_ASSEMBLE
 //#define BOOST_GEOMETRY_DEBUG_IDENTIFIER
 
@@ -229,24 +232,102 @@
         if_typed<ct, double>(5, if_typed_tt<ct>(8, 7)),
         14729.07145);
         
-#ifdef TEST_ENRICO
     test_one<Polygon, Polygon, Polygon>("ggl_list_20110716_enrico",
         ggl_list_20110716_enrico[0], ggl_list_20110716_enrico[1],
         1, 1,
- if_typed<ct, double>(18, 17),
+ if_typed<ct, double>(18, if_typed<ct, float>(15, 17)),
         129904.197692871);
-#endif
 
+ test_one<Polygon, Polygon, Polygon>("ggl_list_20110820_christophe",
+ ggl_list_20110820_christophe[0], ggl_list_20110820_christophe[1],
+ if_typed<ct, float>(2, 1),
+ 0,
+ if_typed_tt<ct>(9, 8),
+ 67.3550722317627);
+
+
+#ifdef TEST_ISOVIST
 #ifdef _MSC_VER
- // Isovist (submitted by Brandon during Formal Review)
     test_one<Polygon, Polygon, Polygon>("isovist",
         isovist1[0], isovist1[1],
         1,
         0,
- if_typed<ct, float>(71,
- if_typed<ct, double>(70, 73)),
- 313.36036462);
+ if_typed<ct, float>(71, if_typed<ct, double>(70, 73)),
+ 313.36036462, 0.1);
+
+ // SQL Server gives: 313.360374193241
+ // PostGIS gives: 313.360364623393
+
+#endif
 #endif
+
+ // Ticket 5103 https://svn.boost.org/trac/boost/ticket/5103
+ // This ticket was actually reported for Boost.Polygon
+ // We check it for Boost.Geometry as well.
+ // SQL Server gives: 2515271331437.69
+ // PostGIS gives: 2515271327070.52
+ // Boost.Geometry gives: 2515271327070.5237746891 (ttmath)
+ // 2515271327070.5156 (double)
+ // 2515271320603.0000 (int)
+ // Note the int-test was tested outside of this unit test. It is in two points 0.37 off (logical for an int).
+ // Because of the width of the polygon (400000 meter) this causes a substantial difference.
+
+ test_one<Polygon, Polygon, Polygon>("ticket_5103", ticket_5103[0], ticket_5103[1],
+ 1, 0, 25, 2515271327070.5);
+
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_a", buffer_rt_a[0], buffer_rt_a[1],
+ 1, 0, 265, 19.280667);
+
+ // Robustness issues, followed out buffer-robustness-tests, test them also reverse
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_f", buffer_rt_f[0], buffer_rt_f[1],
+ 1, 0, if_typed<ct, double>(22, 23), 4.60853);
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_f_rev", buffer_rt_f[1], buffer_rt_f[0],
+ 1, 0, if_typed<ct, double>(22, 23), 4.60853);
+
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_g", buffer_rt_g[0], buffer_rt_g[1],
+ 1, 0, 17, 16.571);
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_g_rev", buffer_rt_g[1], buffer_rt_g[0],
+ 1, 0, 17, 16.571);
+
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_i", buffer_rt_i[0], buffer_rt_i[1],
+ 1, 0, 13, 13.6569);
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_i_rev", buffer_rt_i[1], buffer_rt_i[0],
+ 1, 0, 13, 13.6569);
+
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_j", buffer_rt_j[0], buffer_rt_j[1],
+ 1, 0, -1, 16.5711);
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_j_rev", buffer_rt_j[1], buffer_rt_j[0],
+ 1, 0, -1, 16.5711);
+
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_l", buffer_rt_l[0], buffer_rt_l[1],
+ 1, 0, -1, 19.3995);
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_l_rev", buffer_rt_l[1], buffer_rt_l[0],
+ 1, 0, -1, 19.3995);
+
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_m1", buffer_rt_m1[0], buffer_rt_m1[1],
+ 1, 0, if_typed_tt<ct>(14, 13), 19.4852);
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_m1_rev", buffer_rt_m1[1], buffer_rt_m1[0],
+ 1, 0, if_typed_tt<ct>(14, 13), 19.4852);
+
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_m2", buffer_rt_m2[0], buffer_rt_m2[1],
+ 1, 0, if_typed_tt<ct>(20, 19), 21.4853);
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_m2_rev", buffer_rt_m2[1], buffer_rt_m2[0],
+ 1, 0, if_typed_tt<ct>(20, 19), 21.4853);
+
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_q", buffer_rt_q[0], buffer_rt_q[1],
+ 1, 0, if_typed<ct, float>(18, 17), 18.5710);
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_q_rev", buffer_rt_q[1], buffer_rt_q[0],
+ 1, 0, if_typed<ct, float>(18, 17), 18.5710);
+
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_r", buffer_rt_r[0], buffer_rt_r[1],
+ 1, 0, if_typed<ct, float>(19, 20), 21.07612);
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_r_rev", buffer_rt_r[1], buffer_rt_r[0],
+ 1, 0, if_typed_tt<ct>(20, 19), 21.07612);
+
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_t", buffer_rt_t[0], buffer_rt_t[1],
+ 1, 0, if_typed_tt<ct>(16, 14), 15.6569);
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_t_ref", buffer_rt_t[1], buffer_rt_t[0],
+ 1, 0, if_typed_tt<ct>(16, 14), 15.6569);
 }
 
 template <typename P>
@@ -258,6 +339,7 @@
 
     test_areal<ring, polygon>();
 
+#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
     // Open
     test_areal<bg::model::ring<P, true, false>, bg::model::polygon<P, true, false> >();
 
@@ -266,6 +348,7 @@
 
     // Counter clockwise and open
     test_areal<bg::model::ring<P, false, false>, bg::model::polygon<P, false, false> >();
+#endif
 
     test_one<polygon, box, polygon>("box_ring", example_box, example_ring,
         1, 1, 15, 6.38875);
@@ -302,32 +385,23 @@
     test_one<polygon, box, polygon>("box_poly8", "box(0 0, 3 3)",
             "POLYGON((2 2, 1 4, 2 4, 3 3, 2 2))",
                 1, 0, 8, 10.25);
-
- // Ticket 5103 https://svn.boost.org/trac/boost/ticket/5103
- // This ticket was actually reported for Boost.Polygon
- // but it is apparently a difficult case so we check it for Boost.Geometry as well.
- // SQL Server gives: 2515271331437.69
- // PostGIS gives: 2515271327070.52
- // Boost.Geometry gives: 2515271327070.5237746891 (ttmath)
- // 2515271327070.5156 (double)
- // 2515271320603.0000 (int)
- // Note the int-test was tested externally - it is in two points 0.37 off (makes sense).
- // Because of the width of the polygon (400000 meter) this might indeed cause a substantial difference.
-
- test_one<polygon, polygon, polygon>("ticket_5103", ticket_5103[0], ticket_5103[1],
- 1, 0, 25, 2515271327070.5);
 }
 
 
 int test_main(int, char* [])
 {
     test_all<bg::model::d2::point_xy<double> >();
+#if defined(HAVE_TTMATH)
+ std::cout << "Testing TTMATH" << std::endl;
+ test_all<bg::model::d2::point_xy<ttmath_big> >();
+#endif
 
 #if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
     test_all<bg::model::d2::point_xy<float> >();
     //test_all<bg::model::d2::point_xy<long double> >();
 
 #if defined(HAVE_TTMATH)
+ std::cout << "Testing TTMATH" << std::endl;
     test_all<bg::model::d2::point_xy<ttmath_big> >();
 #endif
 #endif

Modified: branches/release/libs/geometry/test/core/ring.cpp
==============================================================================
--- branches/release/libs/geometry/test/core/ring.cpp (original)
+++ branches/release/libs/geometry/test/core/ring.cpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -34,9 +34,9 @@
 
 template <typename P>
 void test_ring(std::string const& wkt,
- int expected_main_count,
- int expected_interior_ring_count,
- int expected_first_interior_count)
+ std::size_t expected_main_count,
+ std::size_t expected_interior_ring_count,
+ std::size_t expected_first_interior_count)
 {
     typedef bg::model::polygon<P> the_polygon;
     typedef typename bg::ring_type<the_polygon>::type the_ring;
@@ -48,7 +48,7 @@
     the_ring ext = bg::exterior_ring(poly);
     the_interior rings = bg::interior_rings(poly);
 
- BOOST_CHECK_EQUAL(bg::num_interior_rings(poly), std::size_t(expected_interior_ring_count));
+ BOOST_CHECK_EQUAL(bg::num_interior_rings(poly), expected_interior_ring_count);
     BOOST_CHECK_EQUAL(boost::size(rings), expected_interior_ring_count);
     BOOST_CHECK_EQUAL(boost::size(ext), expected_main_count);
     if (boost::size(rings))

Modified: branches/release/libs/geometry/test/geometries/adapted.cpp
==============================================================================
--- branches/release/libs/geometry/test/geometries/adapted.cpp (original)
+++ branches/release/libs/geometry/test/geometries/adapted.cpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -58,7 +58,7 @@
 // ----------------------------------------------------------------------------
 
 template <typename G>
-void test_geometry(G const& geometry, int expected_size = 0)
+void test_geometry(G const& geometry, std::size_t expected_size = 0)
 {
 #if defined(BOOST_GEOMETRY_TEST_RING)
     BOOST_CONCEPT_ASSERT( (bg::concept::ConstRing<G>) );

Modified: branches/release/libs/geometry/test/geometries/custom_linestring.cpp
==============================================================================
--- branches/release/libs/geometry/test/geometries/custom_linestring.cpp (original)
+++ branches/release/libs/geometry/test/geometries/custom_linestring.cpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -87,15 +87,15 @@
     typedef typename bg::point_type<G>::type P;
 
     bg::clear(geometry);
- BOOST_CHECK_EQUAL(boost::size(geometry), 0);
+ BOOST_CHECK_EQUAL(boost::size(geometry), 0u);
 
     bg::append(geometry, bg::make_zero<P>());
- BOOST_CHECK_EQUAL(boost::size(geometry), 1);
+ BOOST_CHECK_EQUAL(boost::size(geometry), 1u);
 
     //std::cout << geometry << std::endl;
 
     bg::clear(geometry);
- BOOST_CHECK_EQUAL(boost::size(geometry), 0);
+ BOOST_CHECK_EQUAL(boost::size(geometry), 0u);
 
 
     //P p = boost::range::front(geometry);

Modified: branches/release/libs/geometry/test/multi/algorithms/Jamfile.v2
==============================================================================
--- branches/release/libs/geometry/test/multi/algorithms/Jamfile.v2 (original)
+++ branches/release/libs/geometry/test/multi/algorithms/Jamfile.v2 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -17,6 +17,7 @@
     [ run multi_correct.cpp ]
     [ run multi_covered_by.cpp ]
     [ run multi_difference.cpp ]
+ [ run multi_disjoint.cpp ]
     [ run multi_distance.cpp ]
     [ run multi_envelope.cpp ]
     [ run multi_equals.cpp ]
@@ -29,6 +30,7 @@
     [ run multi_perimeter.cpp ]
     [ run multi_reverse.cpp ]
     [ run multi_simplify.cpp ]
+ [ run multi_touches.cpp ]
     [ run multi_transform.cpp ]
     [ run multi_union.cpp ]
     [ run multi_unique.cpp ]

Modified: branches/release/libs/geometry/test/multi/algorithms/multi_difference.cpp
==============================================================================
--- branches/release/libs/geometry/test/multi/algorithms/multi_difference.cpp (original)
+++ branches/release/libs/geometry/test/multi/algorithms/multi_difference.cpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -13,6 +13,11 @@
 // #define BOOST_GEOMETRY_DEBUG_ASSEMBLE
 //#define BOOST_GEOMETRY_CHECK_WITH_SQLSERVER
 
+//#define BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER
+//#define BOOST_GEOMETRY_DEBUG_FOLLOW
+//#define BOOST_GEOMETRY_DEBUG_TRAVERSE
+
+
 #include <algorithms/test_difference.hpp>
 #include <algorithms/test_overlay.hpp>
 #include <multi/algorithms/overlay/multi_overlay_cases.hpp>
@@ -163,6 +168,13 @@
     test_one_lp<LineString, LineString, MultiPolygon>("case_mp_ls_3",
             "LINESTRING(6 6,6 7,7 7,7 6,8 6,8 7,9 7,9 6)",
             "MULTIPOLYGON(((5 7,5 8,6 8,6 7,5 7)),((6 6,6 7,7 7,7 6,6 6)),((8 8,9 8,9 7,8 7,7 7,7 8,8 8)))", 2, 5, 3.0);
+
+ return;
+
+ // TODO: this case contains collinearities and should still be solved
+ test_one_lp<LineString, LineString, MultiPolygon>("case_mp_ls_4",
+ "LINESTRING(0 5,0 6,1 6,1 5,2 5,2 6,3 6,3 5,3 4,3 3,2 3,2 4,1 4,1 3,0 3,0 4)",
+ "MULTIPOLYGON(((0 2,0 3,1 2,0 2)),((2 5,3 6,3 5,2 5)),((1 5,1 6,2 6,2 5,1 5)),((2 3,2 4,3 4,2 3)),((0 3,1 4,1 3,0 3)),((4 3,3 3,3 5,4 5,4 4,4 3)))", 5, 11, 6.0);
 }
 
 
@@ -183,6 +195,7 @@
     test_all<bg::model::d2::point_xy<double> >();
 
 #ifdef HAVE_TTMATH
+ std::cout << "Testing TTMATH" << std::endl;
     test_all<bg::model::d2::point_xy<ttmath_big> >();
 #endif
 

Modified: branches/release/libs/geometry/test/multi/algorithms/multi_intersection.cpp
==============================================================================
--- branches/release/libs/geometry/test/multi/algorithms/multi_intersection.cpp (original)
+++ branches/release/libs/geometry/test/multi/algorithms/multi_intersection.cpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -212,6 +212,7 @@
     test_all<bg::model::d2::point_xy<double> >();
 
 #ifdef HAVE_TTMATH
+ std::cout << "Testing TTMATH" << std::endl;
     test_all<bg::model::d2::point_xy<ttmath_big> >();
 #endif
 

Modified: branches/release/libs/geometry/test/multi/algorithms/multi_union.cpp
==============================================================================
--- branches/release/libs/geometry/test/multi/algorithms/multi_union.cpp (original)
+++ branches/release/libs/geometry/test/multi/algorithms/multi_union.cpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -105,7 +105,7 @@
         1, 0, 14, 100.0); // Area from SQL Server
     test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_3",
         case_recursive_boxes_3[0], case_recursive_boxes_3[1],
- 18, 0, 160, 56.5); // Area from SQL Server
+ 17, 0, 159, 56.5); // Area from SQL Server
 }
 
 template <typename P>
@@ -134,6 +134,7 @@
     test_all<bg::model::d2::point_xy<double> >();
 
 #ifdef HAVE_TTMATH
+ std::cout << "Testing TTMATH" << std::endl;
     test_all<bg::model::d2::point_xy<ttmath_big> >();
 #endif
 

Modified: branches/release/libs/geometry/test/multi/algorithms/overlay/multi_overlay_cases.hpp
==============================================================================
--- branches/release/libs/geometry/test/multi/algorithms/overlay/multi_overlay_cases.hpp (original)
+++ branches/release/libs/geometry/test/multi/algorithms/overlay/multi_overlay_cases.hpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -293,7 +293,7 @@
 {
     // for intersection
     "MULTIPOLYGON(((0 0,0 1,1 0,0 0)),((2 2,2 1,0 1,0 2,1 2,2 3,2 2)))",
- "MULTIPOLYGON(((1 1,1 2,2 2,2 1,1 1)),((1 2,0 1,0 3,1 4,1 2))))"
+ "MULTIPOLYGON(((1 1,1 2,2 2,2 1,1 1)),((1 2,0 1,0 3,1 4,1 2)))"
 };
 
 static std::string case_101_multi[2] =

Modified: branches/release/libs/geometry/test/multi/io/wkt/wkt.cpp
==============================================================================
--- branches/release/libs/geometry/test/multi/io/wkt/wkt.cpp (original)
+++ branches/release/libs/geometry/test/multi/io/wkt/wkt.cpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -55,9 +55,30 @@
     test_wkt<bg::model::multi_linestring<bg::model::linestring<P> > >("multilinestring((1 1,2 2,3 3),(4 4,5 5,6 6))", 6, 4 * sqrt(2.0));
     test_wkt<bg::model::multi_polygon<bg::model::polygon<P> > >("multipolygon(((0 0,0 2,2 2,2 0,0 0),(1 1,1 2,2 2,2 1,1 1)),((0 0,0 4,4 4,4 0,0 0)))", 15, 0, 21, 28);
 
+ // Support for the official alternative syntax for multipoint
+ // (provided by Aleksey Tulinov):
+ test_relaxed_wkt<bg::model::multi_point<P> >("multipoint(1 2,3 4)", "multipoint((1 2),(3 4))");
+
     test_wrong_wkt<bg::model::multi_polygon<bg::model::polygon<P> > >(
         "MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0),(1 1,1 2,2 2,2 1,1 1)),(0 0,0 4,4 4,4 0,0 0)))",
         "expected '('");
+
+ test_wrong_wkt<bg::model::multi_linestring<bg::model::linestring<P> > >(
+ "MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10)), (0 0, 1 1)",
+ "too much tokens at ','");
+
+ test_wrong_wkt<bg::model::multi_point<P> >(
+ "MULTIPOINT((8 9), 10 11)",
+ "expected '(' at '10'");
+ test_wrong_wkt<bg::model::multi_point<P> >(
+ "MULTIPOINT(12 13, (14 15))",
+ "bad lexical cast: source type value could not be interpreted as target at '(' in 'multipoint(12 13, (14 15))'");
+ test_wrong_wkt<bg::model::multi_point<P> >(
+ "MULTIPOINT((16 17), (18 19)",
+ "expected ')' in 'multipoint((16 17), (18 19)'");
+ test_wrong_wkt<bg::model::multi_point<P> >(
+ "MULTIPOINT(16 17), (18 19)",
+ "too much tokens at ',' in 'multipoint(16 17), (18 19)'");
 }
 
 /*

Modified: branches/release/libs/geometry/test/multi/io/wkt/wkt.vcproj
==============================================================================
--- branches/release/libs/geometry/test/multi/io/wkt/wkt.vcproj (original)
+++ branches/release/libs/geometry/test/multi/io/wkt/wkt.vcproj 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -20,7 +20,7 @@
                         OutputDirectory="$(SolutionDir)$(ConfigurationName)"
                         IntermediateDirectory="$(ConfigurationName)\wkt"
                         ConfigurationType="1"
- InheritedPropertySheets="..\..\..\..\boost.vsprops"
+ InheritedPropertySheets="..\..\..\boost.vsprops"
                         CharacterSet="1"
>
                         <Tool
@@ -41,7 +41,7 @@
                         <Tool
                                 Name="VCCLCompilerTool"
                                 Optimization="0"
- AdditionalIncludeDirectories="../../../../../../..;../../../.."
+ AdditionalIncludeDirectories="../../../../../..;../../.."
                                 PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
                                 ExceptionHandling="2"
                                 RuntimeLibrary="1"
@@ -93,7 +93,7 @@
                         OutputDirectory="$(SolutionDir)$(ConfigurationName)"
                         IntermediateDirectory="$(ConfigurationName)\wkt"
                         ConfigurationType="1"
- InheritedPropertySheets="..\..\..\..\boost.vsprops"
+ InheritedPropertySheets="..\..\..\boost.vsprops"
                         CharacterSet="1"
                         WholeProgramOptimization="1"
>
@@ -114,7 +114,7 @@
                         />
                         <Tool
                                 Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="../../../../../../..;../../../.."
+ AdditionalIncludeDirectories="../../../../../..;../../.."
                                 PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
                                 ExceptionHandling="2"
                                 UsePrecompiledHeader="0"

Modified: branches/release/libs/geometry/test/multi/multi_tests.sln
==============================================================================
--- branches/release/libs/geometry/test/multi/multi_tests.sln (original)
+++ branches/release/libs/geometry/test/multi/multi_tests.sln 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -46,6 +46,10 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multi_convert", "algorithms\multi_convert.vcproj", "{21B7EF55-23C3-4FD2-9F2F-FD8F0F3FE167}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multi_disjoint", "algorithms\multi_disjoint.vcproj", "{5DEA6558-9DF7-42D4-AF10-4D6D8BB7EAD1}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multi_touches", "algorithms\multi_touches.vcproj", "{108173B8-B6F4-4366-8018-2BF282ED4881}"
+EndProject
 Global
         GlobalSection(SolutionConfigurationPlatforms) = preSolution
                 Debug|Win32 = Debug|Win32
@@ -144,6 +148,14 @@
                 {21B7EF55-23C3-4FD2-9F2F-FD8F0F3FE167}.Debug|Win32.Build.0 = Debug|Win32
                 {21B7EF55-23C3-4FD2-9F2F-FD8F0F3FE167}.Release|Win32.ActiveCfg = Release|Win32
                 {21B7EF55-23C3-4FD2-9F2F-FD8F0F3FE167}.Release|Win32.Build.0 = Release|Win32
+ {5DEA6558-9DF7-42D4-AF10-4D6D8BB7EAD1}.Debug|Win32.ActiveCfg = Debug|Win32
+ {5DEA6558-9DF7-42D4-AF10-4D6D8BB7EAD1}.Debug|Win32.Build.0 = Debug|Win32
+ {5DEA6558-9DF7-42D4-AF10-4D6D8BB7EAD1}.Release|Win32.ActiveCfg = Release|Win32
+ {5DEA6558-9DF7-42D4-AF10-4D6D8BB7EAD1}.Release|Win32.Build.0 = Release|Win32
+ {108173B8-B6F4-4366-8018-2BF282ED4881}.Debug|Win32.ActiveCfg = Debug|Win32
+ {108173B8-B6F4-4366-8018-2BF282ED4881}.Debug|Win32.Build.0 = Debug|Win32
+ {108173B8-B6F4-4366-8018-2BF282ED4881}.Release|Win32.ActiveCfg = Release|Win32
+ {108173B8-B6F4-4366-8018-2BF282ED4881}.Release|Win32.Build.0 = Release|Win32
         EndGlobalSection
         GlobalSection(SolutionProperties) = preSolution
                 HideSolutionNode = FALSE

Modified: branches/release/libs/geometry/test/robustness/convex_hull/random_multi_points.cpp
==============================================================================
--- branches/release/libs/geometry/test/robustness/convex_hull/random_multi_points.cpp (original)
+++ branches/release/libs/geometry/test/robustness/convex_hull/random_multi_points.cpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -1,5 +1,5 @@
 // Boost.Geometry (aka GGL, Generic Geometry Library)
-// Robustness Test
+// Robustness Test - convex_hull
 
 // Copyright (c) 2012 Barend Gehrels, Amsterdam, the Netherlands.
 

Modified: branches/release/libs/geometry/test/strategies/Jamfile.v2
==============================================================================
--- branches/release/libs/geometry/test/strategies/Jamfile.v2 (original)
+++ branches/release/libs/geometry/test/strategies/Jamfile.v2 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -15,6 +15,7 @@
     [ run projected_point.cpp ]
     [ run pythagoras.cpp ]
     [ run spherical_side.cpp ]
+ [ run transform_cs.cpp ]
     [ run transformer.cpp ]
     [ run within.cpp ]
     ;

Modified: branches/release/libs/geometry/test/strategies/projected_point.cpp
==============================================================================
--- branches/release/libs/geometry/test/strategies/projected_point.cpp (original)
+++ branches/release/libs/geometry/test/strategies/projected_point.cpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -87,33 +87,62 @@
 }
 
 
-template <typename P1, typename P2>
-void test_all_2d()
+template <typename P1, typename P2, typename T>
+void test_all_2d(std::string const& wkt_p,
+ std::string const& wkt_sp1,
+ std::string const& wkt_sp2,
+ T expected_distance)
 {
     P1 p;
     P2 sp1, sp2;
- bg::read_wkt("POINT(1 1)", p);
- bg::read_wkt("POINT(0 0)", sp1);
- bg::read_wkt("POINT(2 3)", sp2);
-
- typedef typename bg::strategy::distance::projected_point
- <
- P1,
- P2
- > strategy_type;
-
- BOOST_CONCEPT_ASSERT
- (
- (bg::concept::PointSegmentDistanceStrategy<strategy_type>)
- );
-
+ bg::read_wkt(wkt_p, p);
+ bg::read_wkt(wkt_sp1, sp1);
+ bg::read_wkt(wkt_sp2, sp2);
+
+ {
+ typedef bg::strategy::distance::projected_point
+ <
+ P1,
+ P2
+ > strategy_type;
+
+ BOOST_CONCEPT_ASSERT
+ (
+ (bg::concept::PointSegmentDistanceStrategy<strategy_type>)
+ );
+
+ strategy_type strategy;
+ typedef typename bg::strategy::distance::services::return_type<strategy_type>::type return_type;
+ return_type d = strategy.apply(p, sp1, sp2);
+ BOOST_CHECK_CLOSE(d, expected_distance, 0.001);
+ }
+
+ // Test combination with the comparable strategy
+ {
+ typedef bg::strategy::distance::projected_point
+ <
+ P1,
+ P2,
+ void,
+ bg::strategy::distance::comparable::pythagoras<P1, P2>
+ > strategy_type;
+ strategy_type strategy;
+ typedef typename bg::strategy::distance::services::return_type<strategy_type>::type return_type;
+ return_type d = strategy.apply(p, sp1, sp2);
+ T expected_squared_distance = expected_distance * expected_distance;
+ BOOST_CHECK_CLOSE(d, expected_squared_distance, 0.01);
+ }
 
- strategy_type strategy;
- typedef typename bg::strategy::distance::services::return_type<strategy_type>::type return_type;
- return_type d = strategy.apply(p, sp1, sp2);
- BOOST_CHECK_CLOSE(d, return_type(0.27735203958327), 0.001);
 }
 
+template <typename P1, typename P2>
+void test_all_2d()
+{
+ test_all_2d<P1, P2>("POINT(1 1)", "POINT(0 0)", "POINT(2 3)", 0.27735203958327);
+ test_all_2d<P1, P2>("POINT(2 2)", "POINT(1 4)", "POINT(4 1)", 0.5 * sqrt(2.0));
+ test_all_2d<P1, P2>("POINT(6 1)", "POINT(1 4)", "POINT(4 1)", 2.0);
+ test_all_2d<P1, P2>("POINT(1 6)", "POINT(1 4)", "POINT(4 1)", 2.0);
+}
 
 template <typename P>
 void test_all_2d()

Modified: branches/release/libs/geometry/test/strategies/strategies_tests.sln
==============================================================================
--- branches/release/libs/geometry/test/strategies/strategies_tests.sln (original)
+++ branches/release/libs/geometry/test/strategies/strategies_tests.sln 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -18,6 +18,8 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "within", "within.vcproj", "{AB13D2AC-FD34-4DE4-BD8E-4D463050E5DD}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "transform_cs", "transform_cs.vcproj", "{2128A5D9-C67E-4C00-A917-A79058C78FCC}"
+EndProject
 Global
         GlobalSection(SolutionConfigurationPlatforms) = preSolution
                 Debug|Win32 = Debug|Win32
@@ -60,6 +62,10 @@
                 {AB13D2AC-FD34-4DE4-BD8E-4D463050E5DD}.Debug|Win32.Build.0 = Debug|Win32
                 {AB13D2AC-FD34-4DE4-BD8E-4D463050E5DD}.Release|Win32.ActiveCfg = Release|Win32
                 {AB13D2AC-FD34-4DE4-BD8E-4D463050E5DD}.Release|Win32.Build.0 = Release|Win32
+ {2128A5D9-C67E-4C00-A917-A79058C78FCC}.Debug|Win32.ActiveCfg = Debug|Win32
+ {2128A5D9-C67E-4C00-A917-A79058C78FCC}.Debug|Win32.Build.0 = Debug|Win32
+ {2128A5D9-C67E-4C00-A917-A79058C78FCC}.Release|Win32.ActiveCfg = Release|Win32
+ {2128A5D9-C67E-4C00-A917-A79058C78FCC}.Release|Win32.Build.0 = Release|Win32
         EndGlobalSection
         GlobalSection(SolutionProperties) = preSolution
                 HideSolutionNode = FALSE

Modified: branches/release/libs/geometry/test/views/closeable_view.cpp
==============================================================================
--- branches/release/libs/geometry/test/views/closeable_view.cpp (original)
+++ branches/release/libs/geometry/test/views/closeable_view.cpp 2012-05-28 07:29:18 EDT (Mon, 28 May 2012)
@@ -76,7 +76,7 @@
     it += 2;
     BOOST_CHECK_EQUAL(*it, 1);
 
- BOOST_CHECK_EQUAL(boost::size(view), 4);
+ BOOST_CHECK_EQUAL(boost::size(view), 4u);
 }
 
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk