Skip to main content

terrio

terrio

PyPI CI License: MIT

Python bindings for terrio: read, write, convert and reproject geospatial rasters, vector datasets and point clouds in pure Rust, without GDAL. Wheels need only NumPy (and the small affine package).

pip install terrio

Coming from rasterio

rasterio scripts run with an import change: terrio.rio follows rasterio's API (datasets, windows, CRSs, features, warping, merging, masking, warped VRTs, memory files), compared with rasterio on real files. See Coming from rasterio.

import terrio.rio as rasterio

with rasterio.open("https://example.com/cog.tif") as src:  # read lazily, by window
    profile = src.profile
    dem = src.read(1, out_shape=(512, 512), masked=True)  # through the overviews

xarray

terrio.xarray is rioxarray's API without GDAL (pip install "terrio[xarray]"): rasters open lazily as DataArrays with rioxarray's coordinates, attributes and encoding, and the .terrio accessor has rioxarray's .rio methods. See xarray.

import xarray as xr
import terrio.xarray as txr

da = txr.open_rasterio("https://example.com/cog.tif", masked=True, chunks=True)
ds = xr.open_dataset("dem.tif", engine="terrio")
sub = da.terrio.clip_box(-105.5, 39.5, -105.0, 40.0, crs="EPSG:4326")  # fetches its tiles only
sub.terrio.reproject("EPSG:32613", resampling="bilinear").terrio.to_raster("sub.tif", driver="COG")

Rasters

import terrio

dem = terrio.open_raster("dem.tif")
dem.width, dem.height, dem.count, dem.dtype  # dtype is a NumPy name: "float32", "uint8"...
dem.crs, dem.transform, dem.bounds, dem.nodata
elevation = dem.read(1)  # numpy array (rows, cols) of the raster's own dtype
everything = dem.read()  # (bands, rows, cols)

# GeoTIFFs and COGs, local or remote, can be read by window: only the tiles a window needs are
# decoded, and fetched with HTTP range requests.
cog = terrio.open_raster("https://example.com/cog.tif", lazy=True)
cog.overviews  # [(width, height), ...] of the overviews, largest first
tile = cog.read(1, window=(1024, 1024, 512, 512))  # (col_off, row_off, width, height)
thumb = cog.read(overview=2)
# PMTiles and MBTiles raster tiles too: zoom levels are overviews (PMTiles read in place).
tiles = terrio.open_raster("https://example.com/tiles.pmtiles", lazy=True)

out = terrio.Raster.from_array(elevation * 3.28084, dem.transform, crs=dem.crs, nodata=dem.nodata)
out.write("dem_feet.tif", compress="DEFLATE")
out.write("dem_feet_cog.tif", driver="COG")
out.write("dem.zarr", options={"FORMAT": "ZARR_V3", "GEOREFERENCING_CONVENTION": "SPATIAL_PROJ"})  # GeoZarr

# STAC: a mosaic of an asset over a search's items (or an item's asset, 'STAC:"item.json":red'), read by window.
red = terrio.open_raster('STACIT:"https://earth-search.aws.element84.com/v1/search?collections=sentinel-2-l2a&bbox=-105.05,40.5,-104.95,40.6&datetime=2023-07-05":asset=red', lazy=True)
terrio.open_raster("landsat.tif").write("landsat.pmtiles")  # Byte rasters as tiles (or .mbtiles)

Vector data

ds = terrio.open_vector("countries.gpkg")  # or .shp, .geojson, .fgb, .parquet, .kml, .zip...
layer = ds.layers[0]  # also ds["countries"]
layer.name, layer.crs, layer.geometry_type, layer.fields, len(layer), layer.bounds
collection = layer.to_geojson()  # a GeoJSON FeatureCollection dict
wkb = layer.to_wkb()  # one WKB geometry per feature
columns = layer.columns()  # attribute values by field
gdf = layer.to_geopandas()  # with geopandas installed

terrio.write_vector(layer.to_crs("EPSG:3857"), "countries_3857.fgb")
terrio.write_vector(collection, "countries.geojson")  # GeoJSON dicts, GeoDataFrames...

Point clouds

LAS 1.0 to 1.4 (point formats 0 to 10, extra bytes, waveforms), LAZ, COPC, EPT, PLY and E57. Remote COPC files and EPT datasets are read in place: only the octree nodes a read needs are fetched. Files larger than memory are read and written in chunks (PointCloudFile.chunks, PointCloudWriter); PDAL's filters (smrf, outlier, range, sample, voxel_downsize, voxel_center_nearest_neighbor) and TIN and nearest-neighbour gridding are PointCloud methods.

f = terrio.open_points("https://s3.amazonaws.com/hobu-lidar/autzen-classified.copc.laz")
f.format, f.point_count, f.crs, f.bounds, f.header, f.dimensions
f.info(stats=True)  # the summary `terrio info --json --stats` prints: classes, returns...
points = f.read(bounds=(637000, 851000, 637500, 851500), max_level=4)  # or resolution=, max_points=

points = terrio.read_points("tile.laz", classes=[2], returns=["last", "only"])
z = points["z"]  # NumPy arrays: x, y, z (scaled float64), intensity (uint16), classification...
points.to_dict()  # {name: array}
points.to_numpy()  # a structured array
points.write("ground.copc.laz")  # LAS, LAZ, COPC, PLY or E57
dem = points.grid(1.0, stat="idw")  # a Raster (min, max, mean, idw, count, stdev; like PDAL)
points.to_layer(dimensions=["z", "intensity"]).to_geopandas()
terrio.convert_points("tile.laz", "tile_wgs84.laz", t_srs="EPSG:4326")
terrio.convert_points("tile.laz", "ground.gpkg", classes=[2])  # a layer of points

terrio.PointCloud.from_dict({"x": xs, "y": ys, "z": zs, "intensity": i}, crs="EPSG:32610")

Operations

The operations take the command-line options as keyword arguments. Inputs are paths or objects in memory; outputs are returned, and also written when a destination is given.

terrio.info("dem.tif", stats=True)  # the same dict as `terrio info --json`
terrio.convert("countries.shp", "europe.gpkg", where="CONTINENT = 'Europe'", select=["NAME"])
terrio.convert("https://example.com/cog.tif", "window.tif", srcwin=(0, 0, 512, 512))
terrio.translate("dem.tif", "small.tif", outsize=("25%", "25%"), resampling="average")
terrio.warp("dem.tif", "dem_4326.tif", t_srs="EPSG:4326", resampling="bilinear")
terrio.mosaic(["n40w106.tif", "n40w107.tif"], "mosaic.tif")
terrio.rasterize("counties.gpkg", "pop.tif", attribute="POPULATION", tr=(0.01, 0.01), ot="Int32")
polygons = terrio.polygonize("landcover.tif", connectedness=8)
shade = terrio.dem("dem.tif", "hillshade", z=2, multidirectional=True)  # like gdaldem
terrio.dem("dem.tif", "color-relief", "relief.tif", color_file="colors.txt", alpha=True)
ndvi = terrio.calc("(B - A * 1.0) / (B + A * 1.0)", A="landsat.tif", A_band=3, B="landsat.tif", B_band=4,
                   type="Float32")  # like gdal_calc.py, with NumPy's typing rules
dist = terrio.proximity("roads.tif", values=[1], distunits="GEO")
clean = terrio.sieve("landcover.tif", threshold=10, connectedness=8)
xs, ys = terrio.transform_points([699960], [3900000], "EPSG:32610", "EPSG:4326")

data = open("dem.tif", "rb").read()
raster = terrio.open_bytes(data, "dem.tif")  # from bytes; to bytes with raster.to_bytes("x.tif")

Errors raise terrio.TerrioError subclasses, which also derive from the matching built-in exceptions: NotFoundError is a FileNotFoundError, TerrioIOError an OSError, and InvalidArgumentError, CRSError, UnsupportedError and InvalidDataError are ValueErrors.

Development

cd python
uv venv && uv pip install maturin numpy pytest
uv run maturin develop
uv run pytest                                    # synthetic tests
TERRIO_TEST_DATA=../../terrio-data uv run pytest # real files, compared with GDAL when installed

Metadata

Release files for terrio 0.3.1

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

Source distribution (sdist)

Source distribution for terrio 0.3.1
File Size Uploaded
terrio-0.3.1.tar.gz 1.6 MB Details

Built distributions (wheels)

Table of built distributions (wheels) for terrio 0.3.1
File
terrio-0.3.1-cp310-abi3-win_arm64.whl CPython 3.10 abi3 Windows ARM64 Details
terrio-0.3.1-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
terrio-0.3.1-cp310-abi3-musllinux_1_2_x86_64.whl CPython 3.10 abi3 Linux musl 1.2+ x86-64 Details
terrio-0.3.1-cp310-abi3-musllinux_1_2_aarch64.whl CPython 3.10 abi3 Linux musl 1.2+ ARM64 Details
terrio-0.3.1-cp310-abi3-manylinux_2_28_aarch64.whl CPython 3.10 abi3 Linux glibc 2.28+ ARM64 Details
terrio-0.3.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details
terrio-0.3.1-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details
terrio-0.3.1-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details

Total release size: 136.6 MB

Release files / terrio-0.3.1.tar.gz

Download URL terrio-0.3.1.tar.gz
Size 1.6 MB
Tags Source
SHA-256 checksum
How to use checksums
b9135d68b84d5e91aa08038d67a9cad6d5375355b20d11cfa3b3d029eba58574
BLAKE2b-256 checksum
How to use checksums
8980732987025d724ee4b2f70aafcd967c52df6579c20a325d872c6cb646e7b5
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 Oct 17, 2026.

Transparency log

Release files / terrio-0.3.1-cp310-abi3-win_arm64.whl

Download URL terrio-0.3.1-cp310-abi3-win_arm64.whl
Size 14.6 MB
Tags CPython 3.10 Windows ARM64 abi3
SHA-256 checksum
How to use checksums
959d25bb1baa32520feb16903e9d9b158c840212c997fb79d7b961375fe398c0
BLAKE2b-256 checksum
How to use checksums
c82f57d6d84e68d9350cef9032e9ea68d7de30005e8e1ff42654a14daa03dbf6
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 Oct 17, 2026.

Transparency log

Release files / terrio-0.3.1-cp310-abi3-win_amd64.whl

Download URL terrio-0.3.1-cp310-abi3-win_amd64.whl
Size 15.7 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
20a84aefe4bf9d505e0d3b6498d7a7b28299a88408dafbe5ed4364c8011a0328
BLAKE2b-256 checksum
How to use checksums
51bc2113b0ac50369725192f224dba64c7eef291530dd20e5ed84856eb5ad8aa
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 Oct 17, 2026.

Transparency log

Release files / terrio-0.3.1-cp310-abi3-musllinux_1_2_x86_64.whl

Download URL terrio-0.3.1-cp310-abi3-musllinux_1_2_x86_64.whl
Size 18.7 MB
Tags CPython 3.10 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
e0a9e89b08c24e1866a706543c74a4620a170be9d02a4c66e321ce203ca0464c
BLAKE2b-256 checksum
How to use checksums
d24da2d0af54f5ae87af76f599b034fddaa15cacf941d36d78a5c7b6c69cd702
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 Oct 17, 2026.

Transparency log

Release files / terrio-0.3.1-cp310-abi3-musllinux_1_2_aarch64.whl

Download URL terrio-0.3.1-cp310-abi3-musllinux_1_2_aarch64.whl
Size 18.0 MB
Tags CPython 3.10 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
288bdb500c7e6e112209fe724508e244c98d6c0d2b512f84f6e6d1b0238a49aa
BLAKE2b-256 checksum
How to use checksums
99af2f252b9690c4447da360cdb41fc9a0b9d0dc2e8467713532b95d684dfc61
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 Oct 17, 2026.

Transparency log

Release files / terrio-0.3.1-cp310-abi3-manylinux_2_28_aarch64.whl

Download URL terrio-0.3.1-cp310-abi3-manylinux_2_28_aarch64.whl
Size 17.8 MB
Tags CPython 3.10 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
e52edda7b0f6891c23e74bd64eac4333df3ca01e56bdf0f6f499091cc288c2e1
BLAKE2b-256 checksum
How to use checksums
af6266fa4bd6bd1f65c9884c5e9c72cb60828aadf7bd3072277b204cd63bf0cd
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 Oct 17, 2026.

Transparency log

Release files / terrio-0.3.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL terrio-0.3.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 17.6 MB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
f905e3c40bf8398bf652eb1ad3efdf0fb2244c7274e035beeb7e1ce6d4fd6633
BLAKE2b-256 checksum
How to use checksums
c64320e88620572e52ed86f00fbfc3f6f8bf94eda4137733e50e5f5739728ec4
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 Oct 17, 2026.

Transparency log

Release files / terrio-0.3.1-cp310-abi3-macosx_11_0_arm64.whl

Download URL terrio-0.3.1-cp310-abi3-macosx_11_0_arm64.whl
Size 15.9 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
c6e6bcf30b589eeeb92f58e68f82c9d9b3b087081f30d670187cfdeca09c96da
BLAKE2b-256 checksum
How to use checksums
47c8d6f8572caebb0191e10dab60a737c0ad351a5731f3d4dc33298f1bd0982f
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 Oct 17, 2026.

Transparency log

Release files / terrio-0.3.1-cp310-abi3-macosx_10_12_x86_64.whl

Download URL terrio-0.3.1-cp310-abi3-macosx_10_12_x86_64.whl
Size 16.6 MB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
aeb1b95cbb6b7d38876d4efd90bd7f4f79efad8b96c606baadf4e17af9466e66
BLAKE2b-256 checksum
How to use checksums
2d80b3e42915c93324992fece28d6fdfd17643442d2879dbab572b7bba38d9e7
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 Oct 17, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.1 This release

9 release files

0.2.0

9 release files

0.1.1

7 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