Skip to content

indexation

This module contains stuff for the spatio-temporal indexation of scenes.

The scenes.indexation.Index uses an R-Tree to perform the indexation of objects in the (x, y, t) domain.


Example: spatio-temporal indexation of multiple scenes.core.Scene instances.

Build a spatio temporal index

import scenes
scenes_list = [...]  # a list of various `scenes.core.Scene` instances.
index = scenes.indexation.Index(scenes_list)  # build the index

Search from a BoundingBox

The find_indices() method returns the indices of the indexed scenes.core.Scene instances matching the query. The find() method returns the indexed scenes.core.Scene instances matching the query.

bbox = BoundingBox(43.706, 43.708, 4.317, 4.420)
indices_results = index.find_indices(bbox)  # spatial query returning indices
scenes_results = index.find(bbox)  # spatial query returning scenes instances

A date min and/or a date max can be added in the query.

scenes_results = index.find(bbox, "01/01/2020" "01/01/2022")

Search from a vector data file

The search can also be performed with a vector data file.

vec = "/path/to/vector.gpkg"
scenes_results = index.find(vec, "01/01/2020" "01/01/2022")

Index

Stores an indexation structure for a list of Scenes

Source code in scenes/indexation.py
class Index:
    """
    Stores an indexation structure for a list of Scenes
    """

    def __init__(self, scenes_list: List[Scene]):
        """
        Args:
            scenes_list: list of scenes

        """
        self.scenes_list = scenes_list

        # Build RTrees (lat/lon/time)
        properties = rtree.index.Property()
        properties.dimension = 3
        self.index = rtree.index.Index(properties=properties)
        for scene_idx, scene in enumerate(scenes_list):
            delta = scene.acquisition_date
            dt_min = delta - timedelta(days=1)
            dt_max = delta + timedelta(days=1)
            new_bbox = _bbox(
                bbox_wgs84=scene.bbox_wgs84, date_min=dt_min, date_max=dt_max
            )
            self.index.insert(scene_idx, new_bbox)

    def find_indices(
            self,
            vector_or_bbox: Union[str, BoundingBox],
            date_min: Union[datetime, str] = None,
            date_max: Union[datetime, str] = None
    ) -> List[int]:
        """
        Search the intersecting scenes, and return their indices

        The search is performed using the provided bounding box, or the
        provided input vector data file. The date_min and date_max are both
        optional.

        Args:
            vector_or_bbox: An input vector data file (str) or a bounding box
                in WGS84 (BoundingBox instance)
            date_min: date min (datetime or str) (Default value = None)
            date_max: date max (datetime or str) (Default value = None)

        Returns:
            list of indices

        """
        if not date_min:
            date_min = MINDATE
        if not date_max:
            date_max = MAXDATE

        # Use the bounding box from the vector data, or from the specified one
        actual_bbox_wgs84 = vector_or_bbox
        vector_file = isinstance(vector_or_bbox, str)
        if vector_file:
            actual_bbox_wgs84 = get_bbox_wgs84(vector_or_bbox)

        # Search in R-Tree
        bbox_search = _bbox(
            bbox_wgs84=actual_bbox_wgs84, date_min=date_min, date_max=date_max
        )
        results_indices = list(self.index.intersection(bbox_search))

        # Filter results (if vector_file)
        if vector_file:
            poly_ds = ogr_open(vector_file=vector_or_bbox)
            poly_layer_wgs84 = reproject_ogr_layer(
                poly_ds.GetLayer(), epsg=4326
            )
            filtered_indices = []
            for i in results_indices:
                bbox_wgs84_geom = self.scenes_list[i].bbox_wgs84.to_ogrgeom()
                if poly_overlap(poly_layer_wgs84, bbox_wgs84_geom) > 0:
                    filtered_indices.append(i)
            return filtered_indices
        return results_indices

    def find(
            self,
            vector_or_bbox: Union[str, BoundingBox],
            date_min: Union[datetime, str] = None,
            date_max: Union[datetime, str] = None
    ) -> List[Scene]:
        """
        Search the intersecting scenes, and return them

        Args:
            vector_or_bbox: An input vector data file (str) or a bounding box
                in WGS84 (BoundingBox instance)
            date_min: date min (datetime or str) (Default value = None)
            date_max: date max (datetime or str) (Default value = None)

        Returns:
            list of `Scene` instances

        """
        indices = self.find_indices(
            vector_or_bbox=vector_or_bbox, date_min=date_min, date_max=date_max
        )
        return [self.scenes_list[i] for i in indices]

__init__(scenes_list)

Parameters:

Name Type Description Default
scenes_list List[Scene]

list of scenes

required
Source code in scenes/indexation.py
def __init__(self, scenes_list: List[Scene]):
    """
    Args:
        scenes_list: list of scenes

    """
    self.scenes_list = scenes_list

    # Build RTrees (lat/lon/time)
    properties = rtree.index.Property()
    properties.dimension = 3
    self.index = rtree.index.Index(properties=properties)
    for scene_idx, scene in enumerate(scenes_list):
        delta = scene.acquisition_date
        dt_min = delta - timedelta(days=1)
        dt_max = delta + timedelta(days=1)
        new_bbox = _bbox(
            bbox_wgs84=scene.bbox_wgs84, date_min=dt_min, date_max=dt_max
        )
        self.index.insert(scene_idx, new_bbox)

find(vector_or_bbox, date_min=None, date_max=None)

Search the intersecting scenes, and return them

Parameters:

Name Type Description Default
vector_or_bbox Union[str, BoundingBox]

An input vector data file (str) or a bounding box in WGS84 (BoundingBox instance)

required
date_min Union[datetime, str]

date min (datetime or str) (Default value = None)

None
date_max Union[datetime, str]

date max (datetime or str) (Default value = None)

None

Returns:

Type Description
List[Scene]

list of Scene instances

Source code in scenes/indexation.py
def find(
        self,
        vector_or_bbox: Union[str, BoundingBox],
        date_min: Union[datetime, str] = None,
        date_max: Union[datetime, str] = None
) -> List[Scene]:
    """
    Search the intersecting scenes, and return them

    Args:
        vector_or_bbox: An input vector data file (str) or a bounding box
            in WGS84 (BoundingBox instance)
        date_min: date min (datetime or str) (Default value = None)
        date_max: date max (datetime or str) (Default value = None)

    Returns:
        list of `Scene` instances

    """
    indices = self.find_indices(
        vector_or_bbox=vector_or_bbox, date_min=date_min, date_max=date_max
    )
    return [self.scenes_list[i] for i in indices]

find_indices(vector_or_bbox, date_min=None, date_max=None)

Search the intersecting scenes, and return their indices

The search is performed using the provided bounding box, or the provided input vector data file. The date_min and date_max are both optional.

Parameters:

Name Type Description Default
vector_or_bbox Union[str, BoundingBox]

An input vector data file (str) or a bounding box in WGS84 (BoundingBox instance)

required
date_min Union[datetime, str]

date min (datetime or str) (Default value = None)

None
date_max Union[datetime, str]

date max (datetime or str) (Default value = None)

None

Returns:

Type Description
List[int]

list of indices

Source code in scenes/indexation.py
def find_indices(
        self,
        vector_or_bbox: Union[str, BoundingBox],
        date_min: Union[datetime, str] = None,
        date_max: Union[datetime, str] = None
) -> List[int]:
    """
    Search the intersecting scenes, and return their indices

    The search is performed using the provided bounding box, or the
    provided input vector data file. The date_min and date_max are both
    optional.

    Args:
        vector_or_bbox: An input vector data file (str) or a bounding box
            in WGS84 (BoundingBox instance)
        date_min: date min (datetime or str) (Default value = None)
        date_max: date max (datetime or str) (Default value = None)

    Returns:
        list of indices

    """
    if not date_min:
        date_min = MINDATE
    if not date_max:
        date_max = MAXDATE

    # Use the bounding box from the vector data, or from the specified one
    actual_bbox_wgs84 = vector_or_bbox
    vector_file = isinstance(vector_or_bbox, str)
    if vector_file:
        actual_bbox_wgs84 = get_bbox_wgs84(vector_or_bbox)

    # Search in R-Tree
    bbox_search = _bbox(
        bbox_wgs84=actual_bbox_wgs84, date_min=date_min, date_max=date_max
    )
    results_indices = list(self.index.intersection(bbox_search))

    # Filter results (if vector_file)
    if vector_file:
        poly_ds = ogr_open(vector_file=vector_or_bbox)
        poly_layer_wgs84 = reproject_ogr_layer(
            poly_ds.GetLayer(), epsg=4326
        )
        filtered_indices = []
        for i in results_indices:
            bbox_wgs84_geom = self.scenes_list[i].bbox_wgs84.to_ogrgeom()
            if poly_overlap(poly_layer_wgs84, bbox_wgs84_geom) > 0:
                filtered_indices.append(i)
        return filtered_indices
    return results_indices