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.py have max indentation depth 6. Fix with early returns.
  • High - Import cycles x6: geoai/utils/__init__.py, geoai/train.py participate 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.py swallow errors indiscriminately.
  • Medium - File handles x2: raster.py, landcover_utils.py use open() 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.