def _calculate_grid_edges(self, var_name): """Calculate coordinate grid from product's projection.""" from osgeo.gdal import Open from osgeo import osr variable = Open(var_name) sin = osr.SpatialReference() sin.ImportFromWkt(variable.GetProjection()) wgs84 = osr.SpatialReference() wgs84.ImportFromEPSG(4326) tx = osr.CoordinateTransformation(sin, wgs84) transform = np.vectorize(tx.TransformPoint) # +1 as we want grid cell edges x0, dx, _, y0, _, dy = variable.GetGeoTransform() x_ = x0 + dx * np.arange(variable.RasterXSize + 1) y_ = y0 + dy * np.arange(variable.RasterYSize + 1) x, y = np.meshgrid(x_, y_) lat_edges, lon_edges, _ = transform(x, y) def make_corner_list(arr): """Ravel a grid of cell edges into an ordered list of corners.""" from acp_utils import rolling_window out = rolling_window(arr, (2, 2)) out = out.reshape(out.shape[:-2] + (4, )) out[..., 2:4] = out[..., [3, 2]] return out lat_bounds = make_corner_list(lat_edges) lon_bounds = make_corner_list(lon_edges) return lat_bounds, lon_bounds
def test_phase_data_properties(self): # Use raw GDAL to isolate raster reading from Ifg functionality ds = Open(self.ifg.data_path) data = ds.GetRasterBand(1).ReadAsArray() del ds self.ifg.open() # test full array and row by row access assert_array_equal(data, self.ifg.phase_data) for y, row in enumerate(self.ifg.phase_rows): assert_array_equal(data[y], row) # test the data is cached if changed crd = (5, 4) orig = self.ifg.phase_data[crd] self.ifg.phase_data[crd] *= 2 nv = self.ifg.phase_data[crd] # pull new value out again self.assertEqual(nv, 2 * orig)
def load_dem() -> Dataset: """ Loads the file 'dem.tif' on the current system. Returns ------- Dataset The example digital elevation model. """ file_path = PkgDataAccess.locate_dem() LOG.info("Reading DEM from '%s' ...", file_path) dem = Open(file_path) return dem
def _calculate_grid_centres(self, var_name): """Calculate coordinates of cell centres from project's projection""" from osgeo.gdal import Open from osgeo import osr variable = Open(var_name) sin = osr.SpatialReference() sin.ImportFromWkt(variable.GetProjection()) wgs84 = osr.SpatialReference() wgs84.ImportFromEPSG(4326) tx = osr.CoordinateTransformation(sin, wgs84) transform = np.vectorize(tx.TransformPoint) x0, dx, _, y0, _, dy = variable.GetGeoTransform() x_ = x0 + dx * np.arange(0.5, variable.RasterXSize) y_ = y0 + dy * np.arange(0.5, variable.RasterYSize) x, y = np.meshgrid(x_, y_) lat_data, lon_data, _ = transform(x, y) return lat_data, lon_data
def _convert_to_tif( partial_coverage_tiles: List[PartialCoverageTile], wms_crs_code: str ) -> None: for tile in partial_coverage_tiles: if os.path.exists(tile.wms_path): logging.debug(f"Converting {tile.wms_path} to {tile.tif_path}") src_file = Open(tile.wms_path, GA_ReadOnly) Translate( tile.tif_path, src_file, format="GTiff", noData=None, outputSRS=wms_crs_code, # Translate expects bounds in format ulX, ulY, lrX, lrY so flip minY and maxY outputBounds=(tile.x_min, tile.y_max, tile.x_max, tile.y_min), ) if remove_intermediaries(): os.remove(tile.wms_path) else: logging.warn(f"Expected file {tile.wms_path} does not exist")
def __init__( self, dem_path: str, model_name: Optional[str] = None, ela: int = 2850, m: float = 0.006, plot: bool = True, ) -> None: """ Class constructor for the GlacierFlowModel class. Parameters ---------- dem_path : str Path to the file that holds the DEM. model_name: Optional[str] Name of the model, if not provided the name of the input dem file without extension is set. ela : int, default 2850 The equilibrium-line altitude (ELA) marks the area or zone on a glacier where accumulation is balanced by ablation over a 1-year period. m : float, default 0.006 Glacier mass balance gradient [m/m], the linear relationship between altitude and mass balance. plot : bool, default True Visualization of the simulation process. Returns ------- None """ # Load DEM ------------------------------------------------------------ dem = Open(dem_path) band = dem.GetRasterBand(1) ele = band.ReadAsArray().astype(np.float32) # Instance variables -------------------------------------------------- self.model_name = Path( dem_path).stem if model_name is None else model_name self.dem_path = dem_path # Mass balance parameters self.m = m # Mass balance gradient self.ela_start = ela # Equilibrium line altitude self._setup_params() # Variable parameters (i, ela, steady_state) # 2D arrays self.ele_orig = np.copy(ele) # Original topography self._setup_ndarrays() # Variable arrays (ele, h, u ,hs) # Coordinate reference system and dem resolution self._geo_trans = dem.GetGeoTransform() self._geo_proj = dem.GetProjection() self.res = self._geo_trans[1] # Geographical extent of the dem nrows, ncols = ele.shape x0, dx, dxdy, y0, dydx, dy = self._geo_trans x1 = x0 + dx * ncols y1 = y0 + dy * nrows self.extent = (x0, x1, y1, y0) # Setup statistics self._setup_stats() # Setup plot self.plot = plot
def _calculate_grid_time(self, var_name, lat_data, lon_data): """Approximate time from a pair of corresponding MOD03 files""" from osgeo.gdal import Open from scipy.interpolate import griddata def fetch_MOD03_coordinates(start_time, aqua=False): import os.path from glob import glob from pyhdf.SD import SD from pyhdf.error import HDF4Error # Locate MOD03 file search_path = start_time.strftime( os.path.join(self.mod03_path, "MOD03.A%Y%j.%H%M.061*hdf")) if aqua: # NOTE: System dependent approximation search_path = search_path.replace("MOD", "MYD") try: mod03_file = glob(search_path)[0] except IndexError: raise FileNotFoundError("MOD03: " + search_path) # Read space-time grid from that file try: file_object = SD(mod03_file) dims = file_object.datasets()["Longitude"][1] count = dims[0] // 10, dims[1] // 10 mod_lon = _get_hdf_data(file_object, "Longitude", start=(0, 2), count=count, stride=(10, 10)) mod_lat = _get_hdf_data(file_object, "Latitude", start=(0, 2), count=count, stride=(10, 10)) mod_time = _get_hdf_data(file_object, "EV start time", count=count[:1]) file_object.end() except HDF4Error: raise IOError("Corrupted file: " + mod03_file) return mod_lon, mod_lat, mod_time time_data = [] variable = Open(var_name) meta = variable.GetMetadata_Dict() for timestamp in meta["Orbit_time_stamp"].split(): # Parse time stamp start_time = dt.datetime.strptime(timestamp[:-1], "%Y%j%H%M") try: # Interpolate time from MOD03 files mod_lon0, mod_lat0, mod_time0 = fetch_MOD03_coordinates( start_time - dt.timedelta(seconds=300), timestamp[-1] == "A") mod_lon1, mod_lat1, mod_time1 = fetch_MOD03_coordinates( start_time, timestamp[-1] == "A") mod_lon = concatenate([mod_lon0, mod_lon1]) mod_lat = concatenate([mod_lat0, mod_lat1]) mod_time = concatenate([mod_time0, mod_time1]) if (mod_lon.max() - mod_lon.min()) > 180.: # Sodding dateline mod_lon[mod_lon < 0.] += 360. # Interpolate that grid onto the sinusoidal projection time = griddata((mod_lon.ravel(), mod_lat.ravel()), np.tile(mod_time, mod_lon.shape[1]), (lon_data, lat_data), method="nearest") except (FileNotFoundError, TypeError): # Just use the orbit start time seconds = start_time - MODIS_REFERENCE_TIME time = np.full(lat_data.shape, seconds.total_seconds()) time_data.append(time) return concatenate(time_data)