From 8ff20f086cd34e9c89882cdfb96084ce0e128749 Mon Sep 17 00:00:00 2001 From: Bill Little Date: Tue, 27 Nov 2018 14:11:58 +0000 Subject: [PATCH 1/3] fix lambert conformal secant latitudes --- lib/iris/coord_systems.py | 10 ++++++++-- lib/iris/tests/test_coordsystem.py | 24 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/lib/iris/coord_systems.py b/lib/iris/coord_systems.py index e02ae7dc8c..eb8a48eb8f 100644 --- a/lib/iris/coord_systems.py +++ b/lib/iris/coord_systems.py @@ -776,11 +776,15 @@ def __init__(self, central_lat=39.0, central_lon=-96.0, self.false_easting = false_easting #: Y offset from planar origin in metres. self.false_northing = false_northing - #: The two standard parallels of the cone. + #: The one or two standard parallels of the cone. try: self.secant_latitudes = tuple(secant_latitudes) except TypeError: self.secant_latitudes = (secant_latitudes,) + nlats = len(self.secant_latitudes) + if nlats == 0 or nlats > 2: + emsg = 'Either one or two secant latitudes required, got {}' + raise ValueError(emsg.format(nlats)) #: Ellipsoid definition. self.ellipsoid = ellipsoid @@ -796,7 +800,9 @@ def as_cartopy_crs(self): # We're either north or south polar. Set a cutoff accordingly. if self.secant_latitudes is not None: lats = self.secant_latitudes - max_lat = lats[0] if abs(lats[0]) > abs(lats[1]) else lats[1] + max_lat = lats[0] + if len(lats) == 2: + max_lat = lats[0] if abs(lats[0]) > abs(lats[1]) else lats[1] cutoff = -30 if max_lat > 0 else 30 else: cutoff = None diff --git a/lib/iris/tests/test_coordsystem.py b/lib/iris/tests/test_coordsystem.py index 5aef363533..614f825272 100644 --- a/lib/iris/tests/test_coordsystem.py +++ b/lib/iris/tests/test_coordsystem.py @@ -375,6 +375,30 @@ def test_as_cartopy_projection(self): self.assertEqual(res, expected) class Test_LambertConformal(tests.GraphicsTest): + def test_fail_secant_latitudes_none(self): + emsg = 'one or two secant latitudes required' + with self.assertRaisesRegexp(ValueError, emsg): + LambertConformal(secant_latitudes=()) + + def test_fail_secant_latitudes_excessive(self): + emsg = 'one or two secant latitudes required' + with self.assertRaisesRegexp(ValueError, emsg): + LambertConformal(secant_latitudes=(1, 2, 3)) + + def test_secant_latitudes_single_value(self): + lat_1 = 40 + lcc = LambertConformal(secant_latitudes=lat_1) + ccrs = lcc.as_cartopy_crs() + self.assertEqual(lat_1, ccrs.proj4_params['lat_1']) + seff.assertNotIn('lat_2', ccrs.proj4_params) + + def test_secant_latitudes(self): + lat_1, lat_2 = 40, 41 + lcc = LambertConformal(secant_latitudes=(lat_0, lat_1)) + ccrs = lcc.as_cartopy_crs() + self.assertEqual(lat_1, ccrs.proj4_params['lat_1']) + self.assertEqual(lat_2, ccrs.proj4_params['lat_2']) + def test_north_cutoff(self): lcc = LambertConformal(0, 0, secant_latitudes=(30, 60)) ccrs = lcc.as_cartopy_crs() From bd8cca53b5a15c0564d45bc86d65106582725833 Mon Sep 17 00:00:00 2001 From: Bill Little Date: Tue, 27 Nov 2018 14:26:46 +0000 Subject: [PATCH 2/3] pin cftime back --- lib/iris/tests/test_coordsystem.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/iris/tests/test_coordsystem.py b/lib/iris/tests/test_coordsystem.py index 614f825272..82161b3128 100644 --- a/lib/iris/tests/test_coordsystem.py +++ b/lib/iris/tests/test_coordsystem.py @@ -390,11 +390,11 @@ def test_secant_latitudes_single_value(self): lcc = LambertConformal(secant_latitudes=lat_1) ccrs = lcc.as_cartopy_crs() self.assertEqual(lat_1, ccrs.proj4_params['lat_1']) - seff.assertNotIn('lat_2', ccrs.proj4_params) + self.assertNotIn('lat_2', ccrs.proj4_params) def test_secant_latitudes(self): lat_1, lat_2 = 40, 41 - lcc = LambertConformal(secant_latitudes=(lat_0, lat_1)) + lcc = LambertConformal(secant_latitudes=(lat_1, lat_2)) ccrs = lcc.as_cartopy_crs() self.assertEqual(lat_1, ccrs.proj4_params['lat_1']) self.assertEqual(lat_2, ccrs.proj4_params['lat_2']) From be7d02f882fd9b12ce0e7836e0af44e7b4a3e41e Mon Sep 17 00:00:00 2001 From: Bill Little Date: Tue, 27 Nov 2018 15:40:26 +0000 Subject: [PATCH 3/3] appease the sticker god --- lib/iris/tests/test_coordsystem.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/iris/tests/test_coordsystem.py b/lib/iris/tests/test_coordsystem.py index 82161b3128..c12ebafa74 100644 --- a/lib/iris/tests/test_coordsystem.py +++ b/lib/iris/tests/test_coordsystem.py @@ -30,11 +30,13 @@ import iris.coords import iris.tests.stock -from iris.coord_systems import * +from iris.coord_systems import (GeogCS, LambertConformal, RotatedGeogCS, + Stereographic, TransverseMercator) def osgb(): - return TransverseMercator(latitude_of_projection_origin=49, longitude_of_central_meridian=-2, + return TransverseMercator(latitude_of_projection_origin=49, + longitude_of_central_meridian=-2, false_easting=-400, false_northing=100, scale_factor_at_central_meridian=0.9996012717, ellipsoid=GeogCS(6377563.396, 6356256.909)) @@ -310,6 +312,7 @@ def test_as_cartopy_projection(self): res = tmerc_cs.as_cartopy_projection() self.assertEqual(res, expected) + class Test_Stereographic_construction(tests.IrisTest): def test_stereo(self): st = stereo() @@ -374,6 +377,7 @@ def test_as_cartopy_projection(self): res = st.as_cartopy_projection() self.assertEqual(res, expected) + class Test_LambertConformal(tests.GraphicsTest): def test_fail_secant_latitudes_none(self): emsg = 'one or two secant latitudes required' @@ -386,11 +390,11 @@ def test_fail_secant_latitudes_excessive(self): LambertConformal(secant_latitudes=(1, 2, 3)) def test_secant_latitudes_single_value(self): - lat_1 = 40 + lat_1 = 40 lcc = LambertConformal(secant_latitudes=lat_1) ccrs = lcc.as_cartopy_crs() self.assertEqual(lat_1, ccrs.proj4_params['lat_1']) - self.assertNotIn('lat_2', ccrs.proj4_params) + self.assertNotIn('lat_2', ccrs.proj4_params) def test_secant_latitudes(self): lat_1, lat_2 = 40, 41