Improve operational GIS map workflow
This commit is contained in:
@@ -209,6 +209,7 @@ interface MapWorkspaceProps {
|
||||
mapSelectionQaResult: QaComparisonResult | null
|
||||
latestMapSelectionQualityCheckId: string | null
|
||||
availableMapDatasets: DatasetCreateResponse[]
|
||||
selectedMapDatasetId: string
|
||||
onSelectMapArea: (areaId: string) => void
|
||||
onOpenDatasetInMap: (dataset: DatasetCreateResponse) => void
|
||||
onSetAreaLayerVisible: (visible: boolean) => void
|
||||
@@ -265,6 +266,7 @@ export function MapWorkspace({
|
||||
mapSelectionQaResult,
|
||||
latestMapSelectionQualityCheckId,
|
||||
availableMapDatasets,
|
||||
selectedMapDatasetId,
|
||||
onSelectMapArea,
|
||||
onOpenDatasetInMap,
|
||||
onSetAreaLayerVisible,
|
||||
@@ -305,6 +307,7 @@ export function MapWorkspace({
|
||||
featureProperties?.['name'] ?? featureProperties?.['id'] ?? featureProperties?.['source_feature_id'] ?? 'selected-feature',
|
||||
)
|
||||
const selectedFeatureFilename = selectedFeatureStem === 'selected-feature' ? DEFAULT_SELECTED_FEATURE_FILENAME : `${selectedFeatureStem}.geojson`
|
||||
const selectedMapDataset = availableMapDatasets.find((dataset) => dataset.id === selectedMapDatasetId) ?? null
|
||||
|
||||
useEffect(() => {
|
||||
setBboxInput(bboxToInputState(mapSelectionBbox))
|
||||
@@ -384,6 +387,22 @@ export function MapWorkspace({
|
||||
onDeriveMapSelectionDataset(bbox)
|
||||
}
|
||||
|
||||
const openSelectedDatabaseLayer = (datasetId: string) => {
|
||||
const dataset = availableMapDatasets.find((item) => item.id === datasetId)
|
||||
if (dataset) {
|
||||
onOpenDatasetInMap(dataset)
|
||||
}
|
||||
}
|
||||
|
||||
const runQuickAoiExtract = () => {
|
||||
const bbox = selectedAreaBbox ?? activeLayerBbox
|
||||
if (!bbox) {
|
||||
return
|
||||
}
|
||||
setSelectionBbox(bbox)
|
||||
onRunMapSelectionExtract(bbox)
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="map-workspace-shell" data-testid="map-workspace">
|
||||
<div className="panel-title-row">
|
||||
@@ -419,6 +438,22 @@ export function MapWorkspace({
|
||||
|
||||
<div className="map-control-surface" aria-label="Map workspace controls">
|
||||
<div className="map-toolbar">
|
||||
<label>
|
||||
Database layer
|
||||
<select
|
||||
value={selectedMapDatasetId}
|
||||
onChange={(event) => openSelectedDatabaseLayer(event.target.value)}
|
||||
disabled={availableMapDatasets.length === 0}
|
||||
data-testid="map-database-layer-select"
|
||||
>
|
||||
<option value="">Select persisted vector layer</option>
|
||||
{availableMapDatasets.map((dataset) => (
|
||||
<option key={dataset.id} value={dataset.id}>
|
||||
{dataset.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
Area
|
||||
<select
|
||||
@@ -483,6 +518,7 @@ export function MapWorkspace({
|
||||
</div>
|
||||
<div className="map-status">
|
||||
<strong>{mapLayerLabel}</strong>
|
||||
<span>{selectedMapDataset ? `DB layer: ${selectedMapDataset.name}` : 'No database layer selected'}</span>
|
||||
<span>{areaFeatureCollection ? `${areaFeatureCount} AOI loaded` : 'No AOI loaded'}</span>
|
||||
<span>{mapFeatureCollection ? `${mapFeatureCount} features loaded` : 'No vector/result layer loaded'}</span>
|
||||
</div>
|
||||
@@ -572,6 +608,63 @@ export function MapWorkspace({
|
||||
</div>
|
||||
|
||||
<div className="map-inspection-surface">
|
||||
<div className="gis-test-run-surface" aria-label="Operational GIS test run">
|
||||
<div className="panel-title-row">
|
||||
<div>
|
||||
<p className="eyebrow">Operational GIS run</p>
|
||||
<h3>Database selection test</h3>
|
||||
</div>
|
||||
<span className="count-pill">{mapSelectionResult ? `${mapSelectionResult.feature_count} hits` : 'ready'}</span>
|
||||
</div>
|
||||
<p className="muted">
|
||||
Select a persisted vector layer, then query stored vector_features from PostGIS with the AOI or layer extent.
|
||||
</p>
|
||||
<div className="gis-test-run-grid">
|
||||
<div>
|
||||
<span>Database layer</span>
|
||||
<strong>{selectedMapDataset?.name ?? 'Select a layer'}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>AOI bbox</span>
|
||||
<strong>{selectedAreaBbox ? 'available' : 'missing'}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>Layer bbox</span>
|
||||
<strong>{activeLayerBbox ? 'available' : 'missing'}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>Result</span>
|
||||
<strong>{mapSelectionResult ? `${mapSelectionResult.feature_count} features` : 'not run'}</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div className="feature-extract-actions">
|
||||
<button
|
||||
className="primary-action"
|
||||
disabled={!selectedMapDataset || !mapFeatureCollection || (!selectedAreaBbox && !activeLayerBbox) || mapSelectionLoading}
|
||||
type="button"
|
||||
onClick={runQuickAoiExtract}
|
||||
>
|
||||
{mapSelectionLoading ? 'Running test...' : 'Run AOI/layer query'}
|
||||
</button>
|
||||
<button
|
||||
className="secondary-action"
|
||||
disabled={!selectedAreaBbox}
|
||||
type="button"
|
||||
onClick={() => setSelectionBbox(selectedAreaBbox)}
|
||||
>
|
||||
Use AOI extent
|
||||
</button>
|
||||
<button
|
||||
className="secondary-action"
|
||||
disabled={!activeLayerBbox}
|
||||
type="button"
|
||||
onClick={() => setSelectionBbox(activeLayerBbox)}
|
||||
>
|
||||
Use layer extent
|
||||
</button>
|
||||
</div>
|
||||
{mapSelectionError ? <p className="error">{mapSelectionError}</p> : null}
|
||||
</div>
|
||||
<div className="bbox-select-surface" aria-label="Area selection and extract">
|
||||
<div className="panel-title-row">
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user