Skip to main content

Ultra-fast geospatial windowing with zero-copy memory mapping

Project description

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.4μs (690k ops/s) 170μs (5.9k ops/s) 117x
100 sequential windows 129μs (7.7k ops/s) 16.6ms (60 ops/s) 128x
100 random windows 126μs (8.0k ops/s) 30.4ms (33 ops/s) 241x
50-waypoint flight sim 24μs (41k ops/s) 1.4ms (707 ops/s) 59x

Coordinate Transform Performance

Operation Time Throughput
latlon→pixel (×1000) 2.0ms 494 ops/s
FOV→pixels (×1000) 203μs 4,937 ops/s

Install

pip install geoslice

For converting GeoTIFFs:

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

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)

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)
  • get_window_copy(x, y, width, height)np.ndarray (copy)
  • 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)
  • 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.

Development

Setup

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

# Create venv (use --system-site-packages if you need ROS2)
python3 -m venv .venv --system-site-packages
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

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

Release

Releases are automated via GitHub Actions on version tags:

# Update version in pyproject.toml and python/geoslice/__init__.py
git add -A
git commit -m "Release v0.0.2"
git tag v0.0.2
git push && git push --tags

License

MIT License. See LICENSE file for details.

Project details


Download files

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

Source Distribution

geoslice-0.0.2.tar.gz (26.4 kB view details)

Uploaded Source

Built Distribution

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

geoslice-0.0.2-py3-none-any.whl (10.6 kB view details)

Uploaded Python 3

File details

Details for the file geoslice-0.0.2.tar.gz.

File metadata

  • Download URL: geoslice-0.0.2.tar.gz
  • Upload date:
  • Size: 26.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for geoslice-0.0.2.tar.gz
Algorithm Hash digest
SHA256 1b0198a4dee73ea8c70a7b7d08cf69996989eaf46b9c89a7ce96deb67ba6ca96
MD5 073cdc74a1539287b08d11f6d56a51dc
BLAKE2b-256 50a9e0c9fe056b0cf98b9f127a7b0e0a85710ab248c5141a2ad2c7cf0bb7c286

See more details on using hashes here.

File details

Details for the file geoslice-0.0.2-py3-none-any.whl.

File metadata

  • Download URL: geoslice-0.0.2-py3-none-any.whl
  • Upload date:
  • Size: 10.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for geoslice-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 360e27d97618099250ff4c2a14eb8e2a83a7bf0f8a22569fff71c197137b5d7d
MD5 23db29769f7f8a2f9ebf101c322b79b0
BLAKE2b-256 657cee46a3d7b9293dff50f89153b7324ee99eb9fdf489fa56d46b9cb86cbd15

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page