UNPKG

@geogirafe/lib-geoportal

Version:

GeoGirafe is a flexible application to build online geoportals.

81 lines (80 loc) 3.87 kB
// SPDX-License-Identifier: Apache-2.0 import GirafeSingleton from '../../base/GirafeSingleton.js'; import { SelectionMode } from '../../models/selection.js'; import { applyFeaturesToSelection } from '../utils/utils.js'; /** * Handles the feature selection, independently from the map (2D or 3D) the selection was triggered from. * The selection is done in two steps: * 1. `select()` asks every layer manager to add its own <code>SelectionParam</code> to the state. * 2. The change of <code>selection.selectionParameters</code> triggers the effective query * (WMS GetFeatureInfo and WFS GetFeature) and writes the resulting features into the state. */ export default class SelectionManager extends GirafeSingleton { get state() { return this.context.stateManager.state; } initializeSingleton() { this.context.stateManager.subscribe('selection.selectionParameters', (_, newParams) => { // The querying is asynchronous and nobody awaits it here, // so a failing request must not end up in an unhandled rejection. this.onSelectFeatures(newParams).catch((error) => console.error('Could not select the features.', error)); }); } /** * Selects all the features of the queryable layers that are inside the given extent. * Layers selectable today are WMS, WMTS (with wms layer) and Local files. */ select(extent) { // Reset current selection if SelectionMode is Replace if (this.state.selection.selectionMode === SelectionMode.Replace) { this.selectNone(); } else if (this.state.selection.selectionMode === SelectionMode.Add) { this.state.selection.selectionParameters = []; } // Use batch for changes to prevent multiple selection of objects this.context.stateManager.batchChanges(() => { this.context.wmsManager.selectFeatures(extent); this.context.wmtsManager.selectFeatures(extent); this.context.localFileManager.selectFeatures(extent); }); } selectNone() { this.state.selection.selectedFeatures = []; this.state.selection.selectionParameters = []; this.state.selection.highlightedFeatures = []; } async onSelectFeatures(selectionParams) { if (selectionParams.length === 0) { return; } this.state.loading = true; try { // WMS GetFeatureInfo const wmsPromises = selectionParams.map((param) => { const wmsGetFeatureInfoSelectionParam = param.clone((l) => l.queryable && l.wmsQueryableOnly); const client = this.context.wmsManager.getClient(wmsGetFeatureInfoSelectionParam.ogcServer); return client.getFeatureInfo(wmsGetFeatureInfoSelectionParam); }); // WFS GetFeature const wfsPromises = selectionParams.map((param) => { const wfsGetFeatureInfoSelectionParam = param.clone((l) => l.wfsQueryable); const client = this.context.wfsManager.getClient(wfsGetFeatureInfoSelectionParam.ogcServer); const features = client.getFeature(wfsGetFeatureInfoSelectionParam); return features; }); const wmsGmlFeatures = (await Promise.all(wmsPromises)).flat(); const wfsGmlFeatures = (await Promise.all(wfsPromises)).flat(); const gmlFeatures = [...wmsGmlFeatures, ...wfsGmlFeatures]; if (gmlFeatures.length === 0 && this.state.selection.selectedFeatures.length === 0) { this.state.interface.selectionComponentVisible = false; } else { applyFeaturesToSelection(gmlFeatures, this.state); } } finally { this.state.loading = false; } } }