def set_roi(self, shape=None, geometry=None, crs=wgs84, grid=None, corners=None, noerase=False): """Set a region of interest for the dataset. If set succesfully, a ROI is simply a mask of the same size as the dataset's grid, obtained with the .roi attribute. I haven't decided yet if the data should be masekd out when a ROI has been set. Parameters ---------- shape: path to a shapefile geometry: a shapely geometry crs: the crs of the geometry grid: a Grid object corners: a ((x0, y0), (x1, y1)) tuple of the corners of the square to subset the dataset to. The coordinates are not expressed in wgs84, set the crs keyword noerase: set to true in order to add the new ROI to the previous one """ # The rois are always defined on the original grids, but of course # we take that into account when a subset is set (see roi # decorator below) ogrid = self._ogrid # Initial mask if noerase and (self.roi is not None): mask = self.roi else: mask = np.zeros((ogrid.ny, ogrid.nx), dtype=np.int16) # Several cases if shape is not None: gdf = sio.read_shapefile(shape) gis.transform_geopandas(gdf, to_crs=ogrid.corner_grid, inplace=True) if rasterio is None: raise ImportError('This feature needs rasterio') from rasterio.features import rasterize with rasterio.Env(): mask = rasterize(gdf.geometry, out=mask) if geometry is not None: geom = gis.transform_geometry(geometry, crs=crs, to_crs=ogrid.corner_grid) if rasterio is None: raise ImportError('This feature needs rasterio') from rasterio.features import rasterize with rasterio.Env(): mask = rasterize(np.atleast_1d(geom), out=mask) if grid is not None: _tmp = np.ones((grid.ny, grid.nx), dtype=np.int16) mask = ogrid.map_gridded_data(_tmp, grid, out=mask).filled(0) if corners is not None: cgrid = self._ogrid.center_grid xy0, xy1 = corners x0, y0 = cgrid.transform(*xy0, crs=crs, nearest=True) x1, y1 = cgrid.transform(*xy1, crs=crs, nearest=True) mask[np.min([y0, y1]):np.max([y0, y1])+1, np.min([x0, x1]):np.max([x0, x1])+1] = 1 self.roi = mask
def set_roi(self, shape=None, geometry=None, crs=wgs84, grid=None, corners=None, noerase=False): """Set a region of interest for the dataset. If set succesfully, a ROI is simply a mask of the same size as the dataset's grid, obtained with the .roi attribute. I haven't decided yet if the data should be masekd out when a ROI has been set. Parameters ---------- shape: path to a shapefile geometry: a shapely geometry crs: the crs of the geometry grid: a Grid object corners: a ((x0, y0), (x1, y1)) tuple of the corners of the square to subset the dataset to. The coordinates are not expressed in wgs84, set the crs keyword noerase: set to true in order to add the new ROI to the previous one """ # The rois are always defined on the original grids, but of course # we take that into account when a subset is set (see roi # decorator below) ogrid = self._ogrid # Initial mask if noerase and (self.roi is not None): mask = self.roi else: mask = np.zeros((ogrid.ny, ogrid.nx), dtype=np.int16) # Several cases if shape is not None: gdf = sio.read_shapefile(shape) gis.transform_geopandas(gdf, to_crs=ogrid.corner_grid, inplace=True) with rasterio.Env(): mask = features.rasterize(gdf.geometry, out=mask) if geometry is not None: geom = gis.transform_geometry(geometry, crs=crs, to_crs=ogrid.corner_grid) with rasterio.Env(): mask = features.rasterize(np.atleast_1d(geom), out=mask) if grid is not None: _tmp = np.ones((grid.ny, grid.nx), dtype=np.int16) mask = ogrid.map_gridded_data(_tmp, grid, out=mask).filled(0) if corners is not None: cgrid = self._ogrid.center_grid xy0, xy1 = corners x0, y0 = cgrid.transform(*xy0, crs=crs, nearest=True) x1, y1 = cgrid.transform(*xy1, crs=crs, nearest=True) mask[np.min([y0, y1]):np.max([y0, y1])+1, np.min([x0, x1]):np.max([x0, x1])+1] = 1 self.roi = mask
def region_of_interest(self, shape=None, geometry=None, grid=None, corners=None, crs=wgs84, roi=None, all_touched=False): """Computes a region of interest (ROI). A ROI is simply a mask of the same size as the grid. Parameters ---------- shape : str path to a shapefile geometry : geometry a shapely geometry (don't forget the crs keyword) grid : Grid a Grid object which extent will form the ROI corners : tuple a ((x0, y0), (x1, y1)) tuple of the corners of the square to subset the dataset to (don't forget the crs keyword) crs : crs, default wgs84 coordinate reference system of the geometry and corners roi : ndarray add the new region_of_interest to a previous one (useful for multiple geometries for example) all_touched : boolean pass-through argument for rasterio.features.rasterize, indicating that all grid cells which are clipped by the shapefile defining the region of interest should be included (default=False) """ # Initial mask if roi is not None: mask = np.array(roi, dtype=np.int16) else: mask = np.zeros((self.ny, self.nx), dtype=np.int16) # Collect keyword arguments, overriding anything the user # inadvertently added rasterize_kws = dict(out=mask, all_touched=all_touched) # Several cases if shape is not None: import pandas as pd inplace = False if not isinstance(shape, pd.DataFrame): from salem.sio import read_shapefile shape = read_shapefile(shape) inplace = True # corner grid is needed for rasterio shape = transform_geopandas(shape, to_crs=self.corner_grid, inplace=inplace) import rasterio with rasterio.Env(): mask = rasterio.features.rasterize(shape.geometry, **rasterize_kws) if geometry is not None: import rasterio # corner grid is needed for rasterio geom = transform_geometry(geometry, crs=crs, to_crs=self.corner_grid) with rasterio.Env(): mask = rasterio.features.rasterize(np.atleast_1d(geom), **rasterize_kws) if grid is not None: _tmp = np.ones((grid.ny, grid.nx), dtype=np.int16) mask = self.map_gridded_data(_tmp, grid, out=mask).filled(0) if corners is not None: cgrid = self.center_grid xy0, xy1 = corners x0, y0 = cgrid.transform(*xy0, crs=crs, nearest=True) x1, y1 = cgrid.transform(*xy1, crs=crs, nearest=True) mask[np.min([y0, y1]):np.max([y0, y1]) + 1, np.min([x0, x1]):np.max([x0, x1]) + 1] = 1 return mask
def region_of_interest(self, shape=None, geometry=None, grid=None, corners=None, crs=wgs84, roi=None): """Computes a region of interest (ROI). A ROI is simply a mask of the same size as the grid. Parameters ---------- shape : str path to a shapefile geometry : geometry a shapely geometry (don't forget the crs keyword) grid : Grid a Grid object which extent will form the ROI corners : tuple a ((x0, y0), (x1, y1)) tuple of the corners of the square to subset the dataset to (don't forget the crs keyword) crs : crs, default wgs84 coordinate reference system of the geometry and corners roi : ndarray add the new region_of_interest to a previous one (useful for multiple geometries for example) """ # Initial mask if roi is not None: mask = np.array(roi, dtype=np.int16) else: mask = np.zeros((self.ny, self.nx), dtype=np.int16) # Several cases if shape is not None: import pandas as pd inplace = False if not isinstance(shape, pd.DataFrame): from salem.sio import read_shapefile shape = read_shapefile(shape) inplace = True # corner grid is needed for rasterio shape = transform_geopandas(shape, to_crs=self.corner_grid, inplace=inplace) import rasterio with rasterio.Env(): mask = rasterio.features.rasterize(shape.geometry, out=mask) if geometry is not None: import rasterio # corner grid is needed for rasterio geom = transform_geometry(geometry, crs=crs, to_crs=self.corner_grid) with rasterio.Env(): mask = rasterio.features.rasterize(np.atleast_1d(geom), out=mask) if grid is not None: _tmp = np.ones((grid.ny, grid.nx), dtype=np.int16) mask = self.map_gridded_data(_tmp, grid, out=mask).filled(0) if corners is not None: cgrid = self.center_grid xy0, xy1 = corners x0, y0 = cgrid.transform(*xy0, crs=crs, nearest=True) x1, y1 = cgrid.transform(*xy1, crs=crs, nearest=True) mask[np.min([y0, y1]):np.max([y0, y1]) + 1, np.min([x0, x1]):np.max([x0, x1]) + 1] = 1 return mask