Skip to content

spatial

This module provides classes and functions to help with light geospatial objects (projections, bounding boxes, etc).

BoundingBox

The bounding box class

Source code in scenes/spatial.py
class BoundingBox:
    """
    The bounding box class
    """

    def __init__(self, xmin: float, ymin: float, xmax: float, ymax: float):
        """
        Args:
            xmin: Lower value on the x-axis
            ymin: Lower value on the y-axis
            xmax: Higher value on the x-axis
            ymax: Higher value on the y-axis
        """
        self.xmin = xmin
        self.ymin = ymin
        self.xmax = xmax
        self.ymax = ymax

    def union(self, other: BoundingBox) -> BoundingBox:
        """
        Return a new bounding box resulting in the union of self and other

        Args:
            other: another bounding box

        Returns:
            a new bounding box

        """
        return BoundingBox(xmin=min(self.xmin, other.xmin),
                           ymin=min(self.ymin, other.ymin),
                           xmax=max(self.xmax, other.xmax),
                           ymax=max(self.ymax, other.ymax))

    def __str__(self) -> str:
        """
        Returns a string representing the object

        Returns:
            str(self.to_list())

        """
        return str(self.to_list())

    def to_list(self) -> List[float]:
        """
        Converts the bbox into a list of coordinates, like rasterio does.

        Returns:
            [xmin, ymin, xmax, ymax]

        """
        return [self.xmin, self.ymin, self.xmax, self.ymax]

    def to_ogrgeom(self) -> ogr.Geometry:
        """
        Converts the BoundingBox into an OGR geometry

        Returns: an OGR Geometry from the bounding box

        """
        coords = ((self.xmin, self.ymin),
                  (self.xmax, self.ymin),
                  (self.xmax, self.ymax),
                  (self.xmin, self.ymax))
        return coords2poly(coords)

__init__(xmin, ymin, xmax, ymax)

Parameters:

Name Type Description Default
xmin float

Lower value on the x-axis

required
ymin float

Lower value on the y-axis

required
xmax float

Higher value on the x-axis

required
ymax float

Higher value on the y-axis

required
Source code in scenes/spatial.py
def __init__(self, xmin: float, ymin: float, xmax: float, ymax: float):
    """
    Args:
        xmin: Lower value on the x-axis
        ymin: Lower value on the y-axis
        xmax: Higher value on the x-axis
        ymax: Higher value on the y-axis
    """
    self.xmin = xmin
    self.ymin = ymin
    self.xmax = xmax
    self.ymax = ymax

__str__()

Returns a string representing the object

Returns:

Type Description
str

str(self.to_list())

Source code in scenes/spatial.py
def __str__(self) -> str:
    """
    Returns a string representing the object

    Returns:
        str(self.to_list())

    """
    return str(self.to_list())

to_list()

Converts the bbox into a list of coordinates, like rasterio does.

Returns:

Type Description
List[float]

[xmin, ymin, xmax, ymax]

Source code in scenes/spatial.py
def to_list(self) -> List[float]:
    """
    Converts the bbox into a list of coordinates, like rasterio does.

    Returns:
        [xmin, ymin, xmax, ymax]

    """
    return [self.xmin, self.ymin, self.xmax, self.ymax]

to_ogrgeom()

Converts the BoundingBox into an OGR geometry

Returns: an OGR Geometry from the bounding box

Source code in scenes/spatial.py
def to_ogrgeom(self) -> ogr.Geometry:
    """
    Converts the BoundingBox into an OGR geometry

    Returns: an OGR Geometry from the bounding box

    """
    coords = ((self.xmin, self.ymin),
              (self.xmax, self.ymin),
              (self.xmax, self.ymax),
              (self.xmin, self.ymax))
    return coords2poly(coords)

union(other)

Return a new bounding box resulting in the union of self and other

Parameters:

Name Type Description Default
other BoundingBox

another bounding box

required

Returns:

Type Description
BoundingBox

a new bounding box

Source code in scenes/spatial.py
def union(self, other: BoundingBox) -> BoundingBox:
    """
    Return a new bounding box resulting in the union of self and other

    Args:
        other: another bounding box

    Returns:
        a new bounding box

    """
    return BoundingBox(xmin=min(self.xmin, other.xmin),
                       ymin=min(self.ymin, other.ymin),
                       xmax=max(self.xmax, other.xmax),
                       ymax=max(self.ymax, other.ymax))

coord_list_to_bbox(coords)

Computes the bounding box of multiple coordinates

Parameters:

Name Type Description Default
coords Tuple[Tuple[float]]

coordinates (x1, y1), ..., (xN, yN)

required

Returns:

Type Description
BoundingBox

BoundingBox instance

Source code in scenes/spatial.py
def coord_list_to_bbox(coords: Tuple[Tuple[float]]) -> BoundingBox:
    """
    Computes the bounding box of multiple coordinates

    Args:
        coords: coordinates (x1, y1), ..., (xN, yN)

    Returns:
        BoundingBox instance

    """
    xmin, xmax = math.inf, -math.inf
    ymin, ymax = math.inf, -math.inf
    for x, y in coords:
        xmin = min(xmin, x)
        xmax = max(xmax, x)
        ymin = min(ymin, y)
        ymax = max(ymax, y)

    return BoundingBox(xmin=xmin, ymin=ymin, xmax=xmax, ymax=ymax)

coordinates_transform(src_srs, tgt_srs)

Return a coordinates transform.

Parameters:

Name Type Description Default
src_srs SpatialReference

source CRS

required
tgt_srs SpatialReference

target CRS

required

Returns:

Type Description
CoordinateTransformation

osr.CoordinateTransformation

Source code in scenes/spatial.py
def coordinates_transform(
        src_srs: osr.SpatialReference,
        tgt_srs: osr.SpatialReference
) -> osr.CoordinateTransformation:
    """
    Return a coordinates transform.

    Args:
        src_srs: source CRS
        tgt_srs: target CRS

    Returns:
        osr.CoordinateTransformation

    """
    assert src_srs, "reproject_coords: src_srs is None!"
    assert tgt_srs, "reproject_coords: tgt_srs is None!"
    # Use x,y = lon, lat
    src_srs.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER)
    tgt_srs.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER)
    return osr.CoordinateTransformation(src_srs, tgt_srs)

coords2poly(coords)

Converts a list of coordinates into a polygon

Parameters:

Name Type Description Default
coords Tuple[Tuple[float]]

tuple of (x, y) coordinates

required

Returns:

Type Description
Geometry

a polygon

Source code in scenes/spatial.py
def coords2poly(coords: Tuple[Tuple[float]]) -> ogr.Geometry:
    """
    Converts a list of coordinates into a polygon

    Args:
        coords: tuple of (x, y) coordinates

    Returns:
        a polygon

    """
    ring = ogr.Geometry(ogr.wkbLinearRing)
    for coord in coords + (coords[0],):
        x, y = coord
        ring.AddPoint(x, y)
    poly = ogr.Geometry(ogr.wkbPolygon)
    poly.AddGeometry(ring)

    return poly

epsg2srs(epsg)

Return a Spatial Reference System corresponding to an EPSG

Parameters:

Name Type Description Default
epsg int

EPSG (int)

required

Returns:

Type Description
SpatialReference

OSR spatial reference

Source code in scenes/spatial.py
def epsg2srs(epsg: int) -> osr.SpatialReference:
    """
    Return a Spatial Reference System corresponding to an EPSG

    Args:
        epsg: EPSG (int)

    Returns:
        OSR spatial reference

    """
    srs = osr.SpatialReference()
    srs.ImportFromEPSG(epsg)
    return srs

extent_overlap(extent, other_extent)

Returns the ratio of extents overlaps.

Parameters:

Name Type Description Default
extent Tuple[Tuple[float]]

extent

required
other_extent Tuple[Tuple[float]]

other extent

required

Returns:

Type Description
float

overlap (in the [0, 1] range). 0 -> no overlap with other_extent, 1 -> extent lies inside other_extent

Source code in scenes/spatial.py
def extent_overlap(
        extent: Tuple[Tuple[float]],
        other_extent: Tuple[Tuple[float]]
) -> float:
    """
    Returns the ratio of extents overlaps.

    Args:
        extent: extent
        other_extent: other extent

    Returns:
        overlap (in the [0, 1] range). 0 -> no overlap with other_extent,
            1 -> extent lies inside other_extent

    """
    poly = coords2poly(extent)
    other_poly = coords2poly(other_extent)
    return poly_overlap(poly=poly, other_poly=other_poly)

poly_overlap(poly, other_poly)

Returns the ratio of polygons overlap.

Parameters:

Name Type Description Default
poly Geometry

polygon

required
other_poly Geometry

other polygon

required

Returns:

Type Description
float

overlap (in the [0, 1] range). 0 -> no overlap with other_poly, 1 -> poly is completely inside other_poly

Source code in scenes/spatial.py
def poly_overlap(poly: ogr.Geometry, other_poly: ogr.Geometry) -> float:
    """
    Returns the ratio of polygons overlap.

    Args:
        poly: polygon
        other_poly: other polygon

    Returns:
        overlap (in the [0, 1] range). 0 -> no overlap with other_poly,
            1 -> poly is completely inside other_poly

    """
    inter = poly.Intersection(other_poly)

    return inter.GetArea() / poly.GetArea()

reproject_coords(coords, src_srs, tgt_srs)

Reproject a list of x,y coordinates.

Parameters:

Name Type Description Default
coords List[Tuple[float]]

list of (x, y) tuples

required
src_srs SpatialReference

source CRS

required
tgt_srs SpatialReference

target CRS

required

Returns:

Name Type Description
trans_coords Tuple[Tuple[float]]

coordinates in target CRS

Source code in scenes/spatial.py
def reproject_coords(
        coords: List[Tuple[float]],
        src_srs: osr.SpatialReference,
        tgt_srs: osr.SpatialReference
) -> Tuple[Tuple[float]]:
    """
    Reproject a list of x,y coordinates.

    Args:
        coords: list of (x, y) tuples
        src_srs: source CRS
        tgt_srs: target CRS

    Returns:
        trans_coords: coordinates in target CRS

    """
    trans_coords = []
    transform = coordinates_transform(src_srs=src_srs, tgt_srs=tgt_srs)
    for x, y in coords:
        x, y, _ = transform.TransformPoint(x, y)
        trans_coords.append((x, y))

    return tuple(trans_coords)