High-performance geospatial processing with GPU acceleration, Numba JIT, and format conversion
Project description
GeoFast
High-performance geospatial processing framework with GPU acceleration, Numba JIT compilation, file format conversion, and intelligent caching.
Features
- Multi-backend execution: CPU, CPU Parallel, GPU (CUDA), Numba JIT, Hybrid
- Automatic backend selection: Based on data size and available hardware
- File format conversion: GeoJSON, KML, GPX, CSV, MPZ/MapPlus
- Numba JIT primitives: Point-in-polygon, haversine, Douglas-Peucker, hex grids
- Spatial indexing: R-tree, hex grid index, point index
- GPU kernels: CUDA acceleration via Numba CUDA and CuPy
- Intelligent caching: Memory and disk caching for expensive computations
- Command-line interface: Convert files, view system info, manage cache
Installation
# Basic installation (CPU only)
pip install geofast
# With Numba JIT support (recommended)
pip install geofast[full]
# With GPU support (requires NVIDIA GPU + CUDA)
pip install geofast[gpu]
# Everything
pip install geofast[all]
Quick Start
File Format Conversion
from geofast import convert, read_kml, MPZReader
# Convert between formats (auto-detects from extension)
convert('tracks.kml', 'tracks.geojson')
convert('field.geojson', 'field.kml')
convert('points.csv', 'points.gpx')
# Read KML directly
data = read_kml('file.kml') # Returns GeoJSON-like dict
# Read MapPlus/MPZ files
with MPZReader('data.mpz') as reader:
tracks = reader.get_tracks()
polygons = reader.get_polygons()
geojson = reader.to_geojson()
High-Performance Primitives
from geofast import (
haversine_scalar, haversine_batch,
point_in_polygon, points_in_polygon_batch,
douglas_peucker,
lat_lon_to_hex, polygon_to_hex_cells,
)
import numpy as np
# Fast haversine distance (Numba JIT)
dist = haversine_scalar(lat1, lon1, lat2, lon2, radius=3959) # miles
# Batch operations (parallel)
lats1 = np.array([40.0, 41.0, 42.0])
lons1 = np.array([-74.0, -73.0, -72.0])
distances = haversine_batch(lats1, lons1, lats2, lons2)
# Point-in-polygon (Numba JIT)
poly_x = np.array([0, 1, 1, 0, 0], dtype=np.float64)
poly_y = np.array([0, 0, 1, 1, 0], dtype=np.float64)
inside = point_in_polygon(0.5, 0.5, poly_x, poly_y) # True
# Line simplification
coords = np.array([[0, 0], [1, 0.1], [2, 0], [3, 0.1], [4, 0]])
simplified = douglas_peucker(coords, epsilon=0.2)
# Hex grid operations
q, r = lat_lon_to_hex(40.7128, -74.0060, hex_size_lat=0.001, hex_size_lon=0.001)
Spatial Indexing
from geofast import SpatialIndex, HexGridIndex
# R-tree index for fast polygon queries
index = SpatialIndex()
index.add_polygon('field1', polygon_coords)
index.add_polygon('field2', polygon_coords)
index.build()
# O(log n) point query
hits = index.query_point(lon, lat)
# Hex grid index for O(1) lookups
hex_index = HexGridIndex(hex_size_lat=0.001, hex_size_lon=0.001)
hex_index.add_polygons(polygons_dict)
hex_index.build()
field_ids = hex_index.query_point(lat, lon)
GPU Acceleration
from geofast import haversine_auto, hex_keys_auto, gpu_available
# Automatically uses GPU for large arrays, CPU for small
distances = haversine_auto(lats1, lons1, lats2, lons2)
q_arr, r_arr = hex_keys_auto(lats, lons, hex_size_lat, hex_size_lon)
# Check GPU availability
if gpu_available():
print("GPU acceleration available!")
Caching
from geofast import (
get_polygon_cell_cache,
cached,
set_cache_config,
print_cache_stats,
)
# Enable/configure caching
set_cache_config(enabled=True, cache_dir='~/.geofast/cache')
# Cache expensive computations
cache = get_polygon_cell_cache()
cells = cache.get_or_compute(polygon, hex_lat, hex_lon, compute_func)
# Decorator for automatic caching
@cached(cache_type='disk', ttl=3600)
def expensive_computation(data):
...
# View cache statistics
print_cache_stats()
Decorator-based Backend Selection
from geofast import process, Backend
# Auto-select best backend based on data size
@process(backend=Backend.AUTO, item_count_arg="geometries")
def simplify_fields(geometries, tolerance=0.001):
from shapely import simplify
return list(simplify(geometries, tolerance))
# Force GPU with CPU fallback
@process(backend=Backend.GPU, fallback=Backend.CPU)
def compute_distances(lats1, lons1, lats2, lons2):
...
# Parallel file processing
@process(backend=Backend.CPU_PARALLEL, batch=True)
def convert_files(filepaths):
...
Command Line Interface
# Convert files
geofast convert input.kml output.geojson
geofast convert tracks.mpz tracks.geojson
# Show system info
geofast info
geofast info --cache
# Manage cache
geofast cache --stats
geofast cache --clear
# List supported formats
geofast formats
Supported File Formats
| Format | Read | Write | Notes |
|---|---|---|---|
| GeoJSON | ✅ | ✅ | .geojson, .json |
| KML | ✅ | ✅ | .kml |
| GPX | ✅ | ✅ | .gpx (tracks, waypoints, routes) |
| CSV | ✅ | ✅ | Requires lat/lon columns |
| MPZ/MapPlus | ✅ | ❌ | .mpz, .sdb (SQLite-based) |
| Shapefile | ✅ | ✅ | Requires fiona |
Backends
| Backend | Best For | Requirements |
|---|---|---|
CPU |
Small datasets, simple operations | numpy |
CPU_PARALLEL |
File I/O, embarrassingly parallel tasks | numpy |
GPU |
Large arrays (10k+), matrix operations | cupy |
NUMBA |
Tight loops, custom algorithms | numba |
NUMBA_CUDA |
Custom GPU kernels | numba + CUDA |
HYBRID |
Very large datasets, max throughput | all |
AUTO |
Let GeoFast decide | any |
Configuration
from geofast import set_config
set_config(
max_workers=8, # CPU cores to use
chunk_size=1000, # Items per parallel chunk
gpu_batch_size=10000, # Items per GPU batch
auto_gpu_min_items=1000, # Threshold for AUTO->GPU
verbose=True # Log backend selection
)
Performance
Benchmarks on a system with 16 CPU cores and NVIDIA RTX 4050:
| Operation | Original | With GeoFast | Speedup |
|---|---|---|---|
| Polygon cell computation (7352 polygons) | ~20s | 1.3s (cached) | 15x |
| Track processing (262 tracks) | ~60s | 10.7s | 5.6x |
| Point-in-polygon (batch) | ~30s | 4.7s | 6.4x |
| Full analysis pipeline | ~300s | 41s | 7.3x |
Spray Pattern Generation
Generate optimal spray lines for agricultural fields:
from geofast import generate_spray_patterns
# Generate spray lines from field boundaries
generate_spray_patterns(
'fields.kml', # Input: field polygons
'spray_lines.geojson', # Output: spray lines + boundaries
config={
'swath_width_ft': 50, # Spray width per pass
'hop_distance_ft': 1300 # Max gap for pilot hopping
}
)
Features
- Optimal direction selection: Automatically chooses N-S or E-W based on field shape
- Multi-field optimization: Groups nearby fields for consistent spray direction
- Powerline detection: Flags fields with
hasPowerlines: truewhen transmission lines intersect - Efficiency metrics: Calculates acres/hour, total time, line counts
Command Line
# Basic usage
geofast spray field.kml lines.geojson
# With options
geofast spray field.kml lines.geojson --swath 60 --metadata
# Ground operations (no hopping)
geofast spray field.kml lines.geojson --no-hop
Output Properties
Each field boundary in the output includes:
hasPowerlines: Boolean indicating if powerlines cross the fieldangle: Optimal spray direction (0=N-S, 90=E-W)acres: Field areanum_tracks: Number of spray passes
Project Structure
geofast/
├── __init__.py # Package exports
├── core.py # Backend enum, @process decorator
├── executor.py # Backend dispatch logic
├── primitives.py # Numba JIT functions
├── spatial_index.py # R-tree, hex grid indexing
├── cuda_kernels.py # GPU kernels (CUDA/CuPy)
├── parallel.py # Shared memory, parallel utilities
├── geo_ops.py # High-level geo operations
├── formats.py # File format converters
├── cache.py # Caching layer
├── cli.py # Command-line interface
└── utils.py # Detection, helpers
Requirements
- Python 3.9+
- numpy
Optional
- numba (for JIT compilation)
- shapely 2.0+ (for spatial operations)
- cupy (for GPU acceleration)
- geopandas, fiona (for shapefile support)
License
MIT License - see LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file geofast-0.4.0.tar.gz.
File metadata
- Download URL: geofast-0.4.0.tar.gz
- Upload date:
- Size: 54.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8bee0283e63dd32478c4a6fdb68397eb572a37055307df2d8bd19f01e0bae354
|
|
| MD5 |
df6e8fc477f475908fc529441f0172b4
|
|
| BLAKE2b-256 |
1a2b6bd830bfc4f1b8d82353786a4265364bde5fea9a92ca0f2da760d69a1ef5
|
File details
Details for the file geofast-0.4.0-py3-none-any.whl.
File metadata
- Download URL: geofast-0.4.0-py3-none-any.whl
- Upload date:
- Size: 56.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
30e0e5a7fd06252a6091db81d4da2a940b361b8d2c59aef1927a3c7f1fdc9158
|
|
| MD5 |
29e187996b889f0698dd33c4f7909938
|
|
| BLAKE2b-256 |
b4afbaac52a38a56da1dae8af7dfe8860398e3679c849b8ee974ea950e3007ee
|