Skip to main content

OxiGeo Python Bindings

PyPI version Python versions License

Python bindings for OxiGeo, a pure Rust geospatial data abstraction library. OxiGeo provides high-performance geospatial operations with seamless NumPy integration.

Features

  • Pure Rust Performance: Leverages Rust's speed and safety
  • NumPy Integration: Zero-copy data transfer where possible
  • Raster Operations: Read/write GeoTIFF, Zarr, NetCDF, and more
  • Vector Operations: GeoJSON support with geometry operations
  • Raster Calculator: Algebraic expressions on raster data
  • Coordinate Transformations: Reprojection and warping
  • Type Hints: Full type stub support for IDEs
  • No External Dependencies: No GDAL installation required

Installation

From PyPI (recommended)

pip install oxigeo

From Source

# Install maturin
pip install maturin

# Build and install
cd crates/oxigeo-python
maturin develop --release

Quick Start

Reading Rasters

import oxigeo
import numpy as np

# Open a raster file
ds = oxigeo.open("input.tif")

# Get metadata
print(f"Size: {ds.width}x{ds.height}")
print(f"Bands: {ds.band_count}")

# Read a band as NumPy array
band1 = ds.read_band(1)
print(band1.shape, band1.dtype)

# Get full metadata
metadata = ds.get_metadata()
print(metadata)

# Close dataset
ds.close()

Writing Rasters

import oxigeo
import numpy as np

# Create test data
data = np.random.rand(512, 512).astype(np.float32)

# Create a new raster
ds = oxigeo.create_raster(
    "output.tif",
    width=512,
    height=512,
    bands=1,
    dtype="float32",
    crs="EPSG:4326",
    nodata=-9999.0
)

# Write data
ds.write_band(1, data)

# Set metadata
ds.set_metadata({
    "crs": "EPSG:4326",
    "nodata": -9999.0
})

# Close
ds.close()

Using Context Manager

import oxigeo
import numpy as np

# Automatically closes the dataset
with oxigeo.open("input.tif") as ds:
    data = ds.read_band(1)
    print(f"Mean: {data.mean():.2f}")

Raster Calculator

import oxigeo
import numpy as np

# Open multi-band image
ds = oxigeo.open("sentinel2.tif")
red = ds.read_band(3)   # Red band
nir = ds.read_band(4)   # NIR band

# Calculate NDVI using algebraic expression
ndvi = oxigeo.calc(
    "(NIR - RED) / (NIR + RED)",
    NIR=nir,
    RED=red
)

# More complex expressions
evi = oxigeo.calc(
    "2.5 * (NIR - RED) / (NIR + 6 * RED - 7.5 * BLUE + 1)",
    NIR=nir,
    RED=red,
    BLUE=ds.read_band(2)
)

# Simple arithmetic
scaled = oxigeo.calc("A * 0.0001 - 0.1", A=red)

Reprojection

import oxigeo

# Reproject to Web Mercator
oxigeo.warp(
    "input.tif",
    "output_3857.tif",
    dst_crs="EPSG:3857",
    resampling="bilinear"
)

# Resize raster
oxigeo.warp(
    "input.tif",
    "output_resized.tif",
    width=1024,
    height=1024,
    resampling="cubic"
)

# Reproject and resize
oxigeo.warp(
    "input.tif",
    "output.tif",
    dst_crs="EPSG:4326",
    width=2048,
    height=2048,
    resampling="lanczos"
)

Vector Operations

import oxigeo

# Read GeoJSON
features = oxigeo.read_geojson("input.geojson")
print(f"Features: {len(features['features'])}")

# Buffer a geometry
point = {
    "type": "Point",
    "coordinates": [0.0, 0.0]
}
buffered = oxigeo.buffer_geometry(point, distance=100.0)

# Write GeoJSON
output = {
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "geometry": buffered,
            "properties": {"name": "Buffered Point"}
        }
    ]
}
oxigeo.write_geojson("output.geojson", output, pretty=True)

API Reference

Core Functions

open(path: str, mode: str = "r") -> Dataset

Opens a geospatial dataset.

Parameters:

  • path: Path to file (local or remote URL)
  • mode: Open mode - "r" for read (default), "w" for write

Returns: Opened Dataset object

Raises:

  • IOError: If file cannot be opened
  • ValueError: If format is not supported

version() -> str

Returns the OxiGeo version string.

Raster Functions

create_raster(...) -> Dataset

Creates a new raster file.

Parameters:

  • path: Output file path
  • width: Width in pixels
  • height: Height in pixels
  • bands: Number of bands (default: 1)
  • dtype: Data type (default: "float32")
  • crs: CRS as WKT or EPSG code (optional)
  • nodata: NoData value (optional)

Returns: Created Dataset opened for writing

calc(expression: str, **arrays) -> np.ndarray

Raster calculator - evaluates expressions on raster data.

Parameters:

  • expression: Mathematical expression (e.g., "(A - B) / (A + B)")
  • **arrays: Named NumPy arrays (A=array1, B=array2, etc.)

Returns: Result array

Supported Operators:

  • Arithmetic: +, -, *, /, ** (power)
  • Comparison: <, >, <=, >=, ==, !=
  • Functions: sqrt, abs, log, exp, sin, cos, tan

warp(...) -> None

Reprojects (warps) a raster to different CRS or resolution.

Parameters:

  • src_path: Source raster path
  • dst_path: Destination raster path
  • dst_crs: Target CRS (EPSG code or WKT, optional)
  • width: Target width in pixels (optional)
  • height: Target height in pixels (optional)
  • resampling: Resampling method (default: "bilinear")
    • Options: "nearest", "bilinear", "cubic", "lanczos"

Vector Functions

read_geojson(path: str) -> dict

Reads a GeoJSON file.

Parameters:

  • path: Path to GeoJSON file

Returns: Parsed GeoJSON as dictionary

write_geojson(path: str, data: dict, pretty: bool = True) -> None

Writes a GeoJSON file.

Parameters:

  • path: Output path
  • data: GeoJSON data as dictionary
  • pretty: Pretty-print JSON (default: True)

buffer_geometry(geometry: dict, distance: float, segments: int = 8) -> dict

Buffers a geometry by specified distance.

Parameters:

  • geometry: GeoJSON geometry
  • distance: Buffer distance in geometry units
  • segments: Number of segments per quadrant (default: 8)

Returns: Buffered geometry as GeoJSON

Dataset Class

Properties

  • path: Dataset file path (read-only)
  • width: Width in pixels (read-only)
  • height: Height in pixels (read-only)
  • band_count: Number of bands (read-only)

Methods

read_band(band: int) -> np.ndarray

Reads a raster band as NumPy array.

Parameters:

  • band: Band number (1-indexed)

Returns: 2D NumPy array with shape (height, width)

write_band(band: int, array: np.ndarray) -> None

Writes a NumPy array to a raster band.

Parameters:

  • band: Band number (1-indexed)
  • array: 2D NumPy array to write
get_metadata() -> dict

Returns dataset metadata as a dictionary.

set_metadata(metadata: dict) -> None

Sets dataset metadata.

Parameters:

  • metadata: Metadata dictionary
close() -> None

Closes the dataset and flushes pending writes.

RasterMetadata Class

Metadata container for raster datasets.

Parameters:

  • width: Width in pixels
  • height: Height in pixels
  • band_count: Number of bands (default: 1)
  • data_type: Data type as string (default: "float32")
  • crs: CRS as WKT or EPSG code (optional)
  • nodata: NoData value (optional)

Methods:

  • to_dict(): Converts to dictionary

Exceptions

OxiGeoError

Base exception for all OxiGeo errors. Inherits from Exception.

Specific error types are mapped to appropriate Python exceptions:

  • IOError: File I/O errors
  • ValueError: Invalid parameters or data
  • NotImplementedError: Unsupported operations
  • RuntimeError: Internal errors

Data Types

Supported raster data types:

  • uint8, int8
  • uint16, int16
  • uint32, int32
  • uint64, int64
  • float32, float64
  • complex64, complex128

Supported Formats

Raster Formats

  • GeoTIFF (.tif, .tiff)
  • Cloud Optimized GeoTIFF (COG)
  • Zarr (.zarr)
  • NetCDF (.nc)

Vector Formats

  • GeoJSON (.geojson, .json)
  • FlatGeobuf (.fgb)
  • Shapefile (.shp)
  • GeoParquet (.parquet)

Performance Tips

  1. Use context managers for automatic resource cleanup
  2. Batch operations when processing multiple files
  3. Use appropriate data types - smaller types use less memory
  4. Leverage NumPy for array operations
  5. Use resampling wisely - "nearest" is fastest, "lanczos" highest quality

Examples

See the examples/ directory for complete examples:

  • raster_processing.py - Raster I/O and processing
  • ndvi_calculation.py - Vegetation index calculation
  • reprojection.py - Coordinate transformation
  • vector_operations.py - GeoJSON and geometry operations

Development

Requirements

  • Rust: 1.70 or later
  • Python: 3.9 or later
  • PyO3: 0.29.x (automatically handled by Cargo)
  • Maturin: For building Python wheels

Building from Source

# Install development dependencies
pip install maturin pytest pytest-cov mypy ruff

# Build in debug mode
maturin develop

# Build in release mode
maturin develop --release

# Run tests
pytest tests/

# Type checking
mypy python/oxigeo/

# Linting
ruff check python/

Build Configuration

The crate uses PyO3 with specific feature flags:

  • Default features (extension-module): For building Python extensions (.so/.dylib files)
  • Without extension-module: For Rust unit tests that need to initialize Python

The extension-module feature prevents linking to libpython (correct for Python extensions), but Rust unit tests need libpython to initialize the interpreter. See "Running Tests" section below for details.

Running Tests

Python Tests (Recommended)

# Run all tests
pytest tests/ -v

# Run with coverage
pytest tests/ --cov=oxigeo --cov-report=html

# Run specific test file
pytest tests/test_raster.py -v

Rust Unit Tests

The library uses PyO3 with the extension-module feature for building Python extensions. To run Rust unit tests, you need to build without this feature:

# Compile library (default - with extension-module)
cargo check -p oxigeo-python --lib

# Compile and run Rust unit tests (without extension-module)
cargo test -p oxigeo-python --no-default-features --features geotiff,geojson,algorithms

# Or using maturin
maturin develop && pytest tests/

Note: The extension-module feature is required for building the Python extension but prevents Rust unit tests from linking to libpython. This is a PyO3 design choice - Python-facing tests should use pytest, while Rust unit tests validate internal logic.

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

License

Licensed under the Apache License, Version 2.0. See LICENSE for details.

Citation

If you use OxiGeo in your research, please cite:

@software{oxigeo2026,
  title = {OxiGeo: Pure Rust Geospatial Data Abstraction Library},
  author = {{COOLJAPAN OU (Team Kitasan)}},
  year = {2026},
  url = {https://github.com/cool-japan/oxigeo}
}

Acknowledgments

  • Built with PyO3 for Rust-Python bindings
  • Uses maturin for packaging
  • Inspired by GDAL but pure Rust

Support

Related Projects

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

oxigeo-0.2.3.tar.gz (2.0 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

oxigeo-0.2.3-cp39-abi3-win_amd64.whl (1.5 MB view details)

Uploaded CPython 3.9+Windows x86-64

oxigeo-0.2.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.6 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ x86-64

oxigeo-0.2.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.5 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ ARM64

oxigeo-0.2.3-cp39-abi3-macosx_11_0_arm64.whl (1.4 MB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

oxigeo-0.2.3-cp39-abi3-macosx_10_12_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.9+macOS 10.12+ x86-64

File details

Details for the file oxigeo-0.2.3.tar.gz.

File metadata

  • Download URL: oxigeo-0.2.3.tar.gz
  • Upload date:
  • Size: 2.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for oxigeo-0.2.3.tar.gz
Algorithm Hash digest
SHA256 2404a24250cc55b07678a6bd3ab557443fb2ebc6935fc08ca498c56a81c85143
MD5 d090540fcf7756daa4af442ea1c0ac85
BLAKE2b-256 c621c2b8b7319a7505e7dd3c62162e89f82bc354649f9f521e7ad9ccfcc57b7d

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxigeo-0.2.3.tar.gz:

Publisher: pypi-publish.yml on cool-japan/oxigeo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file oxigeo-0.2.3-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: oxigeo-0.2.3-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 1.5 MB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for oxigeo-0.2.3-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 887cc9d8c5c7ad56703f2bece178e3ee4cb21b307be11b9513a10eb1c650aca8
MD5 843b75091b5b10907c134f471e668adf
BLAKE2b-256 3b77dbe792e928362c0ea65d61327d05d5c1b45a4bf2b0dc0f94c1e17ca750b8

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxigeo-0.2.3-cp39-abi3-win_amd64.whl:

Publisher: pypi-publish.yml on cool-japan/oxigeo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file oxigeo-0.2.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for oxigeo-0.2.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d47e632e12db70678bde32b98203cdb41d5e4034822dbf1f1c1c968b13c16b2a
MD5 3f7bba60b29d48bb085b67f7dee30087
BLAKE2b-256 1fcd6534f41bcd5dd5384c720ffcb13c7b402aae6df141372d24d1928c38e1b8

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxigeo-0.2.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: pypi-publish.yml on cool-japan/oxigeo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file oxigeo-0.2.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for oxigeo-0.2.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 164decb24b371f026a832a7affb2f205c8551d9bff39fde464ab4b68b3fab645
MD5 8c4f8d91b6310c1569e5c4f9233ec5f3
BLAKE2b-256 4ff9a062165ac5b7c4180c2860aa030406c9e17c2c72a98d694d8fc37f88062e

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxigeo-0.2.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: pypi-publish.yml on cool-japan/oxigeo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file oxigeo-0.2.3-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for oxigeo-0.2.3-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c35215077505b642bd81eccdc9c90e73144d1b4f2dc9d03db58c9b28f966d842
MD5 314162193d753f29e33ecadc70161d00
BLAKE2b-256 742350b8e3c4aa27a04c7ac43d01387cd615dc79819f74a9b9c36cda75ecb299

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxigeo-0.2.3-cp39-abi3-macosx_11_0_arm64.whl:

Publisher: pypi-publish.yml on cool-japan/oxigeo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file oxigeo-0.2.3-cp39-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for oxigeo-0.2.3-cp39-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 d02f127e5d7cb8d2cc4a9d6c20390711c58fbe6328d881cf361a2822db1da27f
MD5 fcfa447d8b796a70e8bc876f30535e70
BLAKE2b-256 1f250a16fd50412cd888c83d5e62f20ea3ca26a8a0897891bb247f61c356b3b1

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxigeo-0.2.3-cp39-abi3-macosx_10_12_x86_64.whl:

Publisher: pypi-publish.yml on cool-japan/oxigeo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.2.4

6 files

This release

0.2.3 This release

6 files

0.2.2

6 files

0.2.1

6 files

0.2.0

6 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