sidescanpy.grids.definition#

GridDefinition: metadata contract for a georeferenced grid.

Defines bounding box, resolution, and projection. Handles CRS conversion. No data — just the schema/contract.

Contents

CELL_COUNT_TOLERANCE

Fraction of a cell within which extent / resolution counts as a whole number of cells, so float error (400.2 / 0.3 = 1334.0000000006) does not add a cell.

GridDefinition

Georeferenced grid schema.

utm_crs_for_lonlat

Pick the WGS84 UTM zone CRS containing (lon, lat).

utm_grid_from_wgs84_bbox

Build a GridDefinition in an auto-selected UTM zone from a WGS84 bbox.

bbox_from_channel_dataset

(south, west, north, east) bbox fit to a channel dataset's per-sample lat/lon extent, with a small margin so edge cells aren't clipped.

sidescanpy.grids.definition.CELL_COUNT_TOLERANCE = 1e-06#

Fraction of a cell within which extent / resolution counts as a whole number of cells, so float error (400.2 / 0.3 = 1334.0000000006) does not add a cell. 1e-6 cells is 0.3 um at 0.3 m resolution.

class sidescanpy.grids.definition.GridDefinition(bbox, resolution_m, crs=None)#

Bases: object

Georeferenced grid schema.

A grid is defined by: - bbox: (south, west, north, east) in the given CRS - resolution_m: pixel size in meters - crs: pyproj.CRS (default WGS84)

Provides derived properties (cell counts, coordinates) and projection helpers (reproject_to).

property extent_m_ns#

North-south extent in meters (geodetic if WGS84).

property extent_m_ew#

East-west extent in meters (geodetic if WGS84, at mid-latitude).

property num_cells_ns#

Number of grid cells in north-south direction.

ceil(extent_m_ns / resolution_m), except that a ratio within CELL_COUNT_TOLERANCE of a whole number counts as that number.

property num_cells_ew#

Number of grid cells in east-west direction.

ceil(extent_m_ew / resolution_m), except that a ratio within CELL_COUNT_TOLERANCE of a whole number counts as that number.

property num_cells_total#

Total number of grid cells.

property corner_coords#

Southwest and northeast corner coordinates.

Returns:
(sw_lat, sw_lon, ne_lat, ne_lon)
get_grid_centers()#

Generate 2D arrays of grid cell center coordinates.

Returns:
latsndarray of shape (num_cells_ns, num_cells_ew)
lonsndarray of shape (num_cells_ns, num_cells_ew)

Grid center coordinates in the CRS.

Notes

For WGS84, returns lat/lon. For projected CRS, returns northing/easting (but named as lats/lons for consistency).

reproject_to(target_crs)#

Reproject grid to a different CRS.

Parameters:
target_crspyproj.CRS

Target coordinate reference system.

Returns:
GridDefinition

New grid in target CRS. Resolution is preserved; bbox is transformed to target CRS.

Notes

This transforms the four corners + intermediate points to estimate the new bounding box in the target CRS.

to_dict()#

Serialize to dict (JSON-compatible).

classmethod from_dict(d)#

Reconstruct from dict.

sidescanpy.grids.definition.utm_crs_for_lonlat(lon, lat)#

Pick the WGS84 UTM zone CRS containing (lon, lat).

Standard “auto-UTM” heuristic: zone = floor((lon + 180) / 6) + 1, hemisphere from the sign of lat. EPSG 326xx for northern- hemisphere zones, 327xx for southern. Good enough to pick a sane projected CRS automatically for a survey’s gridded output; near a zone boundary (every 6° of longitude) the “correct” zone is a judgment call anyway — pass an explicit CRS via GridDefinition if a specific zone/datum is required (e.g. matching a state-plane system already in use for a project).

Parameters:
lon, latfloat

WGS84 degrees. Typically the center of the survey’s bbox.

Returns:
pyproj.CRS

WGS84 / UTM zone CRS (EPSG 32601-32660 or 32701-32760).

sidescanpy.grids.definition.utm_grid_from_wgs84_bbox(bbox, resolution_m)#

Build a GridDefinition in an auto-selected UTM zone from a WGS84 bbox.

Picks the UTM zone containing the bbox’s center point (via utm_crs_for_lonlat), then reprojects the bbox into that zone’s meters via GridDefinition.reproject_to (dense edge sampling, not just 4 corners, for accuracy).

Parameters:
bbox(south, west, north, east)

WGS84 degrees.

resolution_mfloat

Grid cell size in meters.

Returns:
GridDefinition

Projected (UTM) grid covering the same ground area as bbox.

sidescanpy.grids.definition.bbox_from_channel_dataset(ds, margin_frac=0.1, min_margin_m=5.0, min_margin_deg=None)#

(south, west, north, east) bbox fit to a channel dataset’s per-sample lat/lon extent, with a small margin so edge cells aren’t clipped.

Typically the first step before utm_grid_from_wgs84_bbox when auto-fitting a grid to a segment.

Parameters:
dsxr.Dataset

Must have latitude_per_sample/longitude_per_sample (i.e. already georeferenced via compute_georeferencing).

margin_fracfloat, default 0.1

Fraction of the lat/lon extent added as margin on each side.

min_margin_mfloat, default 5.0

Minimum margin on each side, in meters (converted to degrees at the data’s latitude), for a near-zero-extent segment.

min_margin_degfloat, optional

Minimum margin in degrees instead of min_margin_m. (Before 0.6.1 this was the only option, defaulting to 0.001 deg – about 110 m, which dominated the margin of a typical grid segment.)

Returns:
(south, west, north, east)
Raises:
ValueError

If no finite latitude/longitude_per_sample values are present.