Skip to main content

GeoSlice

Ultra-fast geospatial windowing with zero-copy memory mapping.

CI PyPI Python

Performance

Head-to-Head: GeoSlice vs Rasterio

============================================================
COMPARISON: 100 x 512x512 windows (4096x4096 4-band image)
============================================================
Method               Time (s)     Ops/s        Speedup
------------------------------------------------------------
GeoSlice (mmap)      0.0003       305,737      154.6x
Rasterio             0.0506       1,977        1.0x
============================================================

Detailed Benchmarks

Test GeoSlice Rasterio Speedup
Single 512x512 window 1.4us (690k ops/s) 170us (5.9k ops/s) 117x
100 sequential windows 129us (7.7k ops/s) 16.6ms (60 ops/s) 128x
100 random windows 126us (8.0k ops/s) 30.4ms (33 ops/s) 241x
50-waypoint flight sim 24us (41k ops/s) 1.4ms (707 ops/s) 59x

Coordinate Transform Performance

Operation Time Throughput
latlon->pixel (x1000) 2.0ms 494 ops/s
FOV->pixels (x1000) 203us 4,937 ops/s

Install

pip install geoslice

For converting GeoTIFFs:

pip install geoslice[convert]
sudo apt install gdal-bin  # Linux

Supported Python: 3.8+ Supported OS: Linux, macOS

Quick Start

1. Convert GeoTIFF (one-time)

from geoslice import convert_tif_to_raw

convert_tif_to_raw("input.tif", "output_map")
# Creates: output_map.bin, output_map.json

Or via CLI:

gdal_translate -of ENVI -co INTERLEAVE=BSQ input.tif output_map.bin

2. Access Windows

from geoslice import FastGeoMap

loader = FastGeoMap("output_map")

# Zero-copy window access (~690k ops/s)
window = loader.get_window(x=100, y=100, width=512, height=512)
print(window.shape)  # (bands, height, width)

# Bounds-checked — raises ValueError if out of range
if loader.is_valid_window(x, y, w, h):
    window = loader.get_window(x, y, w, h)

3. Drone Simulation

from geoslice import FastGeoMap, GeoTransform, FlightPath

loader = FastGeoMap("output_map")
geo = GeoTransform(loader.meta.transform, utm_zone=36)

# Generate spiral flight path
path = FlightPath.spiral(
    center_lat=31.45,
    center_lon=34.80,
    num_waypoints=50,
    altitudes=[50, 100, 150, 200],
)

# Extract windows along path (~41k waypoints/sec)
for state in path:
    win = FlightPath.state_to_window(state, geo)
    if win.is_valid(loader.width, loader.height):
        data = loader.get_window(win.x, win.y, win.width, win.height)
        # Process frame...

API

FastGeoMap

FastGeoMap(base_name: str, use_cpp: bool = None)
  • get_window(x, y, width, height) -> np.ndarray (view, zero-copy). Raises ValueError if out of bounds.
  • get_window_copy(x, y, width, height) -> np.ndarray (copy, safe for modification)
  • is_valid_window(x, y, width, height) -> bool
  • .width, .height, .bands, .shape, .meta

GeoTransform

GeoTransform(transform: tuple, utm_zone: int = 36)
  • latlon_to_pixel(lat, lon) -> (px, py). Validates lat in [-80, 84] (UTM range).
  • pixel_to_latlon(px, py) -> (lat, lon)
  • fov_to_pixels(altitude_m, fov_deg) -> (width, height)

FlightPath

FlightPath.spiral(center_lat, center_lon, num_waypoints, altitudes, fov_deg)
FlightPath.linear(start_lat, start_lon, end_lat, end_lon, num_waypoints, altitude_m)
FlightPath.grid(min_lat, min_lon, max_lat, max_lon, rows, cols, altitude_m)
  • state_to_window(state, geo) -> WindowParams
  • compute_windows(geo) -> List[WindowParams]

How It Works

Rasterio (standard approach):

Seek -> Read -> Decompress -> Allocate -> Copy to RAM

GeoSlice (mmap approach):

Pointer arithmetic -> OS pages in 4KB chunks on-demand

The OS kernel handles caching, prefetching, and memory management. Random access is 241x faster because there's no decompression overhead.

Data Format

GeoSlice operates on pre-converted raw binary files (BSQ interleave) with JSON metadata sidecars:

  • .bin — Raw raster data in Band Sequential format (no compression)
  • .json — Metadata: dtype, dimensions, affine transform, CRS

The conversion step (convert_tif_to_raw or gdal_translate) is a one-time cost that enables all subsequent reads to be zero-copy via mmap.

Input Validation

The library validates inputs at system boundaries:

  • JSON metadata is checked for required fields and valid values
  • Binary file size is verified against metadata dimensions
  • Window coordinates are bounds-checked before access
  • UTM latitude range is validated in coordinate transforms
  • Cache keys use collision-resistant hashing with coordinate verification

C++ Usage

#include <geoslice/geoslice.hpp>

geoslice::MMapReader reader("processed_map");
auto view = reader.get_window(100, 100, 512, 512);

// Zero-copy access
uint8_t pixel = view.at<uint8_t>(0, 0, 0);  // band, y, x

WindowCache

Thread-safe LRU cache with shared_ptr semantics — cached data stays valid even after eviction as long as you hold a reference:

geoslice::WindowCache cache(64 * 1024 * 1024); // 64MB

cache.put(x, y, w, h, data_ptr, size);

auto entry = cache.get(x, y, w, h); // shared_ptr<const CachedWindow>
if (entry) {
    // Safe to use entry->data even if cache evicts this slot later
    process(entry->data.data(), entry->data.size());
}

Development

Setup

git clone https://github.com/PavelGuzenfeld/geoslice
cd geoslice

# Create venv
python3 -m venv .venv
source .venv/bin/activate

# Install with dev dependencies
pip install -e ".[dev]"

Run Tests

# All tests
pytest -v

# Benchmarks with comparison table
pytest tests/test_benchmark.py -v -s

# Just the comparison report
pytest tests/test_benchmark.py::TestDirectComparison -v -s

# Detailed benchmark stats
pytest tests/test_benchmark.py --benchmark-only --benchmark-columns=min,max,mean,ops

Build C++ (optional)

cmake -B build -DBUILD_PYTHON=OFF
cmake --build build
ctest --test-dir build --output-on-failure

Release

Releases are automated via GitHub Actions on version tags:

# Update version in pyproject.toml, setup.py, geoslice.hpp, __init__.py
git add -A
git commit -m "Release v0.1.0"
git tag v0.1.0
git push && git push --tags

License

MIT License. See LICENSE file for details.

Metadata

Release files for geoslice 0.1.2

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

Source distribution (sdist)

Source distribution for geoslice 0.1.2
File Size Uploaded Provenance
geoslice-0.1.2.tar.gz 34.5 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 45.9 kB

Release files / geoslice-0.1.2.tar.gz

Download URL geoslice-0.1.2.tar.gz
Size 34.5 kB
Tags Source
SHA-256 checksum
How to use checksums
8aca34a4bf9e4144d8991fbe6a86054cb626c18e4dc9994dcb834f6caa7b3f16
BLAKE2b-256 checksum
How to use checksums
aeeb7def733b468fed25325aefd11085c0c97b8dc77e583044cfaecb39250d4e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / geoslice-0.1.2-py3-none-any.whl

Download URL geoslice-0.1.2-py3-none-any.whl
Size 11.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
24fb6c516ae115abaef99c392b2f4833d56b9ab9206e942cf955b3da72bf22b5
BLAKE2b-256 checksum
How to use checksums
e812068bcb960aa303525867055d59e32fc9a9018171a66ff30580a332a75279
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Security for geoslice 0.1.2

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

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