document selection-bounded change detection and export provenance
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+44
-2
@@ -1080,6 +1080,21 @@ Return vector stats (feature counts and geometry summary).
|
|||||||
|
|
||||||
Return vector bounds and feature count.
|
Return vector bounds and feature count.
|
||||||
|
|
||||||
|
|
||||||
|
### Export provenance
|
||||||
|
|
||||||
|
Every exported GeoJSON carries a `geointel_provenance` foreign member on the
|
||||||
|
FeatureCollection. RFC 7946 requires parsers to ignore members they do not
|
||||||
|
know, so QGIS and ogr2ogr read the file normally.
|
||||||
|
|
||||||
|
It names the source, the dataset and its `source_version`/`observed_at`, the
|
||||||
|
selection the export was taken from, and — most importantly — whether the file
|
||||||
|
is complete. A capped selection export previously recorded `truncated` on the
|
||||||
|
export *record* only: the downloaded file looked whole, and an operator opening
|
||||||
|
250 of 1.400 buildings in QGIS had nothing to tell them so. Completeness is
|
||||||
|
derived from the counts as well as the flag, so a caller that forgets to pass
|
||||||
|
it cannot produce a file that claims to hold everything.
|
||||||
|
|
||||||
### POST `/api/v1/projects/{project_id}/datasets/{dataset_id}/vector/select`
|
### POST `/api/v1/projects/{project_id}/datasets/{dataset_id}/vector/select`
|
||||||
|
|
||||||
Selection metrics describe two different populations and now say so.
|
Selection metrics describe two different populations and now say so.
|
||||||
@@ -2015,7 +2030,7 @@ If the segmentation run has no persisted geometries, the endpoint returns `SEGME
|
|||||||
### POST `/api/v1/analysis/change-detection`
|
### POST `/api/v1/analysis/change-detection`
|
||||||
|
|
||||||
Compares two persisted vector datasets in the same project and returns a synchronous
|
Compares two persisted vector datasets in the same project and returns a synchronous
|
||||||
job envelope. This is a lightweight V1 foundation for added/removed object review,
|
job envelope. This is a lightweight V1 foundation for object-level change review,
|
||||||
not a temporal run-history engine.
|
not a temporal run-history engine.
|
||||||
|
|
||||||
Request:
|
Request:
|
||||||
@@ -2025,10 +2040,37 @@ Request:
|
|||||||
"source_dataset_id": "uuid",
|
"source_dataset_id": "uuid",
|
||||||
"target_dataset_id": "uuid",
|
"target_dataset_id": "uuid",
|
||||||
"iou_threshold": 0.8,
|
"iou_threshold": 0.8,
|
||||||
"include_unchanged": true
|
"modified_threshold": 0.3,
|
||||||
|
"include_unchanged": true,
|
||||||
|
"bbox": {"min_x": 5.0, "min_y": 51.1, "max_x": 5.2, "max_y": 51.3, "crs": "EPSG:4326"},
|
||||||
|
"area_id": "uuid",
|
||||||
|
"preview_limit": 2000
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`bbox` and `area_id` bound the comparison to the operator's selection, resolved
|
||||||
|
the same way every other analysis resolves it: the drawn rectangle intersected
|
||||||
|
with the named work area. Both populations are loaded through an indexed
|
||||||
|
`ST_Intersects` predicate rather than being read into Python in full. Without a
|
||||||
|
selection the comparison still covers both datasets entire, which is rarely the
|
||||||
|
question and — with `include_unchanged` true — previously returned a
|
||||||
|
FeatureCollection holding both datasets.
|
||||||
|
|
||||||
|
Features are **not** clipped to the selection. A change class describes a whole
|
||||||
|
object, so comparing a clipped earlier footprint against an unclipped later one
|
||||||
|
would manufacture "modified" along the selection edge. Features the edge crosses
|
||||||
|
are compared in full and counted in a warning instead.
|
||||||
|
|
||||||
|
`modified_threshold` separates a redrawn footprint from two distinct objects.
|
||||||
|
Between it and `iou_threshold` the change class is `modified`; below it the
|
||||||
|
source is `removed` and the target `added`. Without that class an extended
|
||||||
|
building appeared as one removal plus one addition, hiding the category the
|
||||||
|
analysis exists to show and inflating both counts.
|
||||||
|
|
||||||
|
`preview_limit` caps the returned geometry — modified, added, removed and only
|
||||||
|
then unchanged — while every count still describes the whole selection.
|
||||||
|
`preview_truncated` says whether the cap applied.
|
||||||
|
|
||||||
Response is a canonical API envelope containing a `JobRead` payload. On success,
|
Response is a canonical API envelope containing a `JobRead` payload. On success,
|
||||||
`result_json` contains:
|
`result_json` contains:
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,15 @@ runtime source of truth.
|
|||||||
- Flood-hazard percentages are shares of the modelled area. Where the VMM model
|
- Flood-hazard percentages are shares of the modelled area. Where the VMM model
|
||||||
does not cover the selection, that is reported as missing coverage and never
|
does not cover the selection, that is reported as missing coverage and never
|
||||||
as an absence of risk.
|
as an absence of risk.
|
||||||
|
- Change detection compares whole objects and does not clip them to the
|
||||||
|
selection, so a footprint crossing the selection edge is compared in full.
|
||||||
|
That is deliberate: clipping one snapshot and not the other would report the
|
||||||
|
selection edge itself as a change. The count of such objects is reported.
|
||||||
|
- The change-detection GeoJSON is capped by `preview_limit` (changes first).
|
||||||
|
The counts always describe the whole selection; the map does not.
|
||||||
|
- An export states its own completeness in `geointel_provenance`. A capped
|
||||||
|
export is still a valid, usable file — it simply no longer implies it holds
|
||||||
|
everything the selection contains.
|
||||||
|
|
||||||
## Historical analysis
|
## Historical analysis
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user