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: MutableMapping

Basic class for storing and handling single and multi-band raster data from which sensor- or application-specific classes inherit.

A RasterDataHandler contains 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 Band instances

__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 RasterCollection 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)

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 RasterCollection as first argument

  • args – optional arguments to pass to func

  • kwargs – optional keyword arguments to pass to func

Returns:

results of func

property band_aliases: List[str]

band aliases in collection

property band_names: List[str]

band names in collection

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:

GeoDataFrame with 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.ndarray or np.ma.MaskedArray if 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 RasterCollection instance 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

copy()[source]

Returns a copy of the current RasterCollection

drop_band(band_name: str)[source]

Deletes a band from the current collection

Parameters:

band_name – name of the band to drop

property empty: bool

Handler has bands loaded

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:

Band instance 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 GeoDataFrame to features defining the pixels to read from the raster bands selected. The geometries can be of type Point, Polygon or MultiPolygon. 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:

GeoDataFrame with 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)

property has_band_aliases: bool

collection supports aliasing

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.

property is_scene: bool

is the RasterCollection a scene

join(other)[source]

Spatial join of one RasterCollection instance with another instance

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.ndarray of datatype boolean or another Band object

  • mask_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.ndarray

  • keep_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 GeoDataFrame or file with vector features understood by fiona. If the geometry type is not Point the 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 GeoDataFrame to features defining the pixels to read from a raster dataset. The geometries can be of type Point, Polygon or MultiPolygon. 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:

GeoDataFrame with 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:

GeoDataFrame with 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 rasterio drivers

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-cogeo package to be installed. Disabled by default.

to_xarray(band_selection: List[str] | None = None) DataArray[source]

Converts bands in collection into a xarray.DataArray

Parameters:

band_selection – selection of bands to process. If not provided uses all bands

Returns:

xarray.DataArray created from RasterCollection.

class eodal.core.raster.RasterOperator[source]

Bases: Operator

Band 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:
  • aRasterCollection object with values (non-empty)

  • otherBand 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: object

A 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

property acquisition_time: datetime

acquisition time of the scene

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 mode: str | None

imaging mode of SAR sensors

property platform: str | None

name of the imaging platform

property processing_level: ProcessingLevels

current processing level

property product_uri: str | None

unique product (scene) identifier

property sensor: str | None

name of the sensor