Skip to main content

landmetrics

Distance to the nearest coastline, land fraction within a radius, and land/ocean point tests, backed by precomputed GSHHG coastline grids.

import landmetrics as lm

lm.distance_to_land(25.0, -80.0)  # km, negative over land
lm.land_fraction(25.0, -80.0, 300.0)  # fraction in [0, 1] within 300 km
lm.is_land(25.0, -80.0)  # bool
lm.is_ocean(25.0, -80.0)  # bool

This is a query-only library: it ships precomputed grid files and reads them efficiently. It does not generate grids from raw GSHHG polygons -- that requires a heavier geospatial toolchain (shapely, geopandas, cartopy, scipy) and is not part of this package.

Install

pip install landmetrics

A coarse (0.1 degree) grid for each query kind ships inside the wheel, so a query works immediately with no network access. Finer grids are fetched from Zenodo on first use and cached locally (see Data below).

API

distance_to_land(lat, lon, path=None, *, resolution_deg=None, min_island_area_km2=None)
land_fraction(lat, lon, radius_km, path=None, *, resolution_deg=None, min_island_area_km2=None)
is_land(lat, lon, path=None, *, resolution_deg=None, min_island_area_km2=None)
is_ocean(lat, lon, path=None, *, resolution_deg=None, min_island_area_km2=None)

lat/lon/radius_km may be scalars or array-like (broadcast together). lon is normalized into [-180, 180) first, so any input convention works, including values that accumulate past +/-180 across the antimeridian.

For repeated queries, open a reusable, explicit object instead of the cached convenience functions:

with lm.DistanceToLand(path) as dtl:
    values = dtl.query(lats, lons)
    land = dtl.is_land(lats, lons)

with lm.LandFraction(path) as lf:
    fractions = lf.query(lats, lons, radius_km=300.0)

open_distance_to_land(...) / open_land_fraction(...) resolve and open a grid by resolution/island-area threshold rather than an explicit path.

is_land / is_ocean

These read the nearest grid cell's sign, not an interpolated value: bilinearly blending the signed distance field across a coastline can carry a land point within one grid cell of the shore to a positive (ocean) value. Accuracy is therefore bounded by grid resolution -- roughly half a cell width at the equator (about 5.5 km at 0.05 degrees, 1.1 km at 0.01 degrees).

Thread safety

DistanceToLand and LandFraction hold an open netCDF handle, and netCDF4/HDF5 access is not safe to share across threads. Use one instance per thread (including the module-level cached instances behind the convenience functions above), or serialize access with a lock. Separate processes are fine, each with its own instance -- just don't open one before forking and then use it from both parent and child.

Performance

Every query reads only the cells its interpolation needs directly out of the netCDF file -- never the whole grid. A scalar query reads at most 8 cells. An array query reads one bounding block when the points are geographically compact, or splits into row-compact tiles otherwise, bounded by a fixed cell budget regardless of the underlying grid's resolution. See docs/grid_format.md for the file layout this depends on.

Data

grid resolution min island area bundled
distance_to_land 0.1 deg 0 km^2 yes
land_fraction 0.1 deg 0 km^2 yes
distance_to_land 0.1 deg 1400, 4748 km^2 fetched from Zenodo
distance_to_land 0.05, 0.01 deg 0, 1400, 4748 km^2 fetched from Zenodo
land_fraction 0.05, 0.01 deg 0 km^2 fetched from Zenodo

grid_path(kind, resolution_deg, min_island_area_km2) resolves a grid file, searching in order: an explicit path, $LANDMETRICS_DATA_DIR (colon-separated directory list), the bundled copy, the local cache ($LANDMETRICS_CACHE_DIR, else a platform user-cache directory), and finally a Zenodo download into the cache. landmetrics list shows every known grid and where it currently resolves; landmetrics fetch <kind> --resolution-deg ... --min-island-area-km2 ... downloads one explicitly.

The non-bundled grids are hosted in a single Zenodo deposit: 10.5281/zenodo.21959508.

The two bundled grids were generated from GSHHG scale "f" (full resolution), levels 1 (mainland and islands) and 5 (Antarctica, ice-shelf-front definition). See docs/grid_format.md for the full derivation and the file schema a third party would need to match to produce a compatible grid.

License

Code is MIT (see LICENSE). The grid data files are derived from GSHHG (Wessel & Smith 1996), which is released under the LGPL; the derived grids are redistributed under LGPL-3.0-or-later -- see DATA_LICENSE.

Command line

landmetrics query --lat 25.0 --lon -80.0
landmetrics fraction --lat 25.0 --lon -80.0 --radius-km 100 300 600
landmetrics list
landmetrics info <path-to-grid.nc>
landmetrics fetch land_fraction --resolution-deg 0.01 --min-island-area-km2 0

Citing

See CITATION.cff. A software DOI is minted by Zenodo on release; see the project's GitHub releases page for the current record. The grid data itself is archived separately: 10.5281/zenodo.21959508.

Metadata

Release files for landmetrics 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for landmetrics 1.0.0
File Size Uploaded
landmetrics-1.0.0.tar.gz 17.2 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for landmetrics 1.0.0
File Interpreter ABI Platform
landmetrics-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 34.4 MB

Release files / landmetrics-1.0.0.tar.gz

Download URL landmetrics-1.0.0.tar.gz
Size 17.2 MB
Tags Source
SHA-256 checksum
How to use checksums
27dfefddad859357a93e71252708e338412fd6d303f122ddfd1920e9a7fd6fad
BLAKE2b-256 checksum
How to use checksums
91bf724df8e8c20df028ea85f9d5fd46eeac73e861f0f88f742d5a6b9772270e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 15, 2026.

Transparency log

Release files / landmetrics-1.0.0-py3-none-any.whl

Download URL landmetrics-1.0.0-py3-none-any.whl
Size 17.2 MB
Tags Python 3
SHA-256 checksum
How to use checksums
7150d4871ca81d68758787603602a5be4997d179ce8e3840551184d37872788e
BLAKE2b-256 checksum
How to use checksums
943567e6ea9cffad84dcdbd527111df903aa823b921f9ff9f40e40c5425ccc1b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page