diff --git a/test/algorithms/area/area_sph_geo.cpp b/test/algorithms/area/area_sph_geo.cpp index c9b47bfe1..b282f13ec 100644 --- a/test/algorithms/area/area_sph_geo.cpp +++ b/test/algorithms/area/area_sph_geo.cpp @@ -6,8 +6,8 @@ // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2015-2021. -// Modifications copyright (c) 2015-2021, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015-2022. +// Modifications copyright (c) 2015-2022, Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -54,30 +54,41 @@ namespace bg = boost::geometry; template void test_spherical_geo() { - typedef CT ct; + using ct = CT; //Geographic - typedef typename bg::model::point + using pt_geo = typename bg::model::point < ct, 2, bg::cs::geographic - > pt_geo; + >; - bg::strategy::area::geographic + using pt_geo_d = bg::model::point < - bg::strategy::vincenty, - 5 - > area_geographic; + double, 2, bg::cs::geographic + >; + using pt_geo_ld = bg::model::point + < + long double, 2, bg::cs::geographic + >; + + bg::strategy::area::geographic area_geographic; + bg::strategy::area::geographic area_a; + bg::strategy::area::geographic area_t; + bg::strategy::area::geographic area_v; + bg::strategy::area::geographic area_k; bg::model::polygon geometry_geo; + //Spherical - typedef typename bg::model::point + using pt_sph = typename bg::model::point < ct, 2, bg::cs::spherical_equatorial - > pt; - bg::model::polygon geometry; + >; + + bg::model::polygon geometry; // unit-sphere has area of 4-PI. Polygon covering 1/8 of it: std::string poly = "POLYGON((0 0,0 90,90 0,0 0))"; @@ -422,14 +433,14 @@ void test_spherical_geo() } { - bg::model::ring aurha; // a'dam-utr-rott.-den haag-a'dam + bg::model::ring aurha; // a'dam-utr-rott.-den haag-a'dam std::string poly = "POLYGON((4.892 52.373,5.119 52.093,4.479 51.930,\ 4.23 52.08,4.892 52.373))"; bg::read_wkt(poly, aurha); /*if (polar) { // Create colatitudes (measured from pole) - for (pt& p : aurha) + for (pt_sph& p : aurha) { bg::set<1>(p, ct(90) - bg::get<1>(p)); } @@ -452,7 +463,7 @@ void test_spherical_geo() } { - bg::model::polygon geometry_sph; + bg::model::polygon geometry_sph; std::string wkt = "POLYGON((0 0, 5 0, 5 5, 0 5, 0 0))"; bg::read_wkt(wkt, geometry_sph); @@ -471,7 +482,7 @@ void test_spherical_geo() // see https://github.com/boostorg/geometry/issues/799 // geographiclib 1.50.1 returns: 25.5736 - bg::model::polygon geometry; + bg::model::polygon geometry; std::string wkt ="POLYGON((-0.020000 51.470027,-0.020031 51.470019,-0.020043 51.470000,\ -0.020031 51.469981,-0.020000 51.469973,-0.019969 51.469981,\ -0.019957 51.470000,-0.019969 51.470019,-0.020000 51.470027))"; @@ -486,20 +497,6 @@ void test_spherical_geo() //geographic - using pt_geo_d = bg::model::point - < - double, 2, bg::cs::geographic - >; - using pt_geo_ld = bg::model::point - < - long double, 2, bg::cs::geographic - >; - - bg::strategy::area::geographic area_a; - bg::strategy::area::geographic area_t; - bg::strategy::area::geographic area_v; - bg::strategy::area::geographic area_k; - bg::model::polygon geometry_geo_d; bg::read_wkt(wkt, geometry_geo_d); @@ -529,7 +526,7 @@ void test_spherical_geo() // very small areas: ~2m^2 // geographiclib 1.50.1 returns: 2.24581 - bg::model::polygon geometry; + bg::model::polygon geometry; std::string wkt ="POLYGON((0.020000 51.470027,0.020005 51.470027,\ 0.020005 51.470000,0.020007 51.4699,0.020000 51.470027))"; bg::read_wkt(wkt, geometry); @@ -543,20 +540,6 @@ void test_spherical_geo() //geographic - using pt_geo_d = bg::model::point - < - double, 2, bg::cs::geographic - >; - using pt_geo_ld = bg::model::point - < - long double, 2, bg::cs::geographic - >; - - bg::strategy::area::geographic area_a; - bg::strategy::area::geographic area_t; - bg::strategy::area::geographic area_v; - bg::strategy::area::geographic area_k; - bg::model::polygon geometry_geo_d; bg::read_wkt(wkt, geometry_geo_d); @@ -581,7 +564,278 @@ void test_spherical_geo() area = bg::area(geometry_geo_ld, area_k); BOOST_CHECK_CLOSE(area, 2.2458050314935392, 0.001); } +} +template +Poly generate_polygon_1() +{ + using PT = typename bg::point_type::type; + + // Rotated by 90.0 - 0.00000000000001 + Poly sp; + sp.outer().push_back(PT(-9.00000000000000142e+01,6.00172345808800074e+01)); + sp.outer().push_back(PT(9.00000000000000142e+01,6.00172345808800074e+01)); + sp.outer().push_back(PT(8.87671232876712253e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(8.38356164383561691e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(7.89041095890410986e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(7.39726027397260282e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(6.90410958904109719e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(6.41095890410958873e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(5.91780821917808240e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(5.42465753424657606e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(4.93150684931506831e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(4.43835616438356126e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(3.94520547945205493e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(3.45205479452054860e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(2.95890410958904120e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(2.46575342465753415e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(1.97260273972602747e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(1.47945205479452060e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(9.86301369863013733e+00,6.00000000000000071e+01)); + sp.outer().push_back(PT(4.93150684931506866e+00,6.00000000000000071e+01)); + sp.outer().push_back(PT(0.00000000000000000e+00,6.00000000000000071e+01)); + sp.outer().push_back(PT(-9.86301369863014976e+00,6.00000000000000071e+01)); + sp.outer().push_back(PT(-1.47945205479451669e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-1.97260273972602853e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-2.46575342465753522e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-2.95890410958904191e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-3.45205479452054860e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-3.94520547945206062e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-4.43835616438356269e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-4.93150684931507470e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-5.42465753424657606e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-5.91780821917808240e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-6.41095890410958873e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-6.90410958904110146e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-7.39726027397260282e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-7.89041095890410418e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-8.38356164383561691e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-8.87671232876712253e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-9.00000000000000142e+01,6.00172345808800074e+01)); + return sp; +} + +template +Poly generate_polygon_2() +{ + using PT = typename bg::point_type::type; + + // Rotated By 90 + Poly sp; + sp.outer().push_back(PT(-9.00000000000000000e+01,6.00172345808800074e+01)); + sp.outer().push_back(PT(9.00000000000000000e+01,6.00172345808800074e+01)); + sp.outer().push_back(PT(8.87671232876712253e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(8.38356164383561691e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(7.89041095890410986e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(7.39726027397260282e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(6.90410958904109719e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(6.41095890410958873e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(5.91780821917808240e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(5.42465753424657606e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(4.93150684931506831e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(4.43835616438356126e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(3.94520547945205493e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(3.45205479452054860e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(2.95890410958904120e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(2.46575342465753415e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(1.97260273972602747e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(1.47945205479452060e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(9.86301369863013733e+00,6.00000000000000071e+01)); + sp.outer().push_back(PT(4.93150684931506866e+00,6.00000000000000071e+01)); + sp.outer().push_back(PT(0.00000000000000000e+00,6.00000000000000071e+01)); + sp.outer().push_back(PT(-9.86301369863014976e+00,6.00000000000000071e+01)); + sp.outer().push_back(PT(-1.47945205479451669e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-1.97260273972602853e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-2.46575342465753522e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-2.95890410958904191e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-3.45205479452054860e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-3.94520547945206062e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-4.43835616438356269e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-4.93150684931507470e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-5.42465753424657606e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-5.91780821917808240e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-6.41095890410958873e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-6.90410958904110146e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-7.39726027397260282e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-7.89041095890410418e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-8.38356164383561691e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-8.87671232876712253e+01,6.00000000000000071e+01)); + sp.outer().push_back(PT(-9.00000000000000000e+01,6.00172345808800074e+01)); + return sp; +} + +template +Poly generate_polygon_3() +{ + using PT = typename bg::point_type::type; + + Poly sp; + sp.outer().push_back(PT(-9.00000000000000142e+01,6.00172345808800074e+01)); + sp.outer().push_back(PT(9.00000000000000142e+01,6.00172345808800074e+01)); + sp.outer().push_back(PT(0.00000000000000000e+00,6.00000000000000071e+01)); + sp.outer().push_back(PT(-9.00000000000000142e+01,6.00172345808800074e+01)); + return sp; +} + +template +Poly generate_polygon_4() +{ + using PT = typename bg::point_type::type; + + Poly sp; + sp.outer().push_back(PT(-9.00000000000000000e+01,6.00172345808800074e+01)); + sp.outer().push_back(PT(9.00000000000000000e+01,6.00172345808800074e+01)); + sp.outer().push_back(PT(0.00000000000000000e+00,6.00000000000000071e+01)); + sp.outer().push_back(PT(-9.00000000000000000e+01,6.00172345808800074e+01)); + return sp; +} + +template +Poly generate_polygon_5() +{ + using PT = typename bg::point_type::type; + + Poly sp; + sp.outer().push_back(PT(-80,6.00172345808800074e+01)); + sp.outer().push_back(PT(80,6.00172345808800074e+01)); + sp.outer().push_back(PT(0,6.00000000000000071e+01)); + sp.outer().push_back(PT(-80,6.00172345808800074e+01)); + return sp; +} + +template +Poly generate_polygon_6() +{ + using PT = typename bg::point_type::type; + + Poly sp; + sp.outer().push_back(PT(-8.999999999999142e+01,6.00172345808800074e+01)); + sp.outer().push_back(PT(8.999999999999142e+01,6.00172345808800074e+01)); + sp.outer().push_back(PT(0.00000000000000000e+00,6.00000000000000071e+01)); + sp.outer().push_back(PT(-8.999999999999142e+01,6.00172345808800074e+01)); + return sp; +} + +template +Poly generate_polygon_7() +{ + using PT = typename bg::point_type::type; + + Poly sp; + sp.outer().push_back(PT(-80,6.00172345808800074e+01)); + sp.outer().push_back(PT(100,6.00172345808800074e+01)); + sp.outer().push_back(PT(10,6.00000000000000071e+01)); + sp.outer().push_back(PT(-80,6.00172345808800074e+01)); + return sp; +} + +template +Poly generate_polygon_8() +{ + using PT = typename bg::point_type::type; + + Poly sp; + sp.outer().push_back(PT(-80,6.00172345808800074e+01)); + sp.outer().push_back(PT(100,6.00172345808800074e+01)); + sp.outer().push_back(PT(30,6.00000000000000071e+01)); + sp.outer().push_back(PT(10,6.00000000000000071e+01)); + sp.outer().push_back(PT(-80,6.00172345808800074e+01)); + return sp; +} + +template +Poly generate_polygon_9() +{ + using PT = typename bg::point_type::type; + + Poly sp; + sp.outer().push_back(PT(-90,6.00172345808800074e+01)); + sp.outer().push_back(PT(90.0000000000000000000001,6.00172345808800074e+01)); + sp.outer().push_back(PT(0,6.00000000000000071e+01)); + sp.outer().push_back(PT(-90,6.00172345808800074e+01)); + return sp; +} + +template +Poly generate_polygon_10() +{ + using PT = typename bg::point_type::type; + + Poly sp; + sp.outer().push_back(PT(-90,6.00172345808800074e+01)); + sp.outer().push_back(PT(89.9999999999999999,6.00172345808800074e+01)); + sp.outer().push_back(PT(0,6.00000000000000071e+01)); + sp.outer().push_back(PT(-90,6.00172345808800074e+01)); + return sp; +} + +template +void segment_through_pole(Strategy str, std::vector results) +{ + // special cases with segments that pass through (or nearby) a pole + // see issue https://github.com/boostorg/geometry/issues/1063 + + using polygon = boost::geometry::model::polygon + < + PT, + true, // clockwise + true, // closed + std::vector, + std::vector, + std::allocator, + std::allocator + >; + + { + auto sp = generate_polygon_1(); + auto area = bg::area(sp, str); + BOOST_CHECK_CLOSE(area, results[0], 0.001); + } + { + auto sp = generate_polygon_2(); + auto area = bg::area(sp, str); + BOOST_CHECK_CLOSE(area, results[0], 0.001); + } + { + auto sp = generate_polygon_3(); + auto area = bg::area(sp, str); + BOOST_CHECK_CLOSE(area, results[1], 0.001); + } + { + auto sp = generate_polygon_4(); + auto area = bg::area(sp, str); + BOOST_CHECK_CLOSE(area, results[1], 0.001); + } + { + auto sp = generate_polygon_5(); + auto area = bg::area(sp, str); + BOOST_CHECK_CLOSE(area, results[2], 0.001); + } + { + auto sp = generate_polygon_6(); + auto area = bg::area(sp, str); + BOOST_CHECK_CLOSE(area, results[1], 0.001); + } + { + auto sp = generate_polygon_7(); + auto area = bg::area(sp, str); + BOOST_CHECK_CLOSE(area, results[1], 0.001); + } + { + auto sp = generate_polygon_8(); + auto area = bg::area(sp, str); + BOOST_CHECK_CLOSE(area, results[3], 0.001); + } + { + auto sp = generate_polygon_9(); + auto area = bg::area(sp, str); + BOOST_CHECK_CLOSE(area, results[1], 0.001); + } + { + auto sp = generate_polygon_10(); + auto area = bg::area(sp, str); + BOOST_CHECK_CLOSE(area, results[1], 0.001); + } } int test_main(int, char* []) @@ -589,5 +843,35 @@ int test_main(int, char* []) test_spherical_geo(); + using sph_pt = typename bg::model::point + < + double, 2, bg::cs::spherical_equatorial + >; + bg::strategy::area::spherical<> sph_str; + + std::vector results_sph {0.4204069, 0.2865233, 0.2261384, 0.3206943}; + + segment_through_pole(sph_str, results_sph); + + + using geo_pt = typename bg::model::point + < + double, 2, bg::cs::geographic + >; + + bg::strategy::area::geographic area_a; + bg::strategy::area::geographic area_t; + bg::strategy::area::geographic area_v; + bg::strategy::area::geographic area_k; + + std::vector results_geo {17188025916331.664, 11713812318907.75, 9245554289678.4492, + 13111012015900.15}; + + segment_through_pole(area_a, results_geo); + segment_through_pole(area_v, results_geo); + //NOTE: thomas strategy results in wrong results in some cases + //segment_through_pole(area_t, results_geo); + segment_through_pole(area_k, results_geo); + return 0; }