From 08d9de50c0f2be0630032a5c348b04ba953199ee Mon Sep 17 00:00:00 2001 From: Ryan May Date: Sat, 27 Apr 2024 19:15:11 -0600 Subject: [PATCH] BUG: Fix incorrect internal use of PlateCarree (Fixes #2377) This replaces a couple of internal uses of PlateCarree() for lon/lat coords with more proper geodetic CRS's on the same ellipse, which avoids some precision problems. In the case of LambertConformal, this was resulting in a traceback when creating a boundary on a spherical Earth datum. --- lib/cartopy/crs.py | 4 ++-- lib/cartopy/tests/crs/test_lambert_conformal.py | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/cartopy/crs.py b/lib/cartopy/crs.py index e43a266a6..a39703e87 100644 --- a/lib/cartopy/crs.py +++ b/lib/cartopy/crs.py @@ -1790,7 +1790,7 @@ def __init__(self, central_longitude=-96.0, central_latitude=39.0, lons[1:-1] = np.linspace(central_longitude - 180 + 0.001, central_longitude + 180 - 0.001, n) - points = self.transform_points(PlateCarree(globe=globe), lons, lats) + points = self.transform_points(self.as_geodetic(), lons, lats) self._boundary = sgeom.LinearRing(points) mins = np.min(points, axis=0) @@ -1866,7 +1866,7 @@ def __init__(self, central_longitude=0.0, central_latitude=0.0, lon = central_longitude + 180 sign = np.sign(central_latitude) or 1 lat = -central_latitude + sign * 0.01 - x, max_y = self.transform_point(lon, lat, PlateCarree(globe=globe)) + x, max_y = self.transform_point(lon, lat, self.as_geodetic()) coords = _ellipse_boundary(a * 1.9999, max_y - false_northing, false_easting, false_northing, 61) diff --git a/lib/cartopy/tests/crs/test_lambert_conformal.py b/lib/cartopy/tests/crs/test_lambert_conformal.py index 23bfea68f..54f6f1f4d 100644 --- a/lib/cartopy/tests/crs/test_lambert_conformal.py +++ b/lib/cartopy/tests/crs/test_lambert_conformal.py @@ -38,6 +38,17 @@ def test_default_with_cutoff(): (-49788019.81831982, 30793476.08487709)) +def test_sphere(): + """Test LambertConformal with spherical globe. (#2377)""" + globe = ccrs.Globe(ellipse='sphere') + + # This would error creating a boundary + crs = ccrs.LambertConformal(globe=globe) + + assert all(np.isfinite(x) for x in crs.x_limits) + assert all(np.isfinite(y) for y in crs.y_limits) + + def test_specific_lambert(): # This projection comes from EPSG Projection 3034 - ETRS89 / ETRS-LCC. crs = ccrs.LambertConformal(central_longitude=10,