-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Description
Blocks https://github.com/DataIntegrationGroup/OcotilloUI/issues/161
Summary
Add OGC API - Features compliant endpoints to enable QGIS desktop integration for geospatial visualization, subsetting, and editing—without requiring direct database access.
Problem
The Starlette Admin UI provides CRUD functionality but lacks map-based visualization. Staff need to:
- View sample locations on a map
- Perform spatial queries and subsetting
- Export data to GIS-compatible formats
Constraints:
- Building custom map fields in Starlette Admin would take 3-5 days
- Direct PostGIS access bypasses business logic and requires DB credential distribution
- Maps and geospatial visualization are fundamental requirements (not deferrable)
Proposed Solution
Implement OGC API - Features endpoints within FastAPI. This is the modern, REST-based successor to WFS and is natively supported by QGIS 3.28+.
Architecture
┌─────────────────────────────────────────────────────┐
│ Staff Workflows │
├─────────────────┬─────────────────┬─────────────────┤
│ Data Entry │ Map/GIS Work │ API Consumers │
│ │ │ │
│ Starlette │ QGIS Desktop │ REST API │
│ Admin │ ───────────────│ (existing) │
│ │ │ │ │
└────────┬────────┴────────┼────────┴────────┬────────┘
│ │ │
│ OGC API - Features │
│ /ogc/collections │
│ │ │
└─────────────────┼─────────────────┘
▼
┌───────────────┐
│ PostgreSQL │
│ + PostGIS │
└───────────────┘
Why OGC API - Features (vs alternatives)
| Option | Pros | Cons |
|---|---|---|
| OGC API - Features ✅ | Native QGIS support, REST-based, modern standard | Some implementation effort |
| Direct PostGIS | Zero dev effort | Bypasses auth/business logic, credential management |
| WFS 1.x/2.0 | Wide support | XML-heavy, complex to implement |
| GeoJSON endpoint | Simple | Read-only, no standard query params |
| Custom QGIS plugin | Full control | Maintenance burden, non-standard |
Implementation Plan
Phase 1: Core Endpoints (Read-Only)
# api/ogc.py
GET /ogc # Landing page
GET /ogc/conformance # Conformance declaration
GET /ogc/collections # List available collections
GET /ogc/collections/{id} # Collection metadata
GET /ogc/collections/{id}/items # Get features (GeoJSON)
GET /ogc/collections/{id}/items/{fid} # Get single featureQuery Parameters (OGC-compliant):
bbox- Bounding box filterdatetime- Temporal filterlimit/offset- Paginationproperties- Property filter (CQL)
Phase 2: Write Support (OGC API - Features Part 4)
POST /ogc/collections/{id}/items # Create feature
PUT /ogc/collections/{id}/items/{fid} # Replace feature
PATCH /ogc/collections/{id}/items/{fid} # Update feature
DELETE /ogc/collections/{id}/items/{fid} # Delete featureCollections to Expose
| Collection | Model | Priority |
|---|---|---|
locations |
Location | P0 |
wells |
Thing (type=well) | P0 |
springs |
Thing (type=spring) | P1 |
sensors |
Sensor | P2 |
observations |
Observation | P2 |
File Structure
api/
├── ogc/
│ ├── __init__.py
│ ├── router.py # Main OGC router
│ ├── collections.py # Collection definitions
│ ├── features.py # Feature CRUD operations
│ ├── conformance.py # OGC conformance classes
│ └── schemas.py # GeoJSON response schemas
QGIS Usage
Once implemented, staff connect via:
- Layer → Add Layer → Add WFS / OGC API - Features Layer
- URL:
https://api.example.com/ogc - Authentication: Bearer token (same as REST API)
Acceptance Criteria
-
GET /ogc/collectionsreturns list of available collections -
GET /ogc/collections/locations/itemsreturns valid GeoJSON FeatureCollection -
bboxparameter filters features spatially -
limit/offsetpagination works correctly - QGIS can connect and display locations layer
- Authentication required (reuses existing auth)
- Phase 2: Write operations respect RBAC permissions
References
- OGC API - Features Spec
- OGC API - Features Part 4 (Transactions)
- QGIS OGC API Support
- pygeoapi (reference implementation)
Estimate
- Phase 1 (Read-only): 2-3 days
- Phase 2 (Write support): 2-3 days
- Total: 4-6 days
This approach provides full GIS capabilities to staff via QGIS while keeping all data access through the authenticated API layer.
Metadata
Metadata
Assignees
Labels
No labels