import type { DatasetCreateResponse, JobRead, SegmentationModelCapability, SegmentationQaResult, SegmentationRead, SegmentationRunRead, SegmentationRunResponse, } from '../../types' import { ModelSelector } from '../models/ModelSelector' import { analysisModelAvailabilityMessage, analysisModelDisplayName, toAnalysisModelOption, } from '../models/modelOptions' import { getDatasetSelectionLabel } from '../../lib/datasetDisplay' interface SegmentationLabProps { managementLocked?: boolean blockedInferenceDatasetCount?: number segmentationModels: SegmentationModelCapability[] loadingSegmentationModels: boolean segmentationModelError: string | null selectedSegmentationDatasetId: string selectedSegmentationModelId: string segmentationTileManifestPath: string segmentationConfidenceThreshold: number runningSegmentation: boolean segmentationJob: JobRead | null segmentationRunResult: SegmentationRunResponse | null segmentationRunError: string | null segmentationRuns: SegmentationRunRead[] selectedSegmentationRunId: string segmentationItems: SegmentationRead[] segmentationTotal: number segmentationTruncated: boolean segmentationClassFilter: string segmentationMinConfidenceFilter: number loadingSegmentationResults: boolean segmentationReferenceDatasetId: string segmentationQaResult: SegmentationQaResult | null segmentationQaError: string | null runningSegmentationQa: boolean selectedProjectId: string | null rasterDatasets: DatasetCreateResponse[] referenceDatasets: DatasetCreateResponse[] selectedSegmentationModelConfigured: boolean selectedSegmentationModelLimitation: string | null onLoadModels: () => void onSelectDataset: (datasetId: string) => void onSelectModel: (modelId: string) => void onSetTileManifestPath: (value: string) => void onSetConfidenceThreshold: (value: number) => void onRunSegmentation: () => void onLoadRuns: () => void onSelectRun: (runId: string) => void onSetClassFilter: (value: string) => void onSetMinConfidenceFilter: (value: number) => void onLoadResults: () => void onSelectReferenceDataset: (datasetId: string) => void onRunQa: () => void } function segmentationRunLabel(run: SegmentationRunRead): string { const timestamp = run.finished_at ?? run.created_at const dateLabel = timestamp ? new Intl.DateTimeFormat('nl-BE', { dateStyle: 'short', timeStyle: 'short' }).format(new Date(timestamp)) : 'datum onbekend' return `${persistedSegmentationModelLabel(run.model_name)} · ${analysisStatusLabel(run.status)} · ${dateLabel}` } function analysisStatusLabel(status: string): string { if (status === 'completed') return 'afgerond' if (status === 'success') return 'geslaagd' if (status === 'failed') return 'mislukt' if (status === 'running') return 'bezig' if (status === 'queued') return 'in wachtrij' return status.replace(/_/g, ' ') } function persistedSegmentationModelLabel(modelName: string | null | undefined): string { if (!modelName) return 'Segmentatie' if (modelName === 'fixture-segmenter') return 'Testsegmentatie' if (modelName === 'sam-placeholder') return 'SAM-model niet geconfigureerd' if (modelName === 'yolo-seg-placeholder') return 'YOLO-segmentatie niet geconfigureerd' if (modelName === 'segmentation-placeholder') return 'Segmentatiemodel niet geconfigureerd' if (modelName === 'yolo-seg-configured') return 'Lokaal YOLO-segmentatiemodel' if (modelName === 'sam-configured') return 'Lokaal SAM-model' return modelName } function segmentationClassLabel(className: string): string { if (className.toLowerCase() === 'building') return 'Gebouw' return className } export function SegmentationLab({ managementLocked = false, blockedInferenceDatasetCount = 0, segmentationModels, loadingSegmentationModels, segmentationModelError, selectedSegmentationDatasetId, selectedSegmentationModelId, segmentationTileManifestPath, segmentationConfidenceThreshold, runningSegmentation, segmentationJob, segmentationRunResult, segmentationRunError, segmentationRuns, selectedSegmentationRunId, segmentationItems, segmentationTotal, segmentationTruncated, segmentationClassFilter, segmentationMinConfidenceFilter, loadingSegmentationResults, segmentationReferenceDatasetId, segmentationQaResult, segmentationQaError, runningSegmentationQa, selectedProjectId, rasterDatasets, referenceDatasets, selectedSegmentationModelConfigured, selectedSegmentationModelLimitation, onLoadModels, onSelectDataset, onSelectModel, onSetTileManifestPath, onSetConfidenceThreshold, onRunSegmentation, onLoadRuns, onSelectRun, onSetClassFilter, onSetMinConfidenceFilter, onLoadResults, onSelectReferenceDataset, onRunQa, }: SegmentationLabProps): JSX.Element { const segmentationHasDataset = selectedSegmentationDatasetId.length > 0 const segmentationHasTileManifest = segmentationTileManifestPath.trim().length > 0 const segmentationModelUiRunnable = selectedSegmentationModelConfigured && selectedSegmentationModelId !== 'fixture-segmenter' const selectedSegmentationModel = segmentationModels.find( (model) => model.model_id === selectedSegmentationModelId, ) ?? null const selectedSegmentationModelAvailability = selectedSegmentationModel ? analysisModelAvailabilityMessage(selectedSegmentationModel) : selectedSegmentationModelLimitation ?? 'Het gekozen segmentatiemodel is niet geconfigureerd' const segmentationRunReady = Boolean(selectedProjectId) && segmentationHasDataset && segmentationModelUiRunnable const segmentationJobActive = segmentationJob?.status === 'queued' || segmentationJob?.status === 'running' const segmentationRunBlockedReason = !selectedProjectId ? 'Kies eerst een werkruimte' : !segmentationHasDataset ? 'Kies een rasterbestand' : selectedSegmentationModelId === 'fixture-segmenter' ? 'Het fixturemodel is alleen bedoeld voor expliciete tests en demo’s' : !selectedSegmentationModelConfigured ? selectedSegmentationModelAvailability : null return (

Vlakken herkennen in beeld

Segmentatie

Technische modelinformatie {segmentationModels.length} modellen
{loadingSegmentationModels ? (
Segmentatiemodellen worden gecontroleerd.

GeoIntel leest de modelregistratie van de backend.

) : null} {segmentationModelError ? (
De modelregistratie voor segmentatie is niet bereikbaar.

{segmentationModelError}

) : null} {segmentationModels.length === 0 && !loadingSegmentationModels ? (
De backend meldt geen segmentatiemodellen.

Vernieuw de status zodra de backend opnieuw bereikbaar is.

) : null}
    {segmentationModels.map((model) => (
  • {analysisModelDisplayName(model)} {model.configured ? 'gereed' : 'niet geconfigureerd'}

    Ondersteunde klassen: {model.supported_classes.join(', ') || 'niet opgegeven'}

    {analysisModelAvailabilityMessage(model)}

    Technische identificatie
    Model-ID: {model.model_id} Framework: {model.framework} Taaktype: {model.task_type}
  • ))}

Nieuwe segmentatie

Wat is nog nodig?

GeoIntel controleert het raster en model voordat de verwerking start.

{segmentationRunReady ? 'Klaar om te starten' : 'Nog niet startklaar'}
Rasterbestand {segmentationHasDataset ? 'Geselecteerd' : 'Kies een rasterbestand'}
Analysemodel {selectedSegmentationModelId === 'fixture-segmenter' ? 'Alleen beschikbaar voor geautomatiseerde tests' : selectedSegmentationModelConfigured ? 'Het gekozen model is beschikbaar' : selectedSegmentationModelAvailability}
Beeldtegels {segmentationHasTileManifest ? 'Technisch manifest gekoppeld' : segmentationHasDataset ? 'Worden automatisch voorbereid' : 'Wachten op een rasterbestand'}
Analyse {segmentationRunReady ? 'Klaar om segmentatie te starten' : segmentationRunBlockedReason}
{rasterDatasets.length === 0 ? (
Geen rasterbestand beschikbaar voor segmentatie. {blockedInferenceDatasetCount > 0 ? (

{blockedInferenceDatasetCount} rasterbestand(en) zijn vooraf uitgesloten door fixture-, quarantaine-, validatie- of provenancegegevens. De volledige servergate blijft beslissend.

) : null}

{managementLocked ? 'Ga naar Kaart en maak een begrensde officiële bronselectie. De synthetische demo-context blijft bewust uitgesloten van geconfigureerde modelinference.' : 'Voeg eerst een gevalideerd rasterbestand toe onder Bronnen of haal via Kaart een begrensde officiële bron op.'}

) : null}
{!managementLocked ?
Technische beeldtegelinstelling
: null}
{segmentationJobActive ? (
{segmentationJob?.status === 'queued' ? 'GPU-taak staat in de wachtrij.' : 'GPU-segmentatie wordt uitgevoerd.'}

{segmentationJob?.status === 'queued' ? 'De server start de taak zodra de NVIDIA-worker beschikbaar is.' : 'GeoIntel volgt de servertaak en toont na voltooiing alleen de werkelijk bewaarde polygonen.'}

Taak-ID: {segmentationJob?.id}
) : null} {!selectedSegmentationModelConfigured ? (
Het segmentatiemodel is nog niet gereed.

{selectedSegmentationModelAvailability}

) : null} {segmentationRunError ? (
De segmentatie is mislukt.

{segmentationRunError}

) : null} {segmentationRunResult ? (

Status: {analysisStatusLabel(segmentationRunResult.status)}

{segmentationRunResult.message}

Herkende vlakken: {segmentationRunResult.segmentation_count}

{segmentationRunResult.error_code ?

Code: {segmentationRunResult.error_code}

: null}
Technische verwerking
Analyserun-ID: {segmentationRunResult.analysis_run_id} Taak-ID: {segmentationRunResult.job_id}
) : null}

Herkende vlakken

Bekijk bewaarde resultaten en filter op klasse of zekerheid.

{loadingSegmentationResults ? (
Segmentatieresultaten worden geladen.

GeoIntel leest de bewaarde polygonen van deze analyse.

) : null}
{loadingSegmentationResults || segmentationRunError ? null : !selectedSegmentationRunId ? (
Kies eerst een bewaarde analyse.

Daarna toont GeoIntel uitsluitend de polygonen van die analyserun.

) : segmentationTotal === 0 ? (
Geen bewaarde vlakken binnen deze filters.

Dit bewijst niet dat het gebied geen relevante objecten bevat.

) : (
{segmentationTruncated ? `${segmentationItems.length} van ${segmentationTotal} vlakken geladen` : `${segmentationTotal} vlakken geladen`}

{segmentationTruncated ? 'De kaart en tabel tonen een begrensde pagina. Gebruik filters om het resultaat gericht te verfijnen.' : 'Deze resultaten zijn bewaard in de database.'}

)}
{segmentationItems.length > 0 ? (
{segmentationItems.map((segmentation) => ( ))}
Klasse Zekerheid Oppervlakte m² Model Herkomst
{segmentationClassLabel(segmentation.class_name)} {segmentation.confidence?.toFixed(2) ?? 'n.v.t.'} {segmentation.area_m2?.toFixed(2) ?? 'n.v.t.'} {persistedSegmentationModelLabel(segmentation.model_name)} {segmentation.tile_index == null ? 'n.v.t.' : 'Luchtbeeldtegel'}
) : null}

Kwaliteitscontrole segmentatie

{segmentationQaError ? (
De kwaliteitscontrole is mislukt.

{segmentationQaError}

) : null} {segmentationQaResult ? (

Status: {segmentationQaResult.status === 'completed' ? 'afgerond' : segmentationQaResult.status}

Precisie: {segmentationQaResult.precision?.toFixed(3) ?? 'n.v.t.'}

Herkenningsgraad: {segmentationQaResult.recall?.toFixed(3) ?? 'n.v.t.'}

F1: {segmentationQaResult.f1_score?.toFixed(3) ?? 'n.v.t.'}

Gemiddelde overlap: {segmentationQaResult.mean_iou?.toFixed(3) ?? 'n.v.t.'}

Onterecht gevonden: {segmentationQaResult.false_positives}

Gemist: {segmentationQaResult.false_negatives}

Technische referentie Kwaliteitscontrole-ID: {segmentationQaResult.quality_check_id}
) : null}
) }