curryer.compute.elevation

Elevation computations and DEM management.

References

GMTED2010

https://pubs.usgs.gov/of/2011/1073/pdf/of2011-1073.pdf

UNAVCO Geoid Height Calculator

https://www.unavco.org/software/geodetic-utilities/geoid-height-calculator/geoid-height-calculator.html

@author: Brandon Stone

Attributes

Classes

Elevation

High-level class for accessing elevation data from individual files.

ElevationRegion

High-level class for accessing elevation data from an optimized

Module Contents

curryer.compute.elevation.logger
curryer.compute.elevation.VDATUMS
curryer.compute.elevation.VDATUM_TO_EPSG
class curryer.compute.elevation.Elevation(data_dir: str | pathlib.Path = None, meters=False, degrees=True)

High-level class for accessing elevation data from individual files.

LON_STEP = 30
LAT_STEP = 20
LON_MID = 0
LAT_MID = 10
data_dir = None
meters = False
degrees = True
_files = None
_metadata = None
_cache
egm96_to_wgs84
static check_for_geoid_data()

Ensure that third-party geoid data is available.

latlon_to_pixel(lon: float, lat: float, transform: affine.Affine)

Convert lon/lat to raster row/col indices using the given Affine transform.

Parameters:
  • lon (float) – Longitude coordinate in degrees.

  • lat (float) – Latitude coordinate in degrees.

  • transform (affine.Affine) – Affine transformation object for coordinate conversion.

Returns:

Row and column indices (row, col) in the raster.

Return type:

tuple of int

Notes

This assumes pixel-center coordinates, so we don’t need to add 0.5 offset since our coordinates already represent pixel centers.

static _get_affine_from_tiff(tif: tifffile.TiffFile) affine.Affine

Extract affine transformation from GeoTIFF using tifffile.

Uses standard GeoTIFF tags ModelPixelScaleTag (33550) and ModelTiepointTag (33922) as defined in GeoTIFF Specification v1.0.

Assumes non-rotated, north-up images. For rotated images using ModelTransformationTag (34264), this method will need enhancement.

Parameters:

tif (tifffile.TiffFile) – An open TiffFile object.

Returns:

The affine transformation matrix.

Return type:

Affine

Raises:

ValueError – If required GeoTIFF tags are missing.

Notes

Standard GeoTIFF structure (from GeoTIFF Specification Section 2.6.1): - ModelPixelScale = (ScaleX, ScaleY, ScaleZ) in map units per pixel - ModelTiepoint = (I, J, K, X, Y, Z) where pixel (I,J) maps to location (X,Y) - Y scale is negative for north-up images (GDAL convention)

static _get_crs_from_tiff(tif: tifffile.TiffFile) int

Extract EPSG code from GeoTIFF using tifffile.

Uses standard GeoTIFF GeoKeys as defined in GeoTIFF Specification v1.0: - ProjectedCSTypeGeoKey (3072): EPSG code for projected coordinate systems - GeographicTypeGeoKey (2048): EPSG code for geographic coordinate systems

Parameters:

tif (tifffile.TiffFile) – An open TiffFile object.

Returns:

The EPSG code for the coordinate reference system.

Return type:

int

Raises:

ValueError – If no valid EPSG code is found in the GeoTIFF metadata.

Notes

tifffile 2025.x parses the GeoKeyDirectoryTag (34735) and converts numeric GeoKey IDs to descriptive names for readability. Values may be Enum objects (e.g., <GCS.WGS_84: 4326>) requiring .value extraction.

These GeoKey names are from the official GeoTIFF specification, not specific to any test data. They will work with any compliant GeoTIFF file.

References

GeoTIFF Specification v1.0, Section 6.3.3.1 (Projected CS Keys) GeoTIFF Specification v1.0, Section 6.3.2.1 (Geographic CS Keys)

locate_files(pattern: str = '*_gmted_*.tif') list[pathlib.Path]

Locate DEM files on the filesystem (cached).

Parameters:

pattern (str, optional) – File name pattern to filter DEM files with.

Returns:

List of found DEM files. Cached after first execution.

Return type:

list[Path]

describe_files() pandas.DataFrame

Compute the metadata for the available DEM files (cached).

Returns:

Metadata for the individual DEM files. Cached after first execution.

Return type:

pd.DataFrame

lookup_file(lon: float, lat: float, arcsec: float = None, stat: str = 'mea', wrap_lon=False, degrees: bool | None = None) pandas.Series | None

Find the DEM file for a given lon/lat point.

Parameters:
  • lon (float) – Longitude in degrees or radians, see degrees.

  • lat (float) – Latitude in degrees or radians, see degrees.

  • arcsec (float, optional) – Select the DEM resolution. Default is the highest available.

  • stat (str, optional) – Select the type of DEM file. Default is “mea” (mean).

  • wrap_lon (bool, optional) – Allow longitude values less than -180 and greater than 180, wrapping them around the globe (e.g., 190 = -170). Default is False.

  • degrees (None or bool, optional) – Assume in/out lon/lat are in degrees. If not specified or None (default), uses the instance value of degrees (default is True).

Returns:

Matching DEM metadata entry or None if no match was found.

Return type:

pd.Series or None

load_file(filepath: pathlib.Path) xarray.DataArray

Load data from a DEM file (cached).

Parameters:

filepath (Path) – Path to the DEM file to load.

Returns:

Loaded elevation data. Cached for each unique file path.

Return type:

xr.DataArray

get_geoid_height(lon: numpy.ndarray | float, lat: numpy.ndarray | float, degrees: bool | None = None) numpy.ndarray | float

Query the geoid height for a given lon/lat(s).

Parameters:
  • lon (np.ndarray or float) – Longitude in degrees or radians, see degrees.

  • lat (np.ndarray or float) – Latitude in degrees or radians, see degrees.

  • degrees (None or bool, optional) – Assume in/out lon/lat are in degrees. If not specified or None (default), uses the instance value of degrees (default is True).

Returns:

Geoid height above the ellipsoid. Default is kilometers unless init variable meters was True.

Return type:

np.ndarray or float

get_dem_height(lon: float, lat: float, filepath: pathlib.Path, degrees: bool | None = None) float

Query the DEM height above the geoid for a given lon/lat.

Parameters:
  • lon (float) – Longitude in degrees or radians, see degrees.

  • lat (float) – Latitude in degrees or radians, see degrees.

  • filepath (Path) – DEM file to query data from.

  • degrees (None or bool, optional) – Assume in/out lon/lat are in degrees. If not specified or None (default), uses the instance value of degrees (default is True).

Returns:

DEM height above the geoid. Default is kilometers unless init variable meters was True.

Return type:

float

query(lon, lat, orthometric=False)

Query the surface (DEM + geoid) height above the ellipsoid a given lon/lat.

Parameters:
  • lon (float) – Longitude in degrees or radians, see init degrees.

  • lat (float) – Latitude in degrees or radians, see init degrees.

  • orthometric (bool, optional) – Exclude the geoid height as part of the surface height. Default is False.

Returns:

Surface (DEM and geoid (unless orthometric=True) height above the ellipsoid. Default is kilometers unless init variable meters was True.

Return type:

float

_pad_lonlat(lon: float, lat: float, pad: float) tuple[float, float, float, float]

Intelligently pad lon/lat values with a meter/kilometer distance.

_regional_files(min_lon: float, max_lon: float, min_lat: float, max_lat: float, allow_empty=False) set[pathlib.Path]

Find all DEM files within a min/max lon/lat region.

_slice_file(rds: xarray.DataArray, min_lon: float, max_lon: float, min_lat: float, max_lat: float, orthometric: bool = False, fill_val: float = None) xarray.DataArray

Subset a DEM file by a min/max lon/lat region.

Parameters:
  • rds (xr.DataArray) – DEM data array with ‘x’ (longitude) and ‘y’ (latitude) coordinates.

  • min_lon (float) – Longitude bounds in degrees ([-180, 180]).

  • max_lon (float) – Longitude bounds in degrees ([-180, 180]).

  • min_lat (float) – Latitude bounds in degrees ([-90, 90]).

  • max_lat (float) – Latitude bounds in degrees ([-90, 90]).

  • orthometric (bool, optional) – If True, return orthometric heights (DEM only). If False, return ellipsoid heights (DEM + geoid).

  • fill_val (float, optional) – Fill value to check for consistency.

Returns:

Subsetted DEM or ellipsoid heights for the region.

Return type:

xr.DataArray

local_minmax(lon, lat, pad, orthometric=False) tuple[float, float]

Compute the elevation min/max around a buffered point.

Parameters:
  • lon (float) – Longitude in degrees or radians, see init degrees.

  • lat (float) – Latitude in degrees or radians, see init degrees.

  • pad (float) – Padding to add to the point, in meters or kilometers, see init meters.

  • orthometric (bool, optional) – Exclude the geoid heights from the result.

Returns:

Min and max elevation around the specified padding point.

Return type:

(float, float)

local_region(min_lon: float, max_lon: float, min_lat: float, max_lat: float, orthometric=False)

Create a regional subset, supporting SIGNIFICANTLY faster queries.

Parameters:
  • min_lon (float) – Minimum longitude extent of the region, see init degrees.

  • max_lon (float) – Maximum longitude extent of the region, see init degrees.

  • min_lat (float) – Minimum latitude extent of the region, see init degrees.

  • max_lat (float) – Maximum latitude extent of the region, see init degrees.

  • orthometric (bool, optional) – Exclude the geoid heights from the result.

Returns:

Elevation subset that only supports queries within its region, but SIGNIFICANTLY faster within the region!

Return type:

ElevationRegion

class curryer.compute.elevation.ElevationRegion(data: numpy.ndarray, ulx: float, uly: float, dx: float, dy: float, orthometric=None, meters: bool | None = None, degrees: bool | None = None)

High-level class for accessing elevation data from an optimized pre-cached dataset.

data
ulx
uly
dx
dy
orthometric = None
meters = None
degrees = None
lrx
lry
_wrap = 360
__repr__()
classmethod from_xarray(hts: xarray.DataArray, **kwargs)

Create a region from an xarray data array.

Parameters:
  • hts (xr.DataArray) – Elevation data with lon/lat coordinates (x/y).

  • kwargs (dict) – See init arguments.

Returns:

Elevation region from an xarray data array.

Return type:

ElevationRegion

query(lon: numpy.ndarray | float, lat: numpy.ndarray | float, orthometric=None) numpy.ndarray | float

Query the surface (DEM + geoid) height above the ellipsoid a given lon/lat.

Parameters:
  • lon (np.ndarray or float) – Longitude in degrees or radians, see init degrees.

  • lat (np.ndarray or float) – Latitude in degrees or radians, see init degrees.

  • orthometric (bool, optional) – Included for backwards compatibility with the slower Elevation implementation. Ignored if not specified, otherwise it must match the value used to create this region.

Returns:

Surface (DEM and geoid (unless orthometric=True)) height above the ellipsoid. Default is kilometers unless init variable meters was True.

Return type:

np.ndarray or float

local_minmax(lon=None, lat=None, pad=None) tuple[float, float]

Compute local min/max elevation. Simply assumes the region is the same as the locality, returning its min/max.

Parameters:
  • lon – Ignored.

  • lat – Ignored.

  • pad – Ignored.

Returns:

Min and max elevation for the region.

Return type:

float, float