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..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,7 +377,32 @@ 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' + 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']) + self.assertNotIn('lat_2', ccrs.proj4_params) + + def test_secant_latitudes(self): + lat_1, lat_2 = 40, 41 + 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']) + def test_north_cutoff(self): lcc = LambertConformal(0, 0, secant_latitudes=(30, 60)) ccrs = lcc.as_cartopy_crs()