The Problem
Applying AI to geospatial data typically means stitching together model training, raster/vector processing, and visualization across incompatible libraries. GeoAI provides a unified Python API for search/download, dataset preparation, training, inference, and interactive mapping, plus a QGIS plugin for non-programmatic workflows.
What This Does
The core geoai/ package (62 files) exposes high-level modules like auto.py (model loading/inference), train.py (training pipelines), canopy.py (canopy height models), extract.py (dataset preparation), and cli.py (command-line interface). It supports GeoTIFF, JPEG2000, GeoJSON, Shapefile, and GeoPackage formats, with automatic GPU device management.
The repo also contains qgis_plugin/ (31 code files) for desktop integration, agent-harness/ (21 code files) providing a CLI wrapper for AI agents, and geoai-mcp-server/ (15 code files) exposing Model Context Protocol endpoints. Documentation is extensive: 114 Jupyter notebooks and 57 Markdown files.
How It Is Wired
Execution starts at geoai/cli.py:143 (run), reaching 140 functions. The CLI dispatches to geoai/__init__.py (33 modules depend on it, highest blast radius) and geoai/utils/__init__.py (21 dependents, part of a circular import cycle). The geoai/train.py file (4703 lines) is the largest, handling training workflows and model inference.
The geoai-mcp-server/src/geoai_mcp_server/server.py exposes three main endpoints: classify_land_cover (line 519), auto_segment_image (line 281), and detect_and_classify_features (line 400). These reach 67, 50, and 32 functions respectively, with filesystem effects via rasterio.open and full_path.parent.mkdir.
Key functions with widest reach: max (119 callers), min (88), normalize_radiometric (39), load_image (32). The geoai/auto.py module makes outbound network calls (model downloads) and runs inference. geoai/pipeline.py performs cryptographic operations (likely for secure model loading).
The call graph shows 3406 internal edges. The qgis_plugin/geoai/dialogs/deepforest_panel.py is the most-connected file (66 functions, called from 59 files) despite being UI code—a surprising hub that creates coupling between the plugin and core.
How To Use It
Setup: Install via pip or conda (README shows geoai-py on PyPI and conda-forge). No lockfile exists, so pin versions manually. Dockerfile uses quay.io/jupyter/base-notebook:latest (mutable tag).
pip install geoai-py
# or
conda install -c conda-forge geoai
Configuration: No required environment variables found. The MCP server has .env.example in geoai-mcp-server/ for optional configuration.
Running it: Use the CLI or import the library:
geoai download --help
geoai pipeline --config config.yaml
For the MCP server: python -m geoai_mcp_server from geoai-mcp-server/src/.
Real-World Use
Building footprint extraction from satellite imagery:
from geoai import load_image, AutoGeoImageProcessor
from geoai.auto import from_pretrained
image = load_image("naip.tif")
model = from_pretrained("opengeos/building-detection")
processor = AutoGeoImageProcessor.from_pretrained("opengeos/building-detection")
inputs = processor(image, return_tensors="pt")
outputs = model(**inputs)
Code Health & Issues
Static analysis found 166 findings (50 high, 116 medium) across 7 kinds:
- High - Deep nesting x25:
geoai/train.py,qgis_plugin/geoai/core/venv_manager.pyhave max indentation depth 6. Fix with early returns. - High - Import cycles x6:
geoai/utils/__init__.py,geoai/train.pyparticipate in circular imports. Breaking these requires extracting shared types. - High - Hub modules x2:
geoai/__init__.py(33 dependents),geoai/utils/__init__.py(21) are high-blast-radius. - High - Oversized files x13:
geoai/train.py(4703 lines),venv_manager.py,raster.py. - Medium - Broad exceptions x11:
train.py,venv_manager.pyswallow errors indiscriminately. - Medium - File handles x2:
raster.py,landcover_utils.pyuseopen()without context manager. - High - Duplication: 1749 repeated 6-line blocks across 87 files.
Security audit: 1 high (unpinned GitHub Actions), 4 medium (no least-privilege token, mutable Docker base, no dependency scan, persist-credentials enabled), 1 low (no job timeouts).
The Bottom Line
GeoAI is a substantial, well-documented library (416 files, 71 tests, CI on 3 OSes) that genuinely simplifies geospatial AI workflows. The main risks are architectural: hub modules and circular imports make changes ripple widely, and the 4703-line train.py is a maintenance liability. Production users should pin dependencies and container images, and expect to refactor if they need to modify core training logic.