Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / geometry / test / strategies / cross_track.cpp
index 2165549..1b02c88 100644 (file)
@@ -1,9 +1,14 @@
 // Boost.Geometry (aka GGL, Generic Geometry Library)
 // Unit Test
 
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
 
 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -15,6 +20,9 @@
 
 #include <geometry_test_common.hpp>
 
+#include <boost/core/ignore_unused.hpp>
+
+#include <boost/geometry/io/wkt/read.hpp>
 
 #include <boost/geometry/algorithms/assign.hpp>
 #include <boost/geometry/algorithms/distance.hpp>
 #include <boost/geometry/geometries/segment.hpp>
 
 
-// This test is GIS oriented. 
+// This test is GIS oriented.
 
 
 template <typename Point, typename LatitudePolicy>
 void test_distance(
-            typename bg::coordinate_type<Point>::type const& lon1, 
+            typename bg::coordinate_type<Point>::type const& lon1,
             typename bg::coordinate_type<Point>::type const& lat1,
-            typename bg::coordinate_type<Point>::type const& lon2, 
+            typename bg::coordinate_type<Point>::type const& lon2,
             typename bg::coordinate_type<Point>::type const& lat2,
-            typename bg::coordinate_type<Point>::type const& lon3, 
+            typename bg::coordinate_type<Point>::type const& lon3,
             typename bg::coordinate_type<Point>::type const& lat3,
-            typename bg::coordinate_type<Point>::type const& radius, 
-            typename bg::coordinate_type<Point>::type const& expected, 
+            typename bg::coordinate_type<Point>::type const& radius,
+            typename bg::coordinate_type<Point>::type const& expected,
             typename bg::coordinate_type<Point>::type const& tolerance)
 {
     typedef bg::strategy::distance::cross_track
         <
-            Point,
-            Point
+            typename bg::coordinate_type<Point>::type
         > strategy_type;
+
     typedef typename bg::strategy::distance::services::return_type
         <
-            strategy_type
+            strategy_type,
+            Point,
+            Point
         >::type return_type;
 
 
+    {
+        // compile-check if there is a strategy for this type
+        typedef typename bg::strategy::distance::services::default_strategy
+            <
+                bg::point_tag, bg::segment_tag, Point, Point
+            >::type cross_track_strategy_type;
+
+        typedef typename bg::strategy::distance::services::default_strategy
+            <
+                bg::segment_tag, bg::point_tag, Point, Point
+            >::type reversed_tags_cross_track_strategy_type;
+
+        boost::ignore_unused<cross_track_strategy_type,
+                             reversed_tags_cross_track_strategy_type>();
+    }
+
+
     BOOST_CONCEPT_ASSERT
         (
-            (bg::concept::PointSegmentDistanceStrategy<strategy_type>)
+            (bg::concept::PointSegmentDistanceStrategy<strategy_type, Point, Point>)
         );
 
 
@@ -71,6 +98,10 @@ void test_distance(
 
     BOOST_CHECK_CLOSE(radius * d, expected, tolerance);
 
+    // The strategy should return the same result if we reverse the parameters
+    d = strategy.apply(p1, p3, p2);
+    BOOST_CHECK_CLOSE(radius * d, expected, tolerance);
+
     // Test specifying radius explicitly
     strategy_type strategy_radius(radius);
     d = strategy_radius.apply(p1, p2, p3);
@@ -84,17 +115,53 @@ void test_distance(
 }
 
 
+template <typename Point>
+void test_case_boost_geometry_list_20120625()
+{
+    // This function tests the bug submitted by Karsten Ahnert
+    // on Boost.Geometry list at 2012-06-25, and wherefore he
+    // submitted a patch a few days later.
+
+    Point p1, p2;
+    bg::model::segment<Point> s1, s2;
+
+    bg::read_wkt("POINT(1 1)", p1);
+    bg::read_wkt("POINT(5 1)", p2);
+    bg::read_wkt("LINESTRING(0 2,2 2)", s1);
+    bg::read_wkt("LINESTRING(2 2,4 2)", s2);
+
+    BOOST_CHECK_CLOSE(boost::geometry::distance(p1, s1), 0.0174586, 0.0001);
+    BOOST_CHECK_CLOSE(boost::geometry::distance(p1, s2), 0.0246783, 0.0001);
+    BOOST_CHECK_CLOSE(boost::geometry::distance(p2, s1), 0.0551745, 0.0001);
+    BOOST_CHECK_CLOSE(boost::geometry::distance(p2, s2), 0.0246783, 0.0001);
+
+    // Check degenerated segments
+    bg::model::segment<Point> s3;
+    bg::read_wkt("LINESTRING(2 2,2 2)", s3);
+    BOOST_CHECK_CLOSE(boost::geometry::distance(p1, s3), 0.0246783, 0.0001);
+    BOOST_CHECK_CLOSE(boost::geometry::distance(p2, s3), 0.0551745, 0.0001);
+
+    // Point/Point distance should be identical:
+    Point p3;
+    bg::read_wkt("POINT(2 2)", p3);
+    BOOST_CHECK_CLOSE(boost::geometry::distance(p1, p3), 0.0246783, 0.0001);
+    BOOST_CHECK_CLOSE(boost::geometry::distance(p2, p3), 0.0551745, 0.0001);
+}
+
+
 template <typename Point, typename LatitudePolicy>
 void test_all()
 {
     typename bg::coordinate_type<Point>::type const average_earth_radius = 6372795.0;
 
-    // distance (Paris <-> Amsterdam/Barcelona), 
+    // distance (Paris <-> Amsterdam/Barcelona),
     // with coordinates rounded as below ~87 km
     // is equal to distance (Paris <-> Barcelona/Amsterdam)
     typename bg::coordinate_type<Point>::type const p_to_ab = 86.798321 * 1000.0;
     test_distance<Point, LatitudePolicy>(2, 48, 4, 52, 2, 41, average_earth_radius, p_to_ab, 0.1);
     test_distance<Point, LatitudePolicy>(2, 48, 2, 41, 4, 52, average_earth_radius, p_to_ab, 0.1);
+
+    test_case_boost_geometry_list_20120625<Point>();
 }