mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-09 23:24:02 +00:00
[within] Fix special case of segment pole endpoint
This commit is contained in:
parent
da3de296d2
commit
4c65c0d936
@ -3,8 +3,9 @@
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2013-2017 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2013-2021.
|
||||
// Modifications copyright (c) 2013-2021 Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2023.
|
||||
// Modifications copyright (c) 2013-2023 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
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
@ -273,11 +274,9 @@ protected:
|
||||
calc_t const anti_p_lon = p_lon + (p_lon <= c0 ? pi : -pi);
|
||||
|
||||
eq1 = eq1_strict // lon strictly equal to s1
|
||||
|| (eq1_anti = longitudes_equal<units_t>(s1_lon, anti_p_lon)) // anti-lon strictly equal to s1
|
||||
|| math::equals(math::abs(s1_lat), half_pi); // s1 is pole
|
||||
|| (eq1_anti = longitudes_equal<units_t>(s1_lon, anti_p_lon)); // anti-lon strictly equal to s1
|
||||
eq2 = eq2_strict // lon strictly equal to s2
|
||||
|| (eq2_anti = longitudes_equal<units_t>(s2_lon, anti_p_lon)) // anti-lon strictly equal to s2
|
||||
|| math::equals(math::abs(s2_lat), half_pi); // s2 is pole
|
||||
|| (eq2_anti = longitudes_equal<units_t>(s2_lon, anti_p_lon)); // anti-lon strictly equal to s2
|
||||
|
||||
// segment overlapping pole
|
||||
calc_t const s_lon_diff = math::longitude_distance_signed<units_t>(s1_lon, s2_lon);
|
||||
@ -293,6 +292,28 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
// check whether point is on a segment with a pole endpoint
|
||||
if (math::longitude_distance_signed<units_t>(s2_lon, p_lon) == c0)
|
||||
{
|
||||
bool const s1_north = math::equals(get<1>(seg1), half_pi);
|
||||
bool const s1_south = math::equals(get<1>(seg1), -half_pi);
|
||||
if (s1_north || s1_south)
|
||||
{
|
||||
state.m_touches = s1_south ? s2_lat > p_lat : s2_lat < p_lat;
|
||||
return state.m_touches;
|
||||
}
|
||||
}
|
||||
if (math::longitude_distance_signed<units_t>(s1_lon, p_lon) == c0)
|
||||
{
|
||||
bool const s2_north = math::equals(get<1>(seg2), half_pi);
|
||||
bool const s2_south = math::equals(get<1>(seg2), -half_pi);
|
||||
if (s2_north || s2_south)
|
||||
{
|
||||
state.m_touches = s2_south ? s1_lat > p_lat : s1_lat < p_lat;
|
||||
return state.m_touches;
|
||||
}
|
||||
}
|
||||
|
||||
// Both equal p -> segment vertical
|
||||
// The only thing which has to be done is check if point is ON segment
|
||||
if (eq1 && eq2)
|
||||
@ -361,7 +382,17 @@ protected:
|
||||
// If needed (eq1 && eq2 ? 0) could be returned
|
||||
|
||||
calc_t const c0 = 0;
|
||||
calc_t const c2 = 2;
|
||||
calc_t const pi = constants::half_period();
|
||||
calc_t const half_pi = pi / c2;
|
||||
|
||||
bool const s1_is_pole = math::equals(std::abs(get<1>(seg1)), half_pi);
|
||||
bool const s2_is_pole = math::equals(std::abs(get<1>(seg2)), half_pi);
|
||||
|
||||
if (s1_is_pole && s2_is_pole)
|
||||
{
|
||||
return count_info(0, false);
|
||||
}
|
||||
|
||||
calc_t const p = get<0>(point);
|
||||
calc_t const s1 = get<0>(seg1);
|
||||
|
@ -63,7 +63,7 @@ void test_p_l()
|
||||
|
||||
test_geometry<P, mls>("POINT(0 0)", "MULTILINESTRING((0 0,1 1,2 2),(0 0,0 1))", true);
|
||||
test_geometry<P, mls>("POINT(0 0)", "MULTILINESTRING((0 0,1 1,2 2),(0 0,0 1),(0 0,1 0))", false);
|
||||
|
||||
|
||||
test_geometry<P, mls>("POINT(1 1)", "MULTILINESTRING((0 0, 1 1),(1 1, 2 2))", true);
|
||||
test_geometry<P, mls>("POINT(1 1)", "MULTILINESTRING((0 0, 1 1),(2 2, 3 3))", false);
|
||||
|
||||
@ -289,12 +289,63 @@ void test_spherical_geographic()
|
||||
// Points outside but on the same level as segment
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-90, 75), poly_n), false);
|
||||
}*/
|
||||
// Segment endpoints on pole with arbitrary longitudes
|
||||
// Segment endpoints on North pole with arbitrary longitudes
|
||||
{
|
||||
bg::model::polygon<Point> poly_n3;
|
||||
bg::read_wkt("POLYGON((45 90,45 80,0 80,45 90))", poly_n3);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(0, 85), poly_n3, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(45, 85), poly_n3, ws), true);
|
||||
bg::model::polygon<Point> poly_n4;
|
||||
bg::read_wkt("POLYGON((45 90,45 80,-10 80,45 90))", poly_n4);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-10, 85), poly_n4, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(0, 85), poly_n4, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(45, 85), poly_n4, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(30, 85), poly_n4, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(50, 85), poly_n4, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-5, 85), poly_n4, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(30, 70), poly_n4, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(50, 70), poly_n4, ws), false);
|
||||
|
||||
// the same polygon but with two points representing the pole
|
||||
bg::model::polygon<Point> poly_n4b;
|
||||
bg::read_wkt("POLYGON((45 90,45 80,-10 80,60 90,45 90))", poly_n4b);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-10, 85), poly_n4b, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(0, 85), poly_n4b, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(45, 85), poly_n4b, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(30, 85), poly_n4b, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(50, 85), poly_n4b, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-5, 85), poly_n4b, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(30, 70), poly_n4b, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(50, 70), poly_n4b, ws), false);
|
||||
|
||||
bg::model::polygon<Point> poly_n5;
|
||||
bg::read_wkt("POLYGON((0 90,-10 80,45 80,0 90))", poly_n5);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-10, 85), poly_n5, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(0, 85), poly_n5, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-1, 85), poly_n5, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(1, 85), poly_n5, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(45, 85), poly_n5, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(30, 85), poly_n5, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(50, 85), poly_n5, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-5, 85), poly_n5, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(30, 70), poly_n5, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(50, 70), poly_n5, ws), false);
|
||||
|
||||
bg::model::polygon<Point> poly_n_4edges;
|
||||
bg::read_wkt("POLYGON((0 90,-10 70,5 60,20 80,0 90))", poly_n_4edges);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(3, 89), poly_n_4edges, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-1, 87), poly_n_4edges, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-10, 86), poly_n_4edges, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(15, 84), poly_n_4edges, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-1, 61), poly_n_4edges, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(15, 81), poly_n_4edges, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(7, 50), poly_n_4edges, ws), false);
|
||||
|
||||
bg::model::polygon<Point> poly_n_5edges;
|
||||
bg::read_wkt("POLYGON((0 90,-10 70,5 60,10 85,20 80,0 90))", poly_n_5edges);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(3, 89), poly_n_5edges, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-1, 87), poly_n_5edges, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-10, 86), poly_n_5edges, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(15, 84), poly_n_5edges, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-1, 61), poly_n_5edges, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(15, 81), poly_n_5edges, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(7, 50), poly_n_5edges, ws), false);
|
||||
}
|
||||
// Segment going through pole
|
||||
{
|
||||
@ -308,12 +359,76 @@ void test_spherical_geographic()
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(0, -90), poly_s1, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(45, -90), poly_s1, ws), true);
|
||||
}
|
||||
// Segment endpoints on pole with arbitrary longitudes
|
||||
// Segment endpoints on South pole with arbitrary longitudes
|
||||
{
|
||||
bg::model::polygon<Point> poly_s2;
|
||||
bg::read_wkt("POLYGON((45 -90,0 -80,45 -80,45 -90))", poly_s2);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(0, -85), poly_s2, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(45, -85), poly_s2, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(30, -85), poly_s2, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(50, -85), poly_s2, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-5, -85), poly_s2, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(30, -70), poly_s2, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(50, -70), poly_s2, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-5, -70), poly_s2, ws), false);
|
||||
|
||||
bg::model::polygon<Point> poly_s3;
|
||||
bg::read_wkt("POLYGON((45 -90,-10 -80,45 -80,45 -90))", poly_s3);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-10, -85), poly_s3, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(0, -85), poly_s3, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-1, -85), poly_s3, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(1, -85), poly_s3, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(45, -85), poly_s3, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(30, -85), poly_s3, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(50, -85), poly_s3, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-5, -85), poly_s3, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(30, -70), poly_s3, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(50, -70), poly_s3, ws), false);
|
||||
|
||||
bg::model::polygon<Point> poly_s5;
|
||||
bg::read_wkt("POLYGON((0 -90,-10 -80,45 -80,0 -90))", poly_s5);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-10, -85), poly_s5, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(0, -85), poly_s5, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-1, -85), poly_s5, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(1, -85), poly_s5, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(45, -85), poly_s5, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(30, -85), poly_s5, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(50, -85), poly_s5, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-5, -85), poly_s5, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(30, -70), poly_s5, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(50, -70), poly_s5, ws), false);
|
||||
|
||||
bg::model::polygon<Point> poly_s4;
|
||||
bg::read_wkt("POLYGON((0 -89,-10 -80,45 -80,0 -89))", poly_s4);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-10, -85), poly_s4, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(0, -85), poly_s4, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(45, -85), poly_s4, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(30, -85), poly_s4, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(50, -85), poly_s4, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-5, -85), poly_s4, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(30, -71), poly_s4, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(50, -70), poly_s4, ws), false);
|
||||
|
||||
//more complex examples
|
||||
bg::model::polygon<Point> poly_s_complex_4edges;
|
||||
bg::read_wkt("POLYGON((0 -90,-10 -70,5 -60,20 -80,0 -90))", poly_s_complex_4edges);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(3, -89), poly_s_complex_4edges, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-1, -87), poly_s_complex_4edges, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-10, -86), poly_s_complex_4edges, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(15, -84), poly_s_complex_4edges, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-1, -61), poly_s_complex_4edges, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(15, -81), poly_s_complex_4edges, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(7, -50), poly_s_complex_4edges, ws), false);
|
||||
|
||||
bg::model::polygon<Point> poly_s_complex_5edges;
|
||||
bg::read_wkt("POLYGON((0 -90,-10 -70,5 -60,10 -85,20 -80,0 -90))", poly_s_complex_5edges);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(3, -89), poly_s_complex_5edges, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-1, -87), poly_s_complex_5edges, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-10, -86), poly_s_complex_5edges, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(15, -84), poly_s_complex_5edges, ws), true);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(-1, -61), poly_s_complex_5edges, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(15, -81), poly_s_complex_5edges, ws), false);
|
||||
BOOST_CHECK_EQUAL(bg::covered_by(Point(7, -50), poly_s_complex_5edges, ws), false);
|
||||
}
|
||||
// Polygon covering nearly half of the globe but no poles
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user