fix: clarify active AI result context
GeoIntel CI / docs-smoke (push) Canceled after 0s
GeoIntel CI / contract-smoke (push) Canceled after 0s

This commit is contained in:
Codex
2026-07-15 00:44:59 +02:00
parent 0cad8fdf76
commit 845c4696e7
6 changed files with 30 additions and 3 deletions
+1
View File
@@ -18,6 +18,7 @@
- Detection QA now applies the persisted tile coverage through the existing GiST-indexed PostGIS geometry column before loading reference rows, while retaining the complete reference population in audit counts. - Detection QA now applies the persisted tile coverage through the existing GiST-indexed PostGIS geometry column before loading reference rows, while retaining the complete reference population in audit counts.
- The unchanged exact IoU matcher now uses a Shapely spatial index to avoid testing geometries whose envelopes cannot intersect. - The unchanged exact IoU matcher now uses a Shapely spatial index to avoid testing geometries whose envelopes cannot intersect.
- Clarified the primary map source and legend whenever an AI result is active so detections are never presented as the underlying official GRB source. - Clarified the primary map source and legend whenever an AI result is active so detections are never presented as the underlying official GRB source.
- Made the fixed workbench context bar follow the active AI layer and exposed the IoU match threshold beside every detection-QA score.
## Sprint 194 Regional official time-series synchronization (2026-07-14) ## Sprint 194 Regional official time-series synchronization (2026-07-14)
@@ -15,7 +15,9 @@ def test_long_context_names_remain_compact_and_inspectable() -> None:
assert "selectedProject?.name === REGIONAL_WORKSPACE_PROJECT_NAME" in app assert "selectedProject?.name === REGIONAL_WORKSPACE_PROJECT_NAME" in app
assert "? REGIONAL_WORKSPACE_LABEL" in app assert "? REGIONAL_WORKSPACE_LABEL" in app
assert "const datasetContextLabel = selectedDataset ? getDatasetDisplayName(selectedDataset)" in app assert "const datasetContextLabel = analysisMapLayerActive && mapFeatureCollection" in app
assert "? getDatasetDisplayName(selectedDataset)" in app
assert "`${mapLayerLabel} · controle vereist`" in app
assert "<strong title={projectContextLabel}>{projectContextLabel}</strong>" in app assert "<strong title={projectContextLabel}>{projectContextLabel}</strong>" in app
assert "<strong title={datasetContextLabel}>{datasetContextLabel}</strong>" in app assert "<strong title={datasetContextLabel}>{datasetContextLabel}</strong>" in app
assert "<strong title={item.value}>{item.value}</strong>" in status assert "<strong title={item.value}>{item.value}</strong>" in status
@@ -61,3 +61,12 @@ def test_detection_qa_remains_persisted_and_primary_not_parallel() -> None:
assert "als kwaliteitscontrole in de database bewaard" in lab assert "als kwaliteitscontrole in de database bewaard" in lab
assert "detectionApi.compareWithReference" in hook assert "detectionApi.compareWithReference" in hook
assert "await loadQualityChecks(selectedProjectId)" in hook assert "await loadQualityChecks(selectedProjectId)" in hook
assert "Minimale IoU voor een match" in lab
assert "detectionQaResult.iou_threshold.toFixed(2)" in lab
def test_active_analysis_is_not_presented_as_the_underlying_source_dataset() -> None:
app = read("frontend/src/App.tsx")
assert "analysisMapLayerActive && mapFeatureCollection" in app
assert "`${mapLayerLabel} · controle vereist`" in app
+9 -1
View File
@@ -8066,5 +8066,13 @@ Validation before final deployment:
- Focused detection, coverage, QA and guided-workflow tests passed. - Focused detection, coverage, QA and guided-workflow tests passed.
- Frontend TypeScript typecheck passed after the source/legend correction. - Frontend TypeScript typecheck passed after the source/legend correction.
Live operational proof:
- The final repository readiness gate passed 578 backend tests, API/document audits, frontend typecheck/build, one Alembic head and all shell smoke checks.
- Deployed commit `0cad8fd` to the Tower all-in-one runtime with AI extras enabled. Health, PostGIS 3.6, the single migration head, required schema/indexes and the port-1202 browser proxy all passed.
- The bounded QA request completed in 1.82 seconds. It retained a raw GRB population of 466,078, materialized/evaluated 1,826 coverage features and excluded 464,252 outside the nine persisted tiles.
- At match IoU 0.25, persisted quality check `341b0076-663a-4427-8a36-d5d9247a730e` measured 1,186 matches, precision 0.6073, recall 0.6495, F1 0.6277 and mean IoU 0.4565. No metric was fabricated.
- A separate UI run at its default stricter match IoU 0.50 also completed and persisted quality check `7a4464cd-152d-424f-a2b9-ed321b91524c`; the lower F1 is now explained by displaying the threshold beside the score.
- In-app browser inspection confirmed 1,953 persisted rows, map rendering over OpenStreetMap and explicit `AI-detecties`, `Detectierun`, `Gevonden gebouwen` and `controle vereist` labels.
Next: Next:
- Deploy the bounded QA correction, rerun the live persisted detection-versus-GRB comparison, verify persisted metrics and inspect the result in MapLibre before declaring the guided operational flow complete. - Add bounded operator-triggered orthophoto acquisition from a drawn map rectangle, then hand that raster to this proven guided pipeline. Keep external acquisition out of browser/startup paths and retain explicit source licensing/provenance.
+7 -1
View File
@@ -685,7 +685,13 @@ function App(): JSX.Element {
? REGIONAL_WORKSPACE_LABEL ? REGIONAL_WORKSPACE_LABEL
: selectedProject?.name ?? 'Geen werkruimte' : selectedProject?.name ?? 'Geen werkruimte'
const areaContextLabel = selectedArea?.name ?? (areas.length > 0 ? 'Kies een gebied' : 'Geen gebied') const areaContextLabel = selectedArea?.name ?? (areas.length > 0 ? 'Kies een gebied' : 'Geen gebied')
const datasetContextLabel = selectedDataset ? getDatasetDisplayName(selectedDataset) : datasets.length > 0 ? 'Kies een bron' : 'Geen bron' const datasetContextLabel = analysisMapLayerActive && mapFeatureCollection
? `${mapLayerLabel} · controle vereist`
: selectedDataset
? getDatasetDisplayName(selectedDataset)
: datasets.length > 0
? 'Kies een bron'
: 'Geen bron'
const layerContextLabel = mapFeatureCollection const layerContextLabel = mapFeatureCollection
? `${mapFeatureCount.toLocaleString('nl-BE')} objecten` ? `${mapFeatureCount.toLocaleString('nl-BE')} objecten`
: viewportVectorLayerActive : viewportVectorLayerActive
@@ -1080,6 +1080,7 @@ export function DetectionLab({
<p>Recall: {detectionQaResult.recall?.toFixed(3) ?? 'n/a'}</p> <p>Recall: {detectionQaResult.recall?.toFixed(3) ?? 'n/a'}</p>
<p>F1: {detectionQaResult.f1_score?.toFixed(3) ?? 'n/a'}</p> <p>F1: {detectionQaResult.f1_score?.toFixed(3) ?? 'n/a'}</p>
<p>Gemiddelde overlap: {detectionQaResult.mean_iou?.toFixed(3) ?? 'n.v.t.'}</p> <p>Gemiddelde overlap: {detectionQaResult.mean_iou?.toFixed(3) ?? 'n.v.t.'}</p>
<p>Minimale IoU voor een match: {detectionQaResult.iou_threshold.toFixed(2)}</p>
<p>Fout positief: {detectionQaResult.false_positives}</p> <p>Fout positief: {detectionQaResult.false_positives}</p>
<p>Fout negatief: {detectionQaResult.false_negatives}</p> <p>Fout negatief: {detectionQaResult.false_negatives}</p>
{detectionQaResult.coverage ? ( {detectionQaResult.coverage ? (