Skip to content

Commit

Permalink
First pass of pyproj crs in Iris (just for stereographic)
Browse files Browse the repository at this point in the history
  • Loading branch information
Will Benfold committed Apr 22, 2022
1 parent c151b10 commit 90f02f7
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 55 deletions.
64 changes: 35 additions & 29 deletions lib/iris/coord_systems.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import cartopy.crs as ccrs
import numpy as np
import pyproj


def _arg_default(value, default, cast_as=float):
Expand Down Expand Up @@ -906,27 +907,41 @@ def __init__(
"""

#: True latitude of planar origin in degrees.
self.central_lat = float(central_lat)

#: True longitude of planar origin in degrees.
self.central_lon = float(central_lon)

#: X offset from planar origin in metres.
self.false_easting = _arg_default(false_easting, 0)

#: Y offset from planar origin in metres.
self.false_northing = _arg_default(false_northing, 0)

#: Latitude of true scale.
self.true_scale_lat = _arg_default(
true_scale_lat, None, cast_as=_float_or_None
self._crs = pyproj.crs.CRS.from_user_input(
ccrs.Stereographic(
central_latitude=central_lat,
central_longitude=central_lon,
false_easting=false_easting,
false_northing=false_northing,
true_scale_latitude=true_scale_lat,
scale_factor=None,
globe=self._ellipsoid_to_globe(ellipsoid, ccrs.Globe()),
)
)
# N.B. the way we use this parameter, we need it to default to None,
# and *not* to 0.0 .

#: Ellipsoid definition (:class:`GeogCS` or None).
self.ellipsoid = ellipsoid
@classmethod
def from_pyproj(cls, crs):
obj = cls.__new__(cls)
super(Stereographic, obj).__init__()
obj._crs = crs
return obj

def __getattr__(self, name):
if name == "central_lat":
return self._crs.to_dict()["lat_0"]
if name == "central_lon":
return self._crs.to_dict()["lon_0"]
if name == "false_easting":
return self._crs.to_cf()["false_easting"]
if name == "false_northing":
return self._crs.to_cf()["false_northing"]
if name == "true_scale_lat":
return None
if name == "ellipsoid":
return self._crs.ellipsoid
if name == "datum":
return self._crs.datum
return super(Stereographic, self).__getattribute__(name)

def __repr__(self):
return (
Expand All @@ -944,16 +959,7 @@ def __repr__(self):
)

def as_cartopy_crs(self):
globe = self._ellipsoid_to_globe(self.ellipsoid, ccrs.Globe())

return ccrs.Stereographic(
self.central_lat,
self.central_lon,
self.false_easting,
self.false_northing,
self.true_scale_lat,
globe=globe,
)
return ccrs.CRS(self._crs)

def as_cartopy_projection(self):
return self.as_cartopy_crs()
Expand Down
33 changes: 7 additions & 26 deletions lib/iris/fileformats/_nc_load_rules/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,35 +395,16 @@ def build_stereographic_coordinate_system(engine, cf_grid_var):
grid mapping variable.
"""
major, minor, inverse_flattening = _get_ellipsoid(cf_grid_var)
from pyproj import CRS

latitude_of_projection_origin = getattr(
cf_grid_var, CF_ATTR_GRID_LAT_OF_PROJ_ORIGIN, None
)
longitude_of_projection_origin = getattr(
cf_grid_var, CF_ATTR_GRID_LON_OF_PROJ_ORIGIN, None
crs = CRS.from_cf(
{
key: getattr(cf_grid_var, key)
for key in cf_grid_var.cf_data.ncattrs()
}
)
false_easting = getattr(cf_grid_var, CF_ATTR_GRID_FALSE_EASTING, None)
false_northing = getattr(cf_grid_var, CF_ATTR_GRID_FALSE_NORTHING, None)
# Iris currently only supports Stereographic projections with a scale
# factor of 1.0. This is checked elsewhere.

ellipsoid = None
if (
major is not None
or minor is not None
or inverse_flattening is not None
):
ellipsoid = iris.coord_systems.GeogCS(major, minor, inverse_flattening)

cs = iris.coord_systems.Stereographic(
latitude_of_projection_origin,
longitude_of_projection_origin,
false_easting,
false_northing,
true_scale_lat=None,
ellipsoid=ellipsoid,
)
cs = iris.coord_systems.Stereographic.from_pyproj(crs)

return cs

Expand Down

0 comments on commit 90f02f7

Please sign in to comment.