Skip to content

Commit 8da3b06

Browse files
committed
feat: automatic field boundary detection (v0.4.0)
- FTW deep learning model for field boundary detection from Sentinel-2 imagery - Dedicated ML processor Docker service (PyTorch + torchgeo + FTW weights) - Detection API: trigger, list, accept, discard with org-scoped access - Full-page detection UI (/farms/[id]/detect) with 3-phase workflow - Interactive polygon drawing via MapLibre GL Draw - Boundary review with confidence scores, bulk actions, zoom-to-select - Boundary editing before accepting as field - 7-step job progress tracking - Alembic migrations for detected_boundaries, nullable job field_id - i18n translations (en + es) for all detection strings - Updated CHANGELOG, ROADMAP, README
1 parent 2060134 commit 8da3b06

27 files changed

Lines changed: 4835 additions & 26 deletions

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,25 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
66

77
## [Unreleased]
88

9+
---
10+
11+
## [0.4.0] - 2026-03-17
12+
913
### Added
14+
- **Automatic field boundary detection** from Sentinel-2 satellite imagery using the FTW (Fields of The World) deep learning model.
15+
- Dedicated ML processor Docker service (`ml-processor`) with PyTorch, torchgeo, and FTW model weights.
16+
- Detection API endpoints: trigger detection, list/accept/discard detected boundaries.
17+
- Full-page detection UI (`/farms/[id]/detect`) with 3-phase workflow: draw area → detecting → review results.
18+
- Interactive polygon drawing via MapLibre GL Draw (pan, zoom, draw, move, edit vertices, delete).
19+
- Viewport preservation across detection phase transitions (draw → detecting → review).
20+
- Bbox overlay shown during detection processing phase.
21+
- Boundary review sidebar with confidence scores, area display, and accept/discard/edit actions.
22+
- Bulk accept-all and discard-all for detected boundaries.
23+
- Zoom-to-boundary on selection from sidebar or map click.
24+
- Boundary geometry editing with DrawMap before accepting as a field.
25+
- 7-step job progress tracking for detection pipeline (validate → STAC search → download → prepare → inference → polygonize → store).
26+
- Alembic migrations for detected boundaries table, nullable job field_id, and updated_at column.
27+
- English and Spanish translations for all detection UI strings.
1028
- Changelog page visible in-app under sidebar navigation.
1129
- SAVI L factor displayed on layer cards in field detail sidebar.
1230

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Open source self-hostable and reproducible Crop Intelligence Platform
3737
## Why OpenFarm
3838
- Self-hostable stack with clear service boundaries (Next.js ↔ FastAPI ↔ TiTiler ↔ MinIO ↔ PostGIS)
3939
- Multi-index vegetation monitoring — NDVI, EVI, SAVI (configurable L factor), and NDWI from Sentinel-2 imagery
40+
- ML-powered automatic field boundary detection (FTW model) with interactive review workflow
4041
- Reproducible pipeline with provenance (Element84 STAC → COG → TiTiler tiles)
4142
- Tenant isolation via `X-Org-Id` + JWT; RBAC (`owner`/`admin`/`member`/`viewer`)
4243
- MapLibre + PMTiles (no Mapbox token needed), ECharts for time series
@@ -144,6 +145,7 @@ ruff format --check .
144145
- **Orgs & RBAC**: owner/admin/member/viewer with audit logging
145146
- **Farms & Fields**: draw/upload GeoJSON/KML, area calc, soft delete
146147
- **Vegetation Monitoring**: NDVI, EVI, SAVI (configurable L factor), NDWI — STAC search → COG → TiTiler tiles → time-series stats
148+
- **Boundary Detection**: automatic field boundary detection from Sentinel-2 imagery using FTW deep learning model — draw area, review results, accept as fields
147149
- **Per-Index Alerts**: configurable threshold and drop-percentage rules for each index
148150
- **Scouting**: geotagged observations with optional photo upload
149151
- **Sharing**: read-only field health reports via share links with multi-index toggle

ROADMAP.md

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ This document outlines where OpenFarm is today and where it's headed. If you'd l
88

99
## Current Status
1010

11-
OpenFarm **Phase 2 (Multi-Index) is complete**. The platform delivers end-to-end satellite-powered crop intelligence with four vegetation indices (NDVI, EVI, SAVI, NDWI), auth, org management, farm/field CRUD, configurable monitoring pipelines, per-index alerts, scouting observations, shareable field health reports, and production-grade security hardening — all functional and deployed. The focus now shifts to testing, documentation, and expanding the platform with new data sources and intelligence capabilities. See [Future Ideas](#future-ideas-post-mvp) for what's next.
11+
OpenFarm **Phase 3 (Boundary Detection) is complete**. The platform delivers end-to-end satellite-powered crop intelligence with four vegetation indices (NDVI, EVI, SAVI, NDWI), ML-powered automatic field boundary detection, auth, org management, farm/field CRUD, configurable monitoring pipelines, per-index alerts, scouting observations, shareable field health reports, and production-grade security hardening — all functional and deployed. The focus now shifts to testing, documentation, and expanding the platform with new data sources and intelligence capabilities. See [Future Ideas](#future-ideas-post-mvp) for what's next.
1212

1313
---
1414

@@ -98,6 +98,20 @@ OpenFarm **Phase 2 (Multi-Index) is complete**. The platform delivers end-to-end
9898
- [x] SAVI L factor stored in layer `params_json` and displayed in UI
9999
- [x] In-app changelog page with parsed Keep a Changelog rendering
100100

101+
## Milestone 7 — Automatic Boundary Detection ✅
102+
103+
- [x] FTW (Fields of The World) deep learning model integration for field boundary detection
104+
- [x] Dedicated ML processor Docker service with PyTorch, torchgeo, and model weights
105+
- [x] Detection API — trigger, list, accept, discard, with org-scoped access control
106+
- [x] Full-page detection UI (`/farms/[id]/detect`) with draw → detecting → review workflow
107+
- [x] Interactive polygon drawing with MapLibre GL Draw (draw, move, edit vertices, delete)
108+
- [x] Viewport preservation across phase transitions
109+
- [x] Boundary review with confidence scores, bulk accept/discard, zoom-to-boundary
110+
- [x] Boundary geometry editing before accepting as a field
111+
- [x] 7-step progress tracking (validate → STAC search → download → prepare → inference → polygonize → store)
112+
- [x] Alembic migrations for detected boundaries, nullable job field_id, updated_at
113+
- [x] i18n translations (English + Spanish) for all detection UI
114+
101115
---
102116

103117
## Future Ideas (Post-MVP)
@@ -107,14 +121,31 @@ These are under consideration but not yet committed. Grouped by theme and roughl
107121
### Platform Foundations
108122
- **Email/Microsoft & Enterprise SSO** — support email/password, Microsoft OAuth, and SAML/OIDC for enterprise identity providers
109123
- **Direct API integration** — stable, versioned public API with API keys for integrating OpenFarm into existing farm management software
110-
- **Boundary detection** — automatic field boundary detection from satellite imagery
111-
- **Crop detection and classification** — ML-based crop type identification from spectral data
112124
- **Multi-satellite support** — Landsat, Planet (currently Sentinel-2 only)
125+
- **Higher-frequency monitoring** — support for daily revisit satellites (e.g., PlanetScope) for near real-time crop monitoring
126+
- **Higher-res imagery** — support for sub-meter commercial imagery for detailed crop monitoring
127+
- **Custom index builder** — UI for users to define custom indices from available bands with formula editor and visualization
128+
- **Data export** — export field data, stats, and reports in CSV, GeoJSON, PDF formats
129+
- **User roles and permissions** — more granular permissions (e.g., field-level access, read-only API keys) and user groups
130+
113131

114132
### Agricultural Intelligence
133+
- **Weather data integration** — overlay forecasts and historical weather on field maps and incorporate into alert rules
134+
- **Crop detection and classification** — ML-based crop type identification from spectral data
135+
- **tree detection and classification** — ML-based tree crop identification and health monitoring
136+
- **Phenology tracking** — track crop growth stages and phenological events from satellite data
137+
- **tree canopy analysis** — canopy cover, leaf area index, and tree height estimation from high-res imagery
138+
- **drought monitoring** — integrate drought indices and soil moisture data for water stress assessment
139+
- **water stress monitoring** — integrate NDWI and soil moisture data for irrigation management
140+
- **soil moisture estimation** — integrate soil moisture data from remote sensing and in-situ sensors
115141
- **Disease/pest risk signals** — risk scoring framework combining vegetation anomalies, weather, and regional pest data
142+
- **nutrient deficiency detection** — identify spectral signatures of common nutrient deficiencies for early intervention
143+
- **Fertilizer and irrigation recommendations** — actionable insights based on crop health trends, weather forecasts, and agronomic models
144+
- **Anomaly detection** — unsupervised ML to identify unusual patterns in field health data that may indicate emerging issues
145+
- **Historical data backfill** — backfill historical vegetation index data for existing fields to enable trend analysis from day one
116146
- **Yield analysis and forecasting** — predict yield from historical NDVI trends, weather, and field data
117-
- **Weather data integration** — overlay forecasts and historical weather on field maps
147+
- **Harvest timing recommendations** — optimal harvest windows based on crop maturity models and vegetation indices
148+
- **Climate impact modeling** — estimate carbon sequestration, emissions, and climate impact of farming practices using field data and agronomic models
118149
- **Carbon/sustainability reporting** — track and report carbon sequestration, emissions, and sustainability metrics
119150

120151
### Analytics & Workflows
@@ -125,11 +156,13 @@ These are under consideration but not yet committed. Grouped by theme and roughl
125156
- **Webhook/notification system** — email, Slack, or SMS on alerts
126157

127158
### Ecosystem & Integrations
128-
- **OpenFarm MCP server** — Model Context Protocol server for AI agent integration
159+
- **AI agent integration** — connect to LLMs for natural language insights, recommendations, and conversational interfaces
160+
- **Model Context Protocol (MCP) server** — standardized interface for AI agents to query field data and trigger analysis
129161
- **Device/Sensor plugin framework** — connect soil sensors, weather stations, and IoT devices
130162
- **Machinery telemetry integration** — ingest GPS tracks and operational data from farm equipment
131163
- **Supply chain / traceability integrations** — link field data to downstream logistics and compliance systems
132164
- **Plugin system** — extensible processing pipelines for custom analysis
165+
- **Community data sharing** — opt-in anonymized data sharing for regional insights and benchmarking
133166

134167
### Enterprise & Scale
135168
- **Enterprise admin controls** — SSO enforcement, audit policies, usage quotas, multi-tenant admin

apps/web/messages/en.json

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,5 +409,50 @@
409409
"title": "Changelog",
410410
"description": "Latest updates and improvements to OpenFarm",
411411
"unreleased": "Unreleased"
412+
},
413+
"detection": {
414+
"title": "Detect Boundaries",
415+
"description": "Draw a rectangle on the map to detect field boundaries using satellite imagery.",
416+
"drawBbox": "Draw area on map",
417+
"drawBboxHint": "Click to place points, double-click to finish. You can move or edit the shape after drawing.",
418+
"bboxArea": "Area: {area} km²",
419+
"bboxTooLarge": "Area exceeds 50 km² limit",
420+
"bboxTooSmall": "Area too small — draw at least 2 km²",
421+
"startDetection": "Start Detection",
422+
"detecting": "Detecting...",
423+
"farmLabel": "Associate with farm",
424+
"farmPlaceholder": "Select a farm",
425+
"windowA": "Window A (planting)",
426+
"windowB": "Window B (harvest)",
427+
"optional": "Optional",
428+
"jobCreated": "Detection job started",
429+
"jobFailed": "Detection failed",
430+
"jobComplete": "Detection complete — {count} boundaries found",
431+
"noBoundaries": "No boundaries detected in this area",
432+
"pending": "Pending",
433+
"accepted": "Accepted",
434+
"discarded": "Discarded",
435+
"confidence": "Confidence: {value}%",
436+
"areaHa": "{area} ha",
437+
"detectedOn": "Detected {date}",
438+
"accept": "Accept",
439+
"acceptAs": "Accept as Field",
440+
"discard": "Discard",
441+
"edit": "Edit & Accept",
442+
"fieldName": "Field name",
443+
"fieldNamePlaceholder": "Enter field name",
444+
"acceptSuccess": "Field created ({area} ha)",
445+
"discardSuccess": "Boundary discarded",
446+
"acceptAll": "Accept All",
447+
"discardAll": "Discard All",
448+
"progress": {
449+
"validate": "Validating area",
450+
"stac_search": "Searching satellite imagery",
451+
"download_bands": "Downloading bands",
452+
"prepare_input": "Preparing input",
453+
"inference": "Running detection model",
454+
"polygonize": "Converting to polygons",
455+
"store_results": "Storing results"
456+
}
412457
}
413458
}

apps/web/messages/es.json

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,5 +409,50 @@
409409
"title": "Registro de cambios",
410410
"description": "Últimas actualizaciones y mejoras de OpenFarm",
411411
"unreleased": "Próximamente"
412+
},
413+
"detection": {
414+
"title": "Detectar Límites",
415+
"description": "Dibuja un rectángulo en el mapa para detectar los límites de campos usando imágenes satelitales.",
416+
"drawBbox": "Dibujar área en el mapa",
417+
"drawBboxHint": "Haz clic para colocar puntos, doble clic para terminar. Puedes mover o editar la forma después de dibujar.",
418+
"bboxArea": "Área: {area} km²",
419+
"bboxTooLarge": "El área excede el límite de 50 km²",
420+
"bboxTooSmall": "Área muy pequeña — dibuja al menos 2 km²",
421+
"startDetection": "Iniciar Detección",
422+
"detecting": "Detectando...",
423+
"farmLabel": "Asociar con finca",
424+
"farmPlaceholder": "Seleccionar una finca",
425+
"windowA": "Ventana A (siembra)",
426+
"windowB": "Ventana B (cosecha)",
427+
"optional": "Opcional",
428+
"jobCreated": "Trabajo de detección iniciado",
429+
"jobFailed": "La detección falló",
430+
"jobComplete": "Detección completa — {count} límites encontrados",
431+
"noBoundaries": "No se detectaron límites en esta área",
432+
"pending": "Pendiente",
433+
"accepted": "Aceptado",
434+
"discarded": "Descartado",
435+
"confidence": "Confianza: {value}%",
436+
"areaHa": "{area} ha",
437+
"detectedOn": "Detectado {date}",
438+
"accept": "Aceptar",
439+
"acceptAs": "Aceptar como Campo",
440+
"discard": "Descartar",
441+
"edit": "Editar y Aceptar",
442+
"fieldName": "Nombre del campo",
443+
"fieldNamePlaceholder": "Ingresa el nombre del campo",
444+
"acceptSuccess": "Campo creado ({area} ha)",
445+
"discardSuccess": "Límite descartado",
446+
"acceptAll": "Aceptar Todos",
447+
"discardAll": "Descartar Todos",
448+
"progress": {
449+
"validate": "Validando área",
450+
"stac_search": "Buscando imágenes satelitales",
451+
"download_bands": "Descargando bandas",
452+
"prepare_input": "Preparando entrada",
453+
"inference": "Ejecutando modelo de detección",
454+
"polygonize": "Convirtiendo a polígonos",
455+
"store_results": "Almacenando resultados"
456+
}
412457
}
413458
}

0 commit comments

Comments
 (0)