I'm using the cdsapi python package to download ERA5 data in netcdf format. I'd like to plot it alongside data from a GPS track and so I'm trying to ensure that the coordinate reference systems (CRS) of both datasets are the same. Ideally, I'd like to convert the ERA5 data to WGS84.
When I open the ERA5 netcdf data with xarray, no CRS is recognized. I've found the spatial reference/earth model used in ERA5 is a sphere with radius 6367.47 km (assuming netcdf inherits from GRIB1 instead of GRIB2), but I can't find a name for this (incomplete?) CRS and don't understand how to use this information to convert the ERA5 data to WGS84.
The comment on this question suggests that I can just convert the longitude values of my ERA5 data to values between -180 and 180, set the CRS to WGS84, and be done with it. But this doesn't seem right, because the WGS84 uses an ellipsoid rather than a sphere to derive the coordinates of physical locations. How can I best convert the ERA5 data to WGS84? I'm interested in both the relevant theory and its practical application (preferably in python).
Here's a minimum working example of my current approach. First I download data using the following code.
import cdsapi
client = cdsapi.Client()
client.retrieve(
'reanalysis-era5-single-levels', {
'product_type': 'reanalysis',
'variable': '2m_temperature',
'year': '2017',
'month': '12',
'day': '17',
'time': '00:00',
'area': [90, 0, 0, 360],
'grid': [1.0, 1.0],
'format': 'netcdf'
},
'era5_test.nc')
Then I load the data with xarray
and convert it to a GeoDataFrame
.
import xarray as xr
import geopandas as gpd
ds = xr.open_dataset('era5_test.nc')
df = ds.to_dataframe().reset_index()
gdf = gpd.GeoDataFrame(df, geometry = gpd.points_from_xy(df['longitude'],
df['latitude']))
Then I transform the longitude values and set the CRS to WGS84.
import numpy as np
def transform_era5_lon_to_wgs84_lon(lon):
return np.mod(lon + 180, 360) - 360
gdf = gdf.apply(lambda col: col.apply(tranfrom_era5_lon_to_wgs84_lon)
if col.name == 'longitude' else col)
gdf.crs = {'init': 'epsg:4326'}