From 02e27dfa3885180d5cccefd033996abb7f59c718 Mon Sep 17 00:00:00 2001 From: Filip Leitner Date: Tue, 5 Nov 2024 16:03:54 +0100 Subject: [PATCH] perf(pop-up): Reduce usage of getLayerForFeature --- .../query-popup/query-popup-base.service.ts | 54 +++++++++++-------- .../query-popup/query-popup.component.ts | 13 ++--- .../query-popup/query-popup.service.model.ts | 2 +- .../hslayers/services/draw/draw.service.ts | 3 +- .../services/query/query-vector.service.ts | 2 +- 5 files changed, 38 insertions(+), 36 deletions(-) diff --git a/projects/hslayers/common/query-popup/query-popup-base.service.ts b/projects/hslayers/common/query-popup/query-popup-base.service.ts index 1fe69779da..e222b4ce56 100644 --- a/projects/hslayers/common/query-popup/query-popup-base.service.ts +++ b/projects/hslayers/common/query-popup/query-popup-base.service.ts @@ -4,12 +4,13 @@ import {ReplaySubject} from 'rxjs'; import {Feature} from 'ol'; import {Geometry} from 'ol/geom'; +import {HsFeatureLayer} from './query-popup.service.model'; import {HsMapService} from 'hslayers-ng/services/map'; import {HsPanelItem} from 'hslayers-ng/common/panels'; import {HsQueryPopupData} from './popup-data'; import {HsQueryPopupWidgetContainerService} from './query-popup-widget-container.service'; import {HsUtilsService} from 'hslayers-ng/services/utils'; -import {getPopUp, getTitle} from 'hslayers-ng/common/extensions'; +import {getName, getPopUp, getTitle} from 'hslayers-ng/common/extensions'; @Injectable({ providedIn: 'root', @@ -33,29 +34,36 @@ export class HsQueryPopupBaseService extends HsQueryPopupData { this.zone.run(() => { this.featuresUnderMouse = features; if (this.featuresUnderMouse.length) { - const layersFound = this.hsUtilsService.removeDuplicates( - this.featuresUnderMouse.map((f) => - this.hsMapService.getLayerForFeature(f), - ), - 'title', + const featuresByLayer = features.reduce( + (acc, feature) => { + const layer = this.hsMapService.getLayerForFeature(feature); + if (layer === undefined) { + return acc; + } + const popUp = getPopUp(layer); + if (popUp) { + const layerName = getName(layer); + if (!acc[layerName]) { + const needSpecialWidgets = + popUp.widgets || popUp.displayFunction; + acc[layerName] = { + layer: layer, + title: getTitle(layer), + features: [], + panelObserver: needSpecialWidgets + ? new ReplaySubject() + : undefined, + }; + } + acc[layerName].features.push(feature); + } + return acc; + }, + {} as {[key: string]: HsFeatureLayer}, ); - this.featureLayersUnderMouse = layersFound - .filter((l) => getPopUp(l)) //Only list the layers which have popUp defined - .map((l) => { - const needSpecialWidgets = - getPopUp(l)?.widgets || getPopUp(l)?.displayFunction; - const layer = { - title: getTitle(l), - layer: l, - features: this.featuresUnderMouse.filter( - (f) => this.hsMapService.getLayerForFeature(f) == l, - ), - panelObserver: needSpecialWidgets - ? new ReplaySubject() - : undefined, - }; - return layer; - }); + + this.featureLayersUnderMouse = Object.values(featuresByLayer); + for (const layer of this.featureLayersUnderMouse) { if (layer.panelObserver) { const popupDef = getPopUp(layer.layer); diff --git a/projects/hslayers/common/query-popup/query-popup.component.ts b/projects/hslayers/common/query-popup/query-popup.component.ts index c534dbf44b..6bd14f56ad 100644 --- a/projects/hslayers/common/query-popup/query-popup.component.ts +++ b/projects/hslayers/common/query-popup/query-popup.component.ts @@ -17,7 +17,6 @@ import {HsMapService} from 'hslayers-ng/services/map'; import {HsQueryPopupServiceModel} from './query-popup.service.model'; import {HsQueryPopupWidgetContainerService} from './query-popup-widget-container.service'; import {getFeatures} from 'hslayers-ng/common/extensions'; -import {getPopUp} from 'hslayers-ng/common/extensions'; @Component({ selector: 'hs-query-popup', @@ -71,16 +70,10 @@ export class HsQueryPopupComponent if (this.data.service == undefined) { return DISPLAY_NONE; } - const featuresWithPopup = this.data.service.featuresUnderMouse.filter( - (f) => { - const layer = this.hsMapService.getLayerForFeature(f); - if (!layer) { - return DISPLAY_NONE; - } - return getPopUp(layer) != undefined; - }, + const featureCount = this.data.service.featureLayersUnderMouse.reduce( + (acc, featureLayer) => acc + featureLayer.features.length, + 0, ); - const featureCount = featuresWithPopup.length; if (featureCount > 0) { let tmpForHover: any[] = []; this.data.service.featuresUnderMouse.forEach((feature) => { diff --git a/projects/hslayers/common/query-popup/query-popup.service.model.ts b/projects/hslayers/common/query-popup/query-popup.service.model.ts index cd85d1a446..a3d95a7f0b 100644 --- a/projects/hslayers/common/query-popup/query-popup.service.model.ts +++ b/projects/hslayers/common/query-popup/query-popup.service.model.ts @@ -9,7 +9,7 @@ import {HsQueryPopupData} from './popup-data'; export type HsFeatureLayer = { title: string; - feature: Feature[]; + features: Feature[]; layer: VectorLayer>; panelObserver: ReplaySubject; }; diff --git a/projects/hslayers/services/draw/draw.service.ts b/projects/hslayers/services/draw/draw.service.ts index 605815282b..0b5cdccaf5 100644 --- a/projects/hslayers/services/draw/draw.service.ts +++ b/projects/hslayers/services/draw/draw.service.ts @@ -108,7 +108,8 @@ export class HsDrawService extends HsDrawServiceParams { this.hsEventBusService.vectorQueryFeatureSelection.subscribe((event) => { this.selectedFeatures.push(event.feature); - if (getEditor(event.selector.getLayer(event.feature)).editable) { + const layer = event.selector.getLayer(event.feature); + if (getEditor(layer)?.editable) { this.modify.setActive(true); } }); diff --git a/projects/hslayers/services/query/query-vector.service.ts b/projects/hslayers/services/query/query-vector.service.ts index 98e9ea1c47..e0f8a9c19b 100644 --- a/projects/hslayers/services/query/query-vector.service.ts +++ b/projects/hslayers/services/query/query-vector.service.ts @@ -78,7 +78,7 @@ export class HsQueryVectorService { this.hsEventBusService.vectorQueryFeatureSelection.subscribe((e) => { if (e?.feature) { - const layer = this.hsMapService.getLayerForFeature(e.feature); + const layer = e.selector.getLayer(e.feature); if (layer && getOnFeatureSelected(layer)) { const originalFeature = this.getSelectedFeature(e.feature); if (originalFeature) {