UTM Zone & EPSG Helpers#
UTM helpers in pyramids.utm for resolving the UTM zone / EPSG code of a WGS84
point or vector layer — used for per-tile reprojection, local-metre areas of
interest, and STAC point cubes.
These return the EPSG-correct zone: the plain 6°-wide longitude bands, with
the hemisphere selecting the 326xx (north) or 327xx (south) band. The
Norway/Svalbard zone shifts are the MGRS grid-zone lettering convention, not the
UTM CRS definitions, so they are deliberately not applied — EPSG:32631 (0°E–6°E) is
the zone whose area of use covers Bergen at 5°E, while EPSG:32632 (6°E–12°E) does
not. The values here agree with pyproj.database.query_utm_crs_info.
Functions#
pyramids.utm.utm_zone(lon)
#
Return the UTM zone number (1-60) for a longitude.
The zone is a plain 6°-wide band: zone 1 starts at 180°W, and each zone spans
6° of longitude. The value depends only on lon; latitude selects the
hemisphere band in utm_epsg, not the zone number.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lon
|
float
|
Longitude in degrees. A longitude outside |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
The UTM zone number, |
Examples:
- Greenwich sits at the zone 30/31 boundary and lands in zone 31:
- Bergen (5°E) is zone 31 — the plain band, not the MGRS zone-32 shift:
- A
0..360longitude is wrapped, so 200°E resolves like 160°W:
Source code in src/pyramids/utm.py
pyramids.utm.utm_epsg(lon, lat)
#
Return the EPSG code of the UTM zone containing (lon, lat).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lon
|
float
|
Longitude in degrees (wrapped into |
required |
lat
|
float
|
Latitude in degrees. Only its sign is used (the equator is treated as
northern) to pick the northern ( |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
|
Examples:
- Bergen, Norway resolves to UTM 31N — matching
pyprojand the EPSG area of use, not the MGRS zone-32 convention: - A southern-hemisphere point uses the
327xxband:
Source code in src/pyramids/utm.py
pyramids.utm.utm_epsg_for_polygon(gdf)
#
Return the UTM EPSG for a vector layer, from the centre of its bounds.
The layer is reprojected to WGS84 (a no-op when it is already EPSG:4326), the
centre of its total bounds is taken, and that lon/lat is passed to utm_epsg.
Any geometry type is accepted (points, lines, polygons); the zone is chosen from
the bounds centre, not a true geometric centroid.
The single zone returned is the one at the bounds centre; it is exact only for a
layer that fits within one 6°-wide zone, and is a best-effort choice for a wider
layer (which spans several zones). Only the clearly-nonsensical case is rejected:
bounds spanning more than 180° of longitude — a dateline-crossing layer (whose
total bounds spuriously spans -180…180), a near-polar extent (whose longitudes
fan out around the pole), or a genuinely half-globe span — where the mid-span
centre would name a zone covering none of the data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
gdf
|
GeoDataFrame
|
A |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
The EPSG code of the UTM zone at the layer's bounds centre. |
Raises:
| Type | Description |
|---|---|
CRSError
|
|
ValueError
|
|
Source code in src/pyramids/utm.py
pyramids.utm.project_to_utm(gdf)
#
Reproject a vector layer to its local UTM zone.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
gdf
|
GeoDataFrame
|
A |
required |
Returns:
| Type | Description |
|---|---|
GeoDataFrame
|
tuple[GeoDataFrame, int]: The layer reprojected to its UTM zone (a fresh |
int
|
|
Raises:
| Type | Description |
|---|---|
CRSError
|
|
ValueError
|
|