eodal.core.raster module¶
This module defines the RasterCollection class which is the basic class for reading,
plotting, transforming, manipulating and writing (geo-referenced) raster data in an
intuitive, object-oriented way (in terms of software philosophy).
A RasterCollection is collection of to zero to N ~eodal.core.band.Band instances,
in which each band denotes a two-dimensional array at its core. The RasterCollection
class allows thereby to handle Band instances with different spatial reference
systems, spatial resolutions (i.e., grid cell sizes) and spatial extents.
Besides that, RasterCollection is a super class from which sensor-specific classes
for reading (satellite) raster image data inherit.
import numpy as np
from eodal.core.raster import RasterCollection
from eodal.core.band import Band
from eodal.core.band import GeoInfo
# New collection from `numpy.ndarray`
# Define GeoInfo and Array first and use them to initialize a new RasterCollection
# instance:
# provide EPSG code
epsg = 32633
# provide upper left (ul) x and y coordinate (in units of the coordinate system
# given by the EPSG code defined above)
ulx, uly = 300000, 5100000
# provide pixel size (spatial resolution). Note that resolution in y direction is
# negative because we start at the upper left corner
pixres_x, pixres_y = 10, -10
# get a new GeoInfo object
geo_info = GeoInfo(epsg=epsg,ulx=ulx,uly=uly,pixres_x=pixres_x,pixres_y=pixres_y)
# define a band name for the band data to add
band_name = 'random'
# optionally, you can also asign a `band_alias` (e.g., color name)
band_alias = 'blue'
# let's define some random numbers in a 2-d array
values = np.random.random(size=(100,120))
# get the RasterCollection object
raster = RasterCollection(
band_constructor=Band,
band_name=band_name,
values=values,
band_alias=band_alias,
geo_info=geo_info
)
Copyright (C) 2022 Lukas Valentin Graf
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
- class eodal.core.raster.RasterCollection(band_constructor: Callable[[...], Band] | None = None, scene_properties: SceneProperties | None = None, *args, **kwargs)[source]¶
Bases:
MutableMappingBasic class for storing and handling single and multi-band raster data from which sensor- or application-specific classes inherit.
A
RasterDataHandlercontains zero to N instances of ~eodal.core.Band. Bands are always indexed using their band name, therefore the band name must be unique!- Attrib scene_properties:
instance of SceneProperties for storing scene (i.e., dataset-wide) metadata. Designed for the usage with remote sensing data.
- Attrib band_names:
names of the bands currently loaded into the collection
- Attrib band_aliases:
optional aliases of the band names. Thus, a band can be accessed either by its name or its alias.
- Attrib empty:
True if no bands are loaded into the collection, False if bands are available
- Attrib has_band_aliases:
True if the band aliases are provided, False otherwise
- Attrib collection:
dictionary-like collection of loaded raster
Bandinstances
- __init__(band_constructor: Callable[[...], Band] | None = None, scene_properties: SceneProperties | None = None, *args, **kwargs)[source]¶
Initializes a new RasterCollection with 0 up to n bands
- Parameters:
band_constructor – optional callable returning an ~eodal.core.Band instance.
scene_properties – optional scene properties of the dataset handled by the current
RasterCollectioninstanceargs – arguments to pass to band_constructor or one of its class methods (Band.from_rasterio, Band.from_vector)
kwargs – key-word arguments to pass to band_constructor or one of its class methods (Band.from_rasterio, Band.from_vector)
- add_band(band_constructor: Callable[[...], Band] | Band, *args, **kwargs) None[source]¶
Adds a band to the collection of raster bands.
Raises an error if a band with the same name already exists (unique name constraint)
- Parameters:
band_constructor – callable returning a ~eodal.core.Band instance or existing Band instance
args – arguments to pass to band_constructor or one of its class methods (Band.from_rasterio, Band.from_vector)
kwargs – key-word arguments to pass to band_constructor or one of its class methods (Band.from_rasterio, Band.from_vector)
- apply(func: Callable, *args, **kwargs) Any[source]¶
Apply a custom function to a
RasterCollection.- Parameters:
func – custom callable taking the
RasterCollectionas first argumentargs – optional arguments to pass to func
kwargs – optional keyword arguments to pass to func
- Returns:
results of func
- band_summaries(band_selection: List[str] | None = None, **kwargs) GeoDataFrame[source]¶
Descriptive band statistics by calling Band.reduce for bands in a collection.
- Parameters:
band_selection – selection of bands to process. If not provided uses all bands
kwargs – optional keyword arguments to pass to ~eodal.core.band.Band.reduce. Use by to get descriptive statistics by selected geometry features (e.g., single polygons).
- Returns:
GeoDataFramewith descriptive statistics for all bands selected and geometry features passed (optional)
- calc_si(si_name: str, inplace: bool | None = False, band_mapping: Dict[str, str] | None = {}) None | ndarray | MaskedArray[source]¶
Calculates a spectral index based on color-names (set as band aliases)
- Parameters:
si_name – name of the spectral index to calculate (e.g., ‘NDVI’).
inplace – if False, returns the calculated SI as numpy array (default), else adds the calculated SI as a new band to the RasterCollection object.
band_mapping – ..versionadd 0.2.2:: optional band mapping to use different color names instead of the default ones (e.g., nir_2 instead of nir_1 as default near-infrared band, which might be helpful for some sensor with more than one NIR band such as Sentinel-2 MSI). See ~`eodal.core.spectral_indices.SpectralIndices` how band_mapping must look like.
- Returns:
np.ndarrayornp.ma.MaskedArrayif inplace is False, None otherwise (is added as band to the collection)
- clip_bands(band_selection: List[str] | None = None, inplace: bool | None = False, **kwargs)[source]¶
Clip bands in RasterCollection to a user-defined spatial bounds.
- Parameters:
band_selection – optional list of bands to clip. If not provided takes all available bands.
inplace – if False (default) returns a copy of the
RasterCollectioninstance with the changes applied. If True overwrites the values in the current instance.**kwargs –
key-word arguments to pass to Band.clip method.
- property collection: MutableMapping¶
collection of the bands currently loaded
- drop_band(band_name: str)[source]¶
Deletes a band from the current collection
- Parameters:
band_name – name of the band to drop
- classmethod from_multi_band_raster(fpath_raster: Path, band_idxs: List[int] | None = None, band_names_src: List[str] | None = None, band_names_dst: List[str] | None = None, band_aliases: List[str] | None = None, **kwargs)[source]¶
Loads bands from a multi-band raster file into a new RasterCollection instance.
Wrapper around ~eodal.core.Band.from_rasterio for 1 to N raster bands.
- Parameters:
fpath_raster – file-path to the raster file (technically spoken, this can also have just a single band)
band_idxs – optional list of band indices in the raster dataset to read. If not provided (default) all bands are loaded. Ignored if band_names_src is provided.
band_names_src – optional list of band names in the raster dataset to read. If not provided (default) all bands are loaded. If band_idxs and band_names_src are provided, the former is ignored.
band_names_dst – optional list of band names in the resulting collection. Must match the length and order of band_idxs or band_names_src
band_aliases – optional list of aliases to use for aliasing of band names
kwargs – optional key-word arguments accepted by ~eodal.core.Band.from_rasterio
- Returns:
RasterCollection instance with loaded bands from the input raster data set.
- get_band(band_name: str) Band | None[source]¶
Returns a single band from the collection or None if the band is not found.
- Parameters:
band_name – band name (or its alias) to return
- Returns:
Bandinstance from band name
- get_band_alias(band_name: str) Dict[str, str] | None[source]¶
Retuns the band_name-alias mapper of a given band in collection if the band has an alias, None instead
- Parameters:
band_name – name of the band for which to return the alias or its name if the alias is provided
- Returns:
mapping of band_name:band_alias (band name is always the key and band_alias is the value)
- get_pixels(vector_features: Path | GeoDataFrame, band_selection: List[str] | None = None) GeoDataFrame[source]¶
Returns pixel values from bands in the collection as
GeoDataFrame.Since a pixel is a dimensionless object (
Point) the extraction method works for raster bands with different pixel sizes, spatial extent and coordinate systems. If a pixel cannot be extracted from a raster band, the band’s nodata value is inserted.- Parameters:
band_selection – optional selection of bands to return
vector_features – file-path or
GeoDataFrameto features defining the pixels to read from the raster bands selected. The geometries can be of typePoint,PolygonorMultiPolygon. In the latter two cases the centroids are used to extract pixel values, whereas for point features the closest raster grid cell is selected.
- Returns:
GeoDataFramewith extracted raster values per pixel or Polygon centroid.
- get_values(band_selection: List[str] | None = None) MaskedArray | ndarray[source]¶
Returns raster values as stacked array in collection.
Note
The selection of bands to return as stacked array must share the same spatial extent, pixel size and coordinate system
- Parameters:
band_selection – optional selection of bands to return
- Returns:
raster band values in their underlying storage type (
numpy.ndarray,numpy.ma.MaskedArray,zarr)
- is_bandstack(band_selection: List[str] | None = None) bool | None[source]¶
Checks if the rasters handled in the collection fulfill the bandstack criteria.
- These criteria are:
all bands have the same CRS
all bands have the same x and y dimension (number of rows and columns)
all bands must have the same upper left corner coordinates
- Parameters:
band_selection – if not None, checks only a list of selected bands. By default, all bands of the current object are checked.
- Returns:
True if the current object fulfills the criteria else False; None if no bands are loaded into the handler’s collection.
- mask(mask: str | ndarray | Band, mask_values: List[Any] | None = None, keep_mask_values: bool | None = False, bands_to_mask: List[str] | None = None, inplace: bool | None = False)[source]¶
Masks pixels of bands in the collection using a boolean array.
Important
The mask band (or mask array) and the bands to mask must have the same shape!
- Parameters:
mask – either a band out of the collection (identified through its band name) or a
numpy.ndarrayof datatype boolean or another Band objectmask_values – if mask is a band out of the collection, a list of values must be specified to create a boolean mask. Ignored if mask is already a boolean
numpy.ndarraykeep_mask_values – if False (default), pixels in mask corresponding to mask_values are masked, otherwise all other pixel values are masked. Ignored if mask is already a boolean
numpy.ndarray.bands_to_mask – bands in the collection to mask based on mask. If not provided, all bands are masked
inplace – if False returns a new RasterCollection (default) otherwise overwrites existing raster band entries
- Returns:
new RasterCollection if inplace==False, None otherwise
- plot_band(band_name: str, **kwargs) Figure[source]¶
Plots a band in the collection of raster bands.
Wrapper method around ~eodal.core.Band.plot.
- Parameters:
band_name – name of the band to plot. Aliasing is supported.
kwargs – key-word arguments to pass to ~eodal.core.Band.plot
- Returns:
~matplotlib.pyplot.Figure with band plotted as map
- plot_multiple_bands(band_selection: List[str] | None = None, ax: Axes | None = None, nodata_color: str | None = 'white', **kwargs)[source]¶
Plots three selected bands in a pseudo RGB with 8bit color-depth.
Important
The bands to plot must have the same spatial resolution, extent and CRS
- Parameters:
band_selection – optional list of bands to plot. If not provided takes the first three bands (or less) to plot
ax – optional matplotlib.axes object to plot onto
nodata_color – ..versionadd:: 0.2.1 Color no-data (masked) pixels should take in the RGB plot. Default is ‘white’. All color names supported by ~matplotlib.colors can be passed.
- Returns:
~matplotlib.pyplot.Figure with band plotted as map in 8bit color depth
- classmethod read_pixels(fpath_raster: Path, vector_features: Path | GeoDataFrame, band_idxs: List[int | None] = None, band_names_src: List[str | None] = None, band_names_dst: List[str | None] = None) GeoDataFrame[source]¶
Wrapper around ~eodal.core.band.read_pixels for raster datasets with multiple bands
Note
The pixels to read are defined by a
GeoDataFrameor file with vector features understood byfiona. If the geometry type is notPointthe centroids will be used for extracting the closest grid cell value.- Parameters:
fpath_raster – file-path to the raster dataset from which to extract pixel values
vector_features – file-path or
GeoDataFrameto features defining the pixels to read from a raster dataset. The geometries can be of typePoint,PolygonorMultiPolygon. In the latter two cases the centroids are used to extract pixel values, whereas for point features the closest raster grid cell is selected.
- ::param band_idxs:
optional list of band indices in the raster dataset to read. If not provided (default) all bands are loaded. Ignored if band_names_src is provided.
- Parameters:
band_names_src – optional list of band names in the raster dataset to read. If not provided (default) all bands are loaded. If band_idxs and band_names_src are provided, the former is ignored.
band_names_dst – optional list of band names in the resulting collection.Must match the length and order of band_idxs or band_names_src.
- Returns:
GeoDataFramewith extracted pixel values. If the vector features defining the sampling points are not within the spatial extent of the raster dataset the pixel values are set to nodata (inferred from the raster source)
- reproject(band_selection: List[str] | None = None, inplace: bool | None = False, **kwargs)[source]¶
Reprojects band in the collection from one coordinate system into another
- Parameters:
band_selection – selection of bands to process. If not provided uses all bands
inplace – if False returns a new RasterCollection (default) otherwise overwrites existing raster band entries
kwargs – key-word arguments to pass to ~eodal.core.Band.reproject
- Returns:
new RasterCollection if inplace==False, None otherwise
- resample(band_selection: List[str] | None = None, inplace: bool | None = False, **kwargs)[source]¶
Resamples band in the collection into a different spatial resolution
- Parameters:
band_selection – selection of bands to process. If not provided uses all bands
inplace – if False returns a new RasterCollection (default) otherwise overwrites existing raster band entries
kwargs – key-word arguments to pass to ~eodal.core.Band.resample
- Returns:
new RasterCollection if inplace==False, None otherwise
- scale(band_selection: List[str] | None = None, inplace: bool | None = False, **kwargs)[source]¶
Applies gain and offset factors to bands in collection
- Parameters:
band_selection – selection of bands to process. If not provided uses all bands
inplace – if False returns a new RasterCollection (default) otherwise overwrites existing raster band entries
kwargs – optional kwargs to pass to ~eodal.core.band.Band.scale_data
- Returns:
RasterCollection if inplace == False, None otherwise
- to_dataframe(band_selection: List[str] | None = None) GeoDataFrame[source]¶
Converts the bands in collection to a
GeoDataFrame- Parameters:
band_selection – selection of bands to process. If not provided uses all bands
- Returns:
GeoDataFramewith point-like features denoting single pixel values across bands in the collection
- to_rasterio(fpath_raster: Path, band_selection: List[str] | None = None, use_band_aliases: bool | None = False, as_cog: bool | None = False) None[source]¶
Writes bands in collection to a raster dataset on disk using
rasteriodrivers- Parameters:
fpath_raster – file-path to the raster dataset (existing ones will be overwritten!)
band_selection – selection of bands to process. If not provided uses all bands
use_band_aliases – use band aliases instead of band names for setting raster band descriptions to the output dataset
as_cog – write the raster dataset as cloud-optimized GeoTIFF. This requires the
rio-cogeopackage to be installed. Disabled by default.
- class eodal.core.raster.RasterOperator[source]¶
Bases:
OperatorBand operator supporting basic algebraic operations on RasterCollection objects
- classmethod calc(a, other: Band | Number | ndarray, operator: str, inplace: bool | None = False, band_selection: List[str] | None = None, right_sided: bool | None = False) None | ndarray[source]¶
executes a custom algebraic operator on RasterCollection objects
- Parameters:
a – RasterCollection object with values (non-empty)
other – Band object, scalar, 3-dimensional numpy.array, or RasterCollection to use on the right-hand side of the operator. If a numpy.array is passed the array must have either shape (1,nrows,ncols) or (nband,nrows,ncols) where nrows is the number of rows in a, ncols the number of columns in a and nbands the number of bands in a or the selection thereof. The latter method does not work if the bands in a selected differ in their shape.
operator – symbolic representation of the operator (e.g., ‘+’ for addition)
inplace – returns a new RasterCollection object if False (default) otherwise overwrites the current RasterCollection data in a
band_selection – optional selection of bands in a to which apply the operation
right_sided – optional flag indicated that the order of a and other has to be switched. False by default. Set to True if the order of argument matters, i.e., for right-hand sided expression in case of subtraction, division and power.
- Returns:
numpy.ndarray if inplace is False, None instead
- class eodal.core.raster.SceneProperties(acquisition_time: datetime | Number | None = None, platform: str | None = None, sensor: str | None = None, processing_level: ProcessingLevels | None = ProcessingLevels.UNKNOWN, product_uri: str | None = None, mode: str | None = None)[source]¶
Bases:
objectA class for storing scene-relevant properties
- Attribute acquisition_time:
image acquisition time
- Attribute platform:
name of the imaging platform
- Attribute sensor:
name of the imaging sensor
- Attribute processing_level:
processing level of the remotely sensed data (if known and applicable)
- Attribute product_uri:
unique product (scene) identifier
- Attribute mode:
imaging mode of SAR sensors
- __init__(acquisition_time: datetime | Number | None = None, platform: str | None = None, sensor: str | None = None, processing_level: ProcessingLevels | None = ProcessingLevels.UNKNOWN, product_uri: str | None = None, mode: str | None = None)[source]¶
Class constructor
- Parameters:
acquisition_time – image acquisition time. Can be a timestamp or any kind of numeric index.
platform – name of the imaging platform
sensor – name of the imaging sensor
processing_level – processing level of the remotely sensed data (if known and applicable)
product_uri – unique product (scene) identifier
- Attribute mode:
imaging mode of SAR sensors
- are_populated() bool[source]¶
returns a Boolean flag indicating if the class attributes have been populated with actual data or still equal defaults.
A scene must have at least a time stamp.
- property processing_level: ProcessingLevels¶
current processing level