diff --git a/include/boost/geometry/util/normalize_spheroidal_box_coordinates.hpp b/include/boost/geometry/util/normalize_spheroidal_box_coordinates.hpp index 9658b8bbef..ee9c26e3b1 100644 --- a/include/boost/geometry/util/normalize_spheroidal_box_coordinates.hpp +++ b/include/boost/geometry/util/normalize_spheroidal_box_coordinates.hpp @@ -48,8 +48,13 @@ class normalize_spheroidal_box_coordinates CoordinateType& latitude2, bool band) { + bool const allow_antimeridian_crossing = + longitude1 >= constants::min_longitude() + && longitude1 <= constants::max_longitude() + && longitude2 > constants::max_longitude() + && longitude2 - constants::period() < longitude1; normalize::apply(longitude1, latitude1, false); - normalize::apply(longitude2, latitude2, false); + normalize::apply(longitude2, latitude2, false, true, allow_antimeridian_crossing); latitude_convert_if_polar::apply(latitude1); latitude_convert_if_polar::apply(latitude2); diff --git a/include/boost/geometry/util/normalize_spheroidal_coordinates.hpp b/include/boost/geometry/util/normalize_spheroidal_coordinates.hpp index 6fa52d7385..82aadc7a3d 100644 --- a/include/boost/geometry/util/normalize_spheroidal_coordinates.hpp +++ b/include/boost/geometry/util/normalize_spheroidal_coordinates.hpp @@ -223,7 +223,8 @@ class normalize_spheroidal_coordinates } public: - static inline void apply(CoordinateType& longitude, bool exact = true) + static inline void apply(CoordinateType& longitude, bool exact = true, + bool allow_antimeridian_crossing = false) { // normalize longitude CoordinateType const epsilon = std::numeric_limits::epsilon(); @@ -234,7 +235,7 @@ class normalize_spheroidal_coordinates { longitude = constants::half_period(); } - else if (longitude > constants::half_period()) + else if ( ! allow_antimeridian_crossing && longitude > constants::half_period()) { longitude = normalize_up(longitude); if (exact || is_integer ? math::equals(longitude, -constants::half_period()) @@ -252,7 +253,8 @@ class normalize_spheroidal_coordinates static inline void apply(CoordinateType& longitude, CoordinateType& latitude, bool normalize_poles = true, - bool exact = true) + bool exact = true, + bool allow_antimeridian_crossing = false) { latitude_convert_if_polar::apply(latitude); @@ -281,7 +283,7 @@ class normalize_spheroidal_coordinates #endif // BOOST_GEOMETRY_NORMALIZE_LATITUDE // normalize longitude - apply(longitude, exact); + apply(longitude, exact, allow_antimeridian_crossing); // finally normalize poles if (normalize_poles) @@ -302,7 +304,8 @@ class normalize_spheroidal_coordinates #endif // BOOST_GEOMETRY_NORMALIZE_LATITUDE BOOST_GEOMETRY_ASSERT(! math::larger_or_equals(constants::min_longitude(), longitude)); - BOOST_GEOMETRY_ASSERT(! math::larger(longitude, constants::max_longitude())); + BOOST_GEOMETRY_ASSERT(! math::larger(longitude, constants::max_longitude()) + || allow_antimeridian_crossing); } }; diff --git a/test/algorithms/envelope_expand/expand_on_spheroid.cpp b/test/algorithms/envelope_expand/expand_on_spheroid.cpp index bbfb46cb0c..4ce167a24b 100644 --- a/test/algorithms/envelope_expand/expand_on_spheroid.cpp +++ b/test/algorithms/envelope_expand/expand_on_spheroid.cpp @@ -591,6 +591,13 @@ void test_expand_point() from_wkt("BOX(10 -90,100 90)"), from_wkt("POINT(-95 -90)"), 10, -90, 100, 90); + + // box crosses anti-meridian and contains point so it should not be changed + tester::apply("p21", + from_wkt("BOX(170 0,190.4 2)"), + from_wkt("POINT(175 1)"), + 170, 0, 190.4, 2, + 0.0); } BOOST_AUTO_TEST_CASE( expand_point ) diff --git a/test/algorithms/envelope_expand/test_envelope_expand_on_spheroid.hpp b/test/algorithms/envelope_expand/test_envelope_expand_on_spheroid.hpp index caf5402f45..b78a983705 100644 --- a/test/algorithms/envelope_expand/test_envelope_expand_on_spheroid.hpp +++ b/test/algorithms/envelope_expand/test_envelope_expand_on_spheroid.hpp @@ -246,7 +246,7 @@ struct box_check_equals && (bg::get<0, 1>(box) < 0 ? equals(bg::get<0, 1>(box), lat_min) : equals_with_eps(bg::get<0, 1>(box), lat_min)) - && equals_with_eps(bg::get<1, 0>(box), lon_max) + && equals(bg::get<1, 0>(box), lon_max) && (bg::get<1, 1>(box) > 0 ? equals(bg::get<1, 1>(box), lat_max) : equals_with_eps(bg::get<1, 1>(box), lat_max));