Open source · Apache-2.0 · Sentinel-1 + Sentinel-2
From observation to decision.
An open, local-first engine for crop mapping and parcel verification. GeoCrop turns Copernicus time series into crop maps with probabilities, and those into parcel decisions that state their evidence.
DecideAccept or review per parcel, with reason codes and markers
ShareCOG, GeoPackage, GeoParquet, STAC and run manifests
Web workspace
Start with the map. Everything else is a keystroke away.
A local workspace served by the engine itself. Choose an area and a period and look at real Sentinel-2 imagery, then go as deep as the command line allows.
A guided first analysis
The New analysis sheet takes an area by coordinates or drawn on the map, a period preset, and shows the exact command before it runs quicklook: monthly cloud-screened composites from windowed COG reads, as true colour, false colour or NDVI.
A terminal that knows the engine
Live syntax colouring and completion of commands, flags, choices and workspace paths, with ghost-text hints, history search, streamed job output and CtrlC to cancel.
Every command, searchable
Press ⌘K or CtrlK. Forms are generated from the real CLI parser, grouped, with a live command-line preview.
Light, dark and pocket-sized
Follows the system appearance or your choice, respects reduced motion, and becomes a phone layout with a tab bar.
Actual captures of the running workspace; provenance and checksums in screenshots.json.
Validation rigour
Accuracy you can defend.
Neighbouring pixels are not independent. GeoCrop evaluates with that in mind by default, and every number traces back to the split that produced it.
Spatial-block CV
Class-stratified spatial blocks, optional buffers that drop training polygons near held-out pixels, leakage assertions and nested tuning.
Locked holdout
Whole spatial blocks set aside before model selection and scored once. In holdout calibration mode the predictor stays frozen.
Transfer: LORO and LOYO
Leave-one-region-out, leave-one-year-out and region-year CV report per-group metrics and the gap to spatial-block CV.
Conformal prediction sets
Temperature-scaled probabilities and class-conditional conformal sets: an ambiguous parcel says which crops it could be.
Area of Applicability
Flags predictions in feature space the model never saw. Parcels below the AOA threshold go to review instead of being accepted.
Independent evaluation
Field points near training polygons are excluded automatically; bootstrap CIs, area-adjusted estimates and calibration error.
Public benchmark · protocol v1
EuroCrops Slovenia 2021, Pomurje
Seven crop classes, Sentinel-2 L2A, a frozen protocol file and one command to reproduce. Parcel-level scores on a spatial-block holdout with 95 % block-bootstrap intervals.
A public transfer task on farmers’ declarations, not field-verified labels, and not Republic of Srpska data. Valid for this protocol only; not evidence of accuracy elsewhere.
Model
OA %
Macro‑F1 %
Coverage % conformal, target 90
rf
86.9 [81.1, 92.2]
85.5 [78.2, 91.7]
91.7
extra_trees
88.1 [82.8, 93.1]
86.3 [78.6, 92.6]
92.9
hist_gb
87.8 [83.0, 92.5]
86.1 [79.4, 91.6]
89.1
catboost
88.5 [83.5, 93.2]
87.2 [80.9, 92.7]
92.0
EuroCrops labels: Schneider et al. (2023), CC-BY-SA-4.0. Full report in docs/benchmarks.
Parcel decisions
Every parcel says why.
Pixel probabilities are aggregated inside an interior buffer, or parcels are classified directly from their signatures. Each parcel is accepted or sent to review with stable reason codes.
Sentinel-2 and Sentinel-1 markers. Harvest, told apart from senescence when radar is available; tillage; dated mowing events; within-parcel homogeneity. Each with confidence and data-sufficiency fields.
A traffic light for Checks by Monitoring. Optional rules can only escalate a colour, and absence rules fire only on confident, sufficient data.
A review aid, not a verdict. A reason describes the configured rule, not a verified crop error or a legal finding.
A selection of the documented codes (parcels, markers). Semicolon-separated and not mutually exclusive.
Models and pretrained adapters
Bring in the state of the art. Keep the same yardstick.
Every model and feature source runs behind the same spatial CV, ablation and prediction, so a new idea is compared on identical folds.
Foundation-model embeddings
An optional feature group emb from Presto, computed locally on the CPU from GeoCrop’s own composites, or from AlphaEarth and TESSERA annual embeddings. Ablation adds handcrafted, embeddings-only and combined rows.
Fields of The World boundaries
ftw-boundaries runs pretrained field-boundary models on two-window composites: CC-BY checkpoints by default, SHA-256-pinned download, watershed parcels, scored like OBIA and the U-Net.
Active learning for field campaigns
Pick a diverse, well-spaced batch among the most uncertain parcels, grouped into trips. Ingest labels with per-round provenance, and simulate label budgets against random sampling.
Classifiers and temporal networks
Random Forest, ExtraTrees, HistGradientBoosting, LightGBM, CatBoost, TempCNN and L-TAE, plus parcel-level classification on signatures, on one benchmark harness.
Heavy dependencies and checkpoints are optional and fetched at runtime; nothing is bundled. Licences and attribution: embeddings, field boundaries, active learning.
Built for real data
Know before you run. Prove it after.
Preflight
Ready, warn or blocked
Scenes per window and orbit, clear-sky coverage, class support under the spatial blocks, CRS overlap, and disk, RAM and runtime estimates before a long run starts.
Acceptance · Semberija 2023
21 of 21 checks
One versioned run of the whole chain on real Sentinel-2 and Sentinel-1 data over about 4 km²: radiometry, S1/S2 co-registration, reproducibility, COG, STAC and GeoParquet validity.
Reliability gate
Killed, then recovered
A real run is killed inside features, train and predict and must recover to the uninterrupted result. Partial outputs are quarantined; a disk guard stops before writing.
Report: acceptance-0.10-dev-2026-10-26. The acceptance checks cover the technical integrity of the chain on that area, not crop-map accuracy.
Open by architecture
One engine. Every way you work.
A layered core — local logic, adapters for networks and external programs, application, interfaces — enforced by architecture tests. Extend it through plugin registries for classifiers, indices, segmenters, exporters and validators.
The browser, on your machine
geocrop serve binds to loopback and requires a token on every API request. Jobs are queued, logged, cancellable and their outputs downloadable. Sentinel-2 cloudless and OpenStreetMap basemaps sit under the imagery.
A standalone plugin adds run-command, demo and load-job algorithms to the Processing Toolbox. It talks to the engine API, streams logs, reconnects to jobs and loads results as layers. QGIS keeps its own Python.
Apache-2.0 (licence, notice). Targets QGIS 3.28–3.x; tested in 3.40.6.
Notebooks and scripts
EngineClient submits the same commands, polls jobs, reads logs and downloads artifacts, without putting the token in the notebook. It uses /api/v1 and falls back on older servers.
# GEOCROP_WEB_TOKEN comes from the environment.from geocrop.client import EngineClient
with EngineClient() as engine:
job = engine.submit(["indices", "--format", "json"])
engine.wait(job["id"], timeout=60)
print(engine.logs(job["id"])["text"])
A versioned REST contract
Every endpoint is served under /api/v1, the documented stable contract with an OpenAPI schema. Requests need a Bearer token; request bodies and job arguments are size-limited.
GET /api/v1/health
GET /api/v1/commands
POST /api/v1/jobs {"argv": ["indices", "--format", "json"]}GET /api/v1/jobs/{id}/logs
POST /api/v1/jobs/{id}/cancel
GET /api/v1/jobs/{id}/artifacts
COG
GeoPackage
GeoParquet
STAC
EuroCrops HCAT
openEO, optional
Docker
Run manifests
Get started
A first run in seconds.
Install, run the synthetic demo, then open the workspace. Python 3.10–3.12.
Terminal
git clone https://github.com/ZeljkoDzafic/geocrop-engine.git
cd geocrop-engine
python3 -m venv .venv && source .venv/bin/activate
python -m pip install -e '.[all,web]'
geocrop demo --root outputs/my-first-demo --quick
# Workspace: first set GEOCROP_WEB_TOKEN (32+ random characters)
geocrop serve --workspace . --port 8765
PowerShell
git clone https://github.com/ZeljkoDzafic/geocrop-engine.git
cd geocrop-engine
py -3.12 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e ".[all,web]"
.\.venv\Scripts\geocrop.exe demo --root outputs\my-first-demo --quick
# Workspace: first set $env:GEOCROP_WEB_TOKEN (32+ random characters)
.\.venv\Scripts\geocrop.exe serve --workspace . --port 8765