def __init__(self, obj): def lonlat(lon, lat): from pyproj import Geod geo = Geod(ellps='WGS84') x = [np.min(lon), np.max(lon), np.min(lat), np.max(lat)] return { 'lon_0': .5 * np.sum(x[:2]), 'lat_0': .5 * np.sum(x[2:]), 'width': geo.inv(x[0], x[3], x[1], x[3])[2], 'height': geo.inv(x[0], x[2], x[0], x[3])[2], 'lat_1': -10, 'lat_2': -40 } def attshw(file): h, w = file.variables['XLONG_M'].shape[-2:] return atts(file, w, h) # this doesn't work if one of the calls to try_list succeeds but returns the wrong # object for the init call to Basemap super().__init__(projection='lcc', **hh.try_list( obj, lambda x: lonlat(x['lon'], x['lat']), lambda x: x.to_dict(), lambda x: hh.try_list( x, atts, attshw, lambda x: lonlat(hh.g2d(x.variables['XLONG']), hh.g2d(x.variables['XLAT'])), ), lambda x: lonlat(*x), lambda x: lonlat( (lambda a, b: b, a)(*x[1].latlons())))) try: self._lonlat = hh.lonlat(obj) except: pass
def project(cls, ds, stations): """Project coordinates from a netCDF file and station longitude / latitude data first, then call :meth:`.compute`. :param ds: Dataset containing the coordinate variables and projection paramters :type ds: :class:`~xarray.Dataset` :param stations: DataFrame containing the locations (longitude / latitude) for which the surrounding 4 points should be determined (as returned from :meth:`.CEAZA.Downloader.get_stations`) :type stations: :class:`~pandas.DataFrame` :returns: see :class:`.Squares` for description of returned DataArray :rtype: :class:`~xarray.DataArray` """ from helpers import g2d from pyproj import Proj pr = Proj(**proj_params(ds)) x, y = pr(g2d(ds.XLONG), g2d(ds.XLAT)) k, l = pr(*stations.loc[:, ('lon', 'lat')].as_matrix().T) return cls.compute(x, y, k, l)
def xr_interp(v, proj_params, stations, time=True, method='linear', return_type='pandas', dt=-4): p = Proj(**proj_params) ij = p(*stations.loc[:, ('lon', 'lat')].as_matrix().T) lon, lat, tv = hh.coord_names(v, 'lon', 'lat', 'time') xy = p(hh.g2d(v.coords[lon]), hh.g2d(v.coords[lat])) x = np.array(v).squeeze() if time: t = v[tv] + np.timedelta64(dt, 'h') df = grid_interp(xy, x, ij, stations.index, t, method=method) else: df = grid_interp(xy, hh.g2d(x), ij, stations.index, method=method) return df if return_type == 'pandas' else xr.DataArray(df)
def interp_nc(nc, var, stations, time=True, tz=False, method='linear', map=None): m = mp.basemap(nc) if map is None else map xy = m.xy() ij = m(*hh.lonlat(stations)) x = nc.variables[var][:].squeeze() if time: t = pd.DatetimeIndex(hh.get_time(nc)) if tz: t = t.tz_localize('UTC').tz_convert(hh.CEAZAMetTZ()) else: t -= np.timedelta64(4, 'h') return sp.grid_interp(xy, x, ij, stations.index, t, method=method) else: return sp.grid_interp(xy, hh.g2d(x), ij, stations.index, method=method)