BoundingBox#
- class rapidtools.core.BoundingBox(min_x: float, min_y: float, max_x: float, max_y: float)[source]#
Bases:
RegionRepresents an axis-aligned rectangular region.
This class acts as a wrapper around a Shapely BaseGeometry that is strictly rectangular. It provides specialized initialization methods and optimized properties for rectangular math.
Methods
Return a new BoundingBox expanded (or shrunk) by a constant distance.
containsCheck if the region completely encloses another geometry.
distanceCalculate the minimum Euclidean distance to another region or geometry.
Create a BoundingBox covering the total spatial extent of a GeoJSON file.
Create a BoundingBox that exactly encloses a geometry.
Create a BoundingBox representing the spatial extent of a raster file.
Create a box covering the total extent of two regions.
Return the bounding box of this region.
intersectsDetermine if the region spatially intersects with another geometry.
Splits the bounding box into four equal-sized quadrants.
Split the bounding box into a grid of smaller boxes.
- property area: float#
Return the area of the bounding box.
Overridden from
Regionto use simple float math instead of Shapely logic for performance.- Returns:
float – The area in the squared units of the coordinate system.
Note
If coordinates are in meters (e.g., UTM), result is sq. meters.
If coordinates are in degrees (e.g., WGS84), result is sq. degrees. Square degrees are generally not useful for physical size estimates.
Example
>>> from rapidtools.core import BoundingBox >>> >>> bbox = BoundingBox(0, 0, 5, 5) >>> bbox.area 25.0
- property centroid: tuple[float, float]#
Return the center point of the bounding box.
Overridden from
Regionto use simple float math instead of Shapely logic for performance.- Returns:
tuple[float, float] – The (longitude, latitude) center coordinates.
Example
>>> from rapidtools.core import BoundingBox >>> >>> bbox = BoundingBox(0, 0, 10, 20) >>> bbox.centroid (5.0, 10.0)
- classmethod from_geojson(filepath: str | Path) BoundingBox[source]#
Create a BoundingBox covering the total spatial extent of a GeoJSON file.
The method uses a pre-computed top-level
bboxmember when one is present (the fastest path) and otherwise streams the bounds of every feature without building large in-memory geometry lists. Feature-levelbboxmembers are honoured before falling back to the geometry. Empty geometries are skipped. If the file declares a legacycrsmember that is not EPSG:4326, the resulting bounds are reprojected to WGS84.- Parameters:
filepath (str | Path) – Path to a GeoJSON file containing a
FeatureCollection, a singleFeature, or a bare geometry object.- Returns:
BoundingBox – A box covering the entire extent of the GeoJSON content, in WGS84 (EPSG:4326) coordinates.
- Raises:
ValueError – If the top-level
typeis not a supported GeoJSON type, or if the file contains no valid, non-empty geometries.
Example
>>> from rapidtools.core import BoundingBox >>> >>> bbox = BoundingBox.from_geojson('data.geojson') >>> print(bbox.bounds) (-118.5, 34.0, -118.0, 34.5)
- classmethod from_geometry(geometry: BaseGeometry) BoundingBox[source]#
Create a BoundingBox that exactly encloses a geometry.
- Parameters:
geometry (BaseGeometry) – Any Shapely geometry (Polygon, Point, LineString, etc.) to wrap.
- Returns:
BoundingBox – A new instance covering the extent of the input geometry.
Example
>>> from rapidtools.core import BoundingBox >>> >>> from shapely.geometry import LineString >>> line = LineString([(0, 0), (10, 10)]) >>> bbox = BoundingBox.from_geometry(line) >>> bbox.bounds (0.0, 0.0, 10.0, 10.0)
- classmethod from_raster(filepath: str | Path) BoundingBox[source]#
Create a BoundingBox representing the spatial extent of a raster file.
Automatically reprojects the bounds to WGS84 (EPSG:4326) if the source raster is in a different coordinate reference system (e.g., a localized UTM zone). Rasters without a CRS are assumed to already be in WGS84.
- Parameters:
filepath (str | Path) – Path to the georeferenced raster file.
- Returns:
BoundingBox – A WGS84 bounding box covering the extent of the raster.
- Raises:
RasterioIOError – If the file cannot be opened.
Example
>>> from rapidtools.core import BoundingBox >>> from rapidtools import download_dataset >>> >>> # Download a sample drone flight: >>> [raster_path] = download_dataset('eaton_patch1') >>> >>> # Extract its spatial bounds instantly: >>> bbox = BoundingBox.from_raster(raster_path) >>> print(bbox.bounds) (-118.0934, 34.1842, -118.0911, 34.1858)
- classmethod from_union(region1: Region, region2: Region) BoundingBox[source]#
Create a box covering the total extent of two regions.
This calculates the “envelope union” (min of mins, max of maxs) of two regions
- Parameters:
region1 (Region) – The first region.
region2 (Region) – The second region.
- Returns:
BoundingBox – A new instance large enough to cover both inputs.
Example
>>> from rapidtools.core import BoundingBox >>> >>> b1 = BoundingBox(0, 0, 1, 1) >>> b2 = BoundingBox(10, 10, 11, 11) >>> union_box = BoundingBox.from_union(b1, b2) >>> union_box.bounds (0.0, 0.0, 11.0, 11.0)
- buffer(distance: float) BoundingBox[source]#
Return a new BoundingBox expanded (or shrunk) by a constant distance.
This operation pushes the box boundaries outward by the specified distance.
- Parameters:
distance (float) – The amount to expand the box edges. Use negative values to shrink the box.
- Returns:
BoundingBox – A new BoundingBox instance with adjusted boundaries.
Example
>>> from rapidtools.core import BoundingBox >>> >>> bbox = BoundingBox(0, 0, 10, 10) >>> expanded = bbox.buffer(1.0) >>> expanded.bounds (-1.0, -1.0, 11.0, 11.0)
- get_bounding_box() BoundingBox[source]#
Return the bounding box of this region.
Since this object is already a BoundingBox, this method simply returns
self.- Returns:
BoundingBox – The object itself.
- split() list[BoundingBox][source]#
Splits the bounding box into four equal-sized quadrants.
This method is used by the API client for adaptive tiling when a tile is too dense with features and needs to be subdivided.
- Returns:
A list of four new BoundingBox objects for the quadrants – [bottom-left, bottom-right, top-left, top-right].
Example
>>> from rapidtools.core import BoundingBox >>> >>> bbox = BoundingBox(0, 0, 10, 10) >>> quads = bbox.split() >>> quads[0].bounds # Bottom-Left (0.0, 0.0, 5.0, 5.0) >>> quads[3].bounds # Top-Right (5.0, 5.0, 10.0, 10.0)
- tile_by_area(max_area: float = 0.01) list[BoundingBox][source]#
Split the bounding box into a grid of smaller boxes.
The grid dimensions are calculated to maintain the aspect ratio of the original box as closely as possible while ensuring every tile has an area less than or equal to
max_area.- Parameters:
max_area (float) – The maximum allowed area for a single tile. Defaults to 0.01.
- Returns:
list[BoundingBox] – A flattened list of the resulting sub-boxes.
Example
Initialize a bounding box with an area of 100 square units:
>>> from rapidtools.core import BoundingBox >>> >>> bbox = BoundingBox(0, 0, 10, 10)
Split the bounding box into tiles with a maximum area of 25 square units:
>>> tiles = bbox.tile_by_area(max_area=25) INFO: Tiling BoundingBox into 2x2 grid (Target Area: 25, Total Tiles: 4) >>> len(tiles) 4