Add guided operational GIS workflow
This commit is contained in:
@@ -308,6 +308,7 @@ export function MapWorkspace({
|
||||
)
|
||||
const selectedFeatureFilename = selectedFeatureStem === 'selected-feature' ? DEFAULT_SELECTED_FEATURE_FILENAME : `${selectedFeatureStem}.geojson`
|
||||
const selectedMapDataset = availableMapDatasets.find((dataset) => dataset.id === selectedMapDatasetId) ?? null
|
||||
const usesDefaultOsmBasemap = !import.meta.env.VITE_MAP_STYLE_URL
|
||||
|
||||
useEffect(() => {
|
||||
setBboxInput(bboxToInputState(mapSelectionBbox))
|
||||
@@ -437,6 +438,12 @@ export function MapWorkspace({
|
||||
</div>
|
||||
|
||||
<div className="map-control-surface" aria-label="Map workspace controls">
|
||||
{usesDefaultOsmBasemap ? (
|
||||
<div className="basemap-policy-notice" aria-label="Basemap usage notice">
|
||||
<strong>Local/demo basemap</strong>
|
||||
<span>Public OpenStreetMap tiles are active. Configure VITE_MAP_STYLE_URL for production or heavier use.</span>
|
||||
</div>
|
||||
) : null}
|
||||
<div className="map-toolbar">
|
||||
<label>
|
||||
Database layer
|
||||
@@ -664,6 +671,92 @@ export function MapWorkspace({
|
||||
</button>
|
||||
</div>
|
||||
{mapSelectionError ? <p className="error">{mapSelectionError}</p> : null}
|
||||
<div className="guided-gis-flow" aria-label="Guided operational GIS workflow">
|
||||
<div className="guided-gis-steps">
|
||||
<div className={selectedMapDataset ? 'complete' : ''}>
|
||||
<span>1</span>
|
||||
<strong>Layer</strong>
|
||||
<small>{selectedMapDataset ? selectedMapDataset.name : 'Select database layer'}</small>
|
||||
</div>
|
||||
<div className={currentSelectionBbox ? 'complete' : ''}>
|
||||
<span>2</span>
|
||||
<strong>Extent</strong>
|
||||
<small>{currentSelectionBbox ? 'AOI/layer bbox ready' : 'Use AOI or layer extent'}</small>
|
||||
</div>
|
||||
<div className={mapSelectionResult ? 'complete' : ''}>
|
||||
<span>3</span>
|
||||
<strong>Query</strong>
|
||||
<small>{mapSelectionResult ? `${mapSelectionResult.feature_count} persisted features` : 'Run PostGIS selection'}</small>
|
||||
</div>
|
||||
<div className={latestSelectionDatasetName ? 'complete' : ''}>
|
||||
<span>4</span>
|
||||
<strong>Dataset</strong>
|
||||
<small>{latestSelectionDatasetName ?? 'Save query result'}</small>
|
||||
</div>
|
||||
<div className={mapSelectionQaResult ? 'complete' : ''}>
|
||||
<span>5</span>
|
||||
<strong>QA/QC</strong>
|
||||
<small>{mapSelectionQaResult ? `F1 ${mapSelectionQaResult.f1_score ?? 'n/a'}` : 'Compare with reference'}</small>
|
||||
</div>
|
||||
<div className={latestSelectionExportPath ? 'complete' : ''}>
|
||||
<span>6</span>
|
||||
<strong>Export</strong>
|
||||
<small>{latestSelectionExportPath ? 'GeoJSON artifact ready' : 'Save handoff artifact'}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="guided-gis-actions">
|
||||
<button
|
||||
className="secondary-action"
|
||||
disabled={!mapSelectionResult || !currentSelectionBbox || selectionDatasetSaving}
|
||||
type="button"
|
||||
onClick={saveAreaSelectionDataset}
|
||||
>
|
||||
{selectionDatasetSaving ? 'Saving dataset...' : 'Save result dataset'}
|
||||
</button>
|
||||
<button
|
||||
className="secondary-action"
|
||||
disabled={!mapSelectionResult || !currentSelectionBbox || selectionExporting}
|
||||
type="button"
|
||||
onClick={saveAreaSelectionExport}
|
||||
>
|
||||
{selectionExporting ? 'Saving export...' : 'Save GeoJSON export'}
|
||||
</button>
|
||||
<label>
|
||||
Reference
|
||||
<select
|
||||
value={selectedMapQaReferenceDatasetId}
|
||||
onChange={(event) => onSelectMapQaReferenceDataset(event.target.value)}
|
||||
disabled={!latestSelectionDatasetName || mapQaReferenceDatasets.length === 0 || mapSelectionQaRunning}
|
||||
>
|
||||
<option value="">Select reference</option>
|
||||
{mapQaReferenceDatasets.map((dataset) => (
|
||||
<option key={dataset.id} value={dataset.id}>
|
||||
{dataset.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
<button
|
||||
className="primary-action"
|
||||
disabled={!latestSelectionDatasetName || !selectedMapQaReferenceDatasetId || mapSelectionQaRunning}
|
||||
type="button"
|
||||
onClick={onRunMapSelectionQa}
|
||||
>
|
||||
{mapSelectionQaRunning ? 'Running QA...' : 'Run QA/QC'}
|
||||
</button>
|
||||
<button
|
||||
className="secondary-action"
|
||||
disabled={!latestMapSelectionQualityCheckId}
|
||||
type="button"
|
||||
onClick={onOpenMapSelectionQualityEvidence}
|
||||
>
|
||||
Open evidence
|
||||
</button>
|
||||
</div>
|
||||
{selectionDatasetError ? <p className="error">{selectionDatasetError}</p> : null}
|
||||
{selectionExportError ? <p className="error">{selectionExportError}</p> : null}
|
||||
{mapSelectionQaError ? <p className="error">{mapSelectionQaError}</p> : null}
|
||||
</div>
|
||||
</div>
|
||||
<div className="bbox-select-surface" aria-label="Area selection and extract">
|
||||
<div className="panel-title-row">
|
||||
|
||||
Reference in New Issue
Block a user