diff --git a/docs/iris/src/whatsnew/2.1.rst b/docs/iris/src/whatsnew/2.1.rst
index a1c4a21e5f..e8c91aba29 100644
--- a/docs/iris/src/whatsnew/2.1.rst
+++ b/docs/iris/src/whatsnew/2.1.rst
@@ -57,6 +57,8 @@ Iris 2.1 Features
* Iris can now represent data on the Albers Equal Area Projection,
and the NetCDF loader and saver were updated to handle this.
https://github.com/SciTools/iris/issues/2943
+* The :class:`~iris.coord_systems.Mercator` projection has been updated to accept
+ the ``standard_parallel`` keyword argument.
Bugs Fixed
==========
diff --git a/lib/iris/coord_systems.py b/lib/iris/coord_systems.py
index 0bc770f9b8..e02ae7dc8c 100644
--- a/lib/iris/coord_systems.py
+++ b/lib/iris/coord_systems.py
@@ -831,7 +831,8 @@ class Mercator(CoordSystem):
grid_mapping_name = "mercator"
- def __init__(self, longitude_of_projection_origin=0, ellipsoid=None):
+ def __init__(self, longitude_of_projection_origin=0.0, ellipsoid=None,
+ standard_parallel=0.0):
"""
Constructs a Mercator coord system.
@@ -840,17 +841,23 @@ def __init__(self, longitude_of_projection_origin=0, ellipsoid=None):
True longitude of planar origin in degrees.
* ellipsoid
:class:`GeogCS` defining the ellipsoid.
+ * standard_parallel
+ the latitude where the scale is 1. Defaults to 0 degrees.
"""
-
#: True longitude of planar origin in degrees.
self.longitude_of_projection_origin = longitude_of_projection_origin
#: Ellipsoid definition.
self.ellipsoid = ellipsoid
+ #: The latitude where the scale is 1 (defaults to 0 degrees).
+ self.standard_parallel = standard_parallel
def __repr__(self):
- res = "Mercator(longitude_of_projection_origin={!r}, ellipsoid={!r})"
- return res.format(self.longitude_of_projection_origin, self.ellipsoid)
+ res = ("Mercator(longitude_of_projection_origin="
+ "{self.longitude_of_projection_origin!r}, "
+ "ellipsoid={self.ellipsoid!r}, "
+ "standard_parallel={self.standard_parallel!r})")
+ return res.format(self=self)
def as_cartopy_crs(self):
if self.ellipsoid is not None:
@@ -860,7 +867,8 @@ def as_cartopy_crs(self):
return ccrs.Mercator(
central_longitude=self.longitude_of_projection_origin,
- globe=globe)
+ globe=globe,
+ latitude_true_scale=self.standard_parallel)
def as_cartopy_projection(self):
return self.as_cartopy_crs()
diff --git a/lib/iris/tests/results/coord_systems/Mercator.xml b/lib/iris/tests/results/coord_systems/Mercator.xml
index db84f80666..e8036ef824 100644
--- a/lib/iris/tests/results/coord_systems/Mercator.xml
+++ b/lib/iris/tests/results/coord_systems/Mercator.xml
@@ -1,2 +1,2 @@
-
+
diff --git a/lib/iris/tests/results/netcdf/netcdf_merc.cml b/lib/iris/tests/results/netcdf/netcdf_merc.cml
index ef239bb2f2..02fc4e7c34 100644
--- a/lib/iris/tests/results/netcdf/netcdf_merc.cml
+++ b/lib/iris/tests/results/netcdf/netcdf_merc.cml
@@ -53,15 +53,15 @@
45.5158, 45.9993]]" shape="(192, 192)" standard_name="longitude" units="Unit('degrees')" value_type="float32" var_name="lon"/>
-
-
+
-
-
+
diff --git a/lib/iris/tests/test_coordsystem.py b/lib/iris/tests/test_coordsystem.py
index 25be9bb1be..6def1a3123 100644
--- a/lib/iris/tests/test_coordsystem.py
+++ b/lib/iris/tests/test_coordsystem.py
@@ -33,17 +33,12 @@
from iris.coord_systems import *
-
-
def osgb():
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))
-def merc():
- return Mercator(longitude_of_projection_origin=90.0,
- ellipsoid=GeogCS(6377563.396, 6356256.909))
def stereo():
return Stereographic(central_lat=-90, central_lon=-45,
@@ -391,58 +386,5 @@ def test_south_cutoff(self):
self.assertEqual(ccrs.cutoff, 30)
-class Test_Mercator_construction(tests.IrisTest):
- def test_merc(self):
- tm = merc()
- self.assertXMLElement(tm, ("coord_systems", "Mercator.xml"))
-
-
-class Test_Mercator_repr(tests.IrisTest):
- def test_merc(self):
- tm = merc()
- expected = "Mercator(longitude_of_projection_origin=90.0, "\
- "ellipsoid=GeogCS(semi_major_axis=6377563.396, "\
- "semi_minor_axis=6356256.909))"
- self.assertEqual(expected, repr(tm))
-
-
-class Test_Mercator_as_cartopy_crs(tests.IrisTest):
- def test_as_cartopy_crs(self):
- longitude_of_projection_origin = 90.0
- ellipsoid = GeogCS(semi_major_axis=6377563.396,
- semi_minor_axis=6356256.909)
-
- merc_cs = Mercator(
- longitude_of_projection_origin,
- ellipsoid=ellipsoid)
-
- expected = ccrs.Mercator(
- central_longitude=longitude_of_projection_origin,
- globe=ccrs.Globe(semimajor_axis=6377563.396,
- semiminor_axis=6356256.909, ellipse=None))
-
- res = merc_cs.as_cartopy_crs()
- self.assertEqual(res, expected)
-
-
-class Test_Mercator_as_cartopy_projection(tests.IrisTest):
- def test_as_cartopy_projection(self):
- longitude_of_projection_origin = 90.0
- ellipsoid = GeogCS(semi_major_axis=6377563.396,
- semi_minor_axis=6356256.909)
-
- merc_cs = Mercator(
- longitude_of_projection_origin,
- ellipsoid=ellipsoid)
-
- expected = ccrs.Mercator(
- central_longitude=longitude_of_projection_origin,
- globe=ccrs.Globe(semimajor_axis=6377563.396,
- semiminor_axis=6356256.909, ellipse=None))
-
- res = merc_cs.as_cartopy_projection()
- self.assertEqual(res, expected)
-
-
if __name__ == "__main__":
tests.main()
diff --git a/lib/iris/tests/unit/coord_systems/test_Mercator.py b/lib/iris/tests/unit/coord_systems/test_Mercator.py
new file mode 100644
index 0000000000..a2791efe67
--- /dev/null
+++ b/lib/iris/tests/unit/coord_systems/test_Mercator.py
@@ -0,0 +1,109 @@
+# (C) British Crown Copyright 2018, Met Office
+#
+# This file is part of Iris.
+#
+# Iris is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Iris is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Iris. If not, see .
+"""Unit tests for the :class:`iris.coord_systems.Mercator` class."""
+
+from __future__ import (absolute_import, division, print_function)
+from six.moves import (filter, input, map, range, zip) # noqa
+
+# Import iris.tests first so that some things can be initialised before
+# importing anything else.
+import iris.tests as tests
+
+import cartopy.crs as ccrs
+from iris.coord_systems import GeogCS, Mercator
+
+
+class Test_Mercator__basics(tests.IrisTest):
+ def setUp(self):
+ self.tm = Mercator(longitude_of_projection_origin=90.0,
+ ellipsoid=GeogCS(6377563.396, 6356256.909))
+
+ def test_construction(self):
+ self.assertXMLElement(self.tm, ("coord_systems", "Mercator.xml"))
+
+ def test_repr(self):
+ expected = ("Mercator(longitude_of_projection_origin=90.0, "
+ "ellipsoid=GeogCS(semi_major_axis=6377563.396, "
+ "semi_minor_axis=6356256.909), "
+ "standard_parallel=0.0)")
+ self.assertEqual(expected, repr(self.tm))
+
+
+class Test_Mercator__as_cartopy_crs(tests.IrisTest):
+ def test_simple(self):
+ # Check that a projection set up with all the defaults is correctly
+ # converted to a cartopy CRS.
+ merc_cs = Mercator()
+ res = merc_cs.as_cartopy_crs()
+ expected = ccrs.Mercator(globe=ccrs.Globe())
+ self.assertEqual(res, expected)
+
+ def test_extra_kwargs(self):
+ # Check that a projection with non-default values is correctly
+ # converted to a cartopy CRS.
+ longitude_of_projection_origin = 90.0
+ true_scale_lat = 14.0
+ ellipsoid = GeogCS(semi_major_axis=6377563.396,
+ semi_minor_axis=6356256.909)
+
+ merc_cs = Mercator(
+ longitude_of_projection_origin,
+ ellipsoid=ellipsoid,
+ standard_parallel=true_scale_lat)
+
+ expected = ccrs.Mercator(
+ central_longitude=longitude_of_projection_origin,
+ globe=ccrs.Globe(semimajor_axis=6377563.396,
+ semiminor_axis=6356256.909, ellipse=None),
+ latitude_true_scale=true_scale_lat)
+
+ res = merc_cs.as_cartopy_crs()
+ self.assertEqual(res, expected)
+
+
+class Test_as_cartopy_projection(tests.IrisTest):
+ def test_simple(self):
+ # Check that a projection set up with all the defaults is correctly
+ # converted to a cartopy projection.
+ merc_cs = Mercator()
+ res = merc_cs.as_cartopy_projection()
+ expected = ccrs.Mercator(globe=ccrs.Globe())
+ self.assertEqual(res, expected)
+
+ def test_extra_kwargs(self):
+ longitude_of_projection_origin = 90.0
+ true_scale_lat = 14.0
+ ellipsoid = GeogCS(semi_major_axis=6377563.396,
+ semi_minor_axis=6356256.909)
+
+ merc_cs = Mercator(
+ longitude_of_projection_origin,
+ ellipsoid=ellipsoid,
+ standard_parallel=true_scale_lat)
+
+ expected = ccrs.Mercator(
+ central_longitude=longitude_of_projection_origin,
+ globe=ccrs.Globe(semimajor_axis=6377563.396,
+ semiminor_axis=6356256.909, ellipse=None),
+ latitude_true_scale=true_scale_lat)
+
+ res = merc_cs.as_cartopy_projection()
+ self.assertEqual(res, expected)
+
+
+if __name__ == "__main__":
+ tests.main()