From 0f6df441c306daa7e515d03431ad15669b1cf27f Mon Sep 17 00:00:00 2001 From: Tim Deubler Date: Thu, 15 Feb 2024 18:22:18 +0100 Subject: [PATCH] To ensure backwards compatibility, feature ID queries are now typeless again. Signed-off-by: Tim Deubler --- .../core/src/providers/FeatureProvider.ts | 54 ++++++--------- .../core/src/providers/FeatureRegistry.ts | 66 +++++++++++++++++++ 2 files changed, 85 insertions(+), 35 deletions(-) create mode 100644 packages/core/src/providers/FeatureRegistry.ts diff --git a/packages/core/src/providers/FeatureProvider.ts b/packages/core/src/providers/FeatureProvider.ts index 4d47b7e7b..80cd5aa41 100644 --- a/packages/core/src/providers/FeatureProvider.ts +++ b/packages/core/src/providers/FeatureProvider.ts @@ -33,6 +33,7 @@ import {TileProviderOptions} from './TileProvider/TileProviderOptions'; import {GeoPoint} from '../geo/GeoPoint'; import {GeoRect} from '../geo/GeoRect'; import {PathFinder} from '../route/Route'; +import {FeatureRegistry, FeatureRegistryInfo} from './FeatureRegistry'; const REMOVE_FEATURE_EVENT = 'featureRemove'; @@ -41,25 +42,12 @@ const MODIFY_FEATURE_COORDINATES_EVENT = 'featureCoordinatesChange'; let UNDEF; - -class FeatureStorageInfo { - feature: Feature; - tiles: Set; - - constructor(feature: Feature) { - this.feature = feature; - this.tiles = new Set(); - } -} - -// FeatureStorageInfo.prototype.cnt = 0; - /** * Feature provider. * */ export class FeatureProvider extends Provider { - fStore: Map = new Map(); + private fReg: FeatureRegistry; // Map = new Map(); Feature: any; @@ -82,6 +70,7 @@ export class FeatureProvider extends Provider { super(options); this.tree = new RTree(9); + this.fReg = new FeatureRegistry(); this.Feature = this.Feature || Feature; @@ -107,7 +96,7 @@ export class FeatureProvider extends Provider { unique[unique.length] = provider.getFeature(prepared.id); } } else { - // unkown feature + // unknown feature console.warn('unkown feature detected..', feature.geometry.type, feature); } } @@ -276,10 +265,7 @@ export class FeatureProvider extends Provider { * Get all the features that are currently present in the provider. */ all(): Feature[] { - const data = new Array(this.cnt); - let i = 0; - this.fStore.forEach((f) => data[i++] = f.feature); - return data; + return this.fReg.toArray(); }; /** @@ -290,7 +276,7 @@ export class FeatureProvider extends Provider { * @returns the found feature or undefined if feature is not present. */ getFeature(id: string | number): Feature | undefined { - return this.fStore.get(id)?.feature; + return this.fReg.get(id)?.feature; }; /** @@ -539,8 +525,8 @@ export class FeatureProvider extends Provider { * @param feature - Object literal containing "id" property. * @returns the {@link Feature} if it is found, otherwise undefined */ - exists(feature: { id: number | string }): Feature { - return this.fStore.get(feature.id)?.feature; + exists(feature: { id: number | string }): { feature?: Feature } { + return this.fReg.get(feature.id); // ?.feature; }; @@ -639,7 +625,7 @@ export class FeatureProvider extends Provider { this.cnt--; - this.fStore.delete(feature.id); + this.fReg.delete(feature.id); this.tree?.remove(feature); @@ -914,20 +900,18 @@ export class FeatureProvider extends Provider { } else if (arguments.length == 0) { // full wipe provider.tree?.clear(); - const featuresInfo = Array.from(provider.fStore); - provider.fStore.clear(); - - for (const [id, featureInfo] of featuresInfo) { - const feature = featureInfo.feature; + const featuresInfo = provider.fReg.toArray(); + provider.fReg.clear(); + for (const feature of featuresInfo) { if (!provider.isDroppable(feature)) { - provider.fStore.set(id, new FeatureStorageInfo(feature)); + provider.fReg.set(feature.id, new FeatureRegistryInfo(feature)); provider.tree?.insert(feature); } } - provider.cnt = provider.fStore.size; + provider.cnt = provider.fReg.size(); // Provider clears complete tile storage Provider.prototype.clear.call(this, bbox); @@ -949,7 +933,7 @@ export class FeatureProvider extends Provider { if (!filter || filter(feature)) { // filter out the duplicates!! if ( - !this.fStore.has(id) + !this.fReg.has(id) ) { // not in tree already?? this.cnt++; @@ -963,7 +947,7 @@ export class FeatureProvider extends Provider { this.updateBBox(feature); - this.fStore.set(id, new FeatureStorageInfo(feature as Feature)); + this.fReg.set(String(id), new FeatureRegistryInfo(feature as Feature)); inserted = feature; } @@ -974,7 +958,7 @@ export class FeatureProvider extends Provider { _mark(o, tile: Tile) { - this.fStore.get(o.id)?.tiles.add(tile.quadkey); + this.fReg.get(o.id)?.tiles.add(tile.quadkey); }; @@ -995,7 +979,7 @@ export class FeatureProvider extends Provider { _dropFeature(feature: Feature, qk: string, trigger?: boolean) { const provider = this; - const featureStoreInfo = provider.fStore.get(feature.id); + const featureStoreInfo = provider.fReg.get(feature.id); if (featureStoreInfo) { const tiles = featureStoreInfo.tiles; @@ -1004,7 +988,7 @@ export class FeatureProvider extends Provider { if (provider.isDroppable(feature)) { if (!tiles.size) { provider.cnt--; - provider.fStore.delete(feature.id); + provider.fReg.delete(feature.id); provider.tree?.remove(feature); diff --git a/packages/core/src/providers/FeatureRegistry.ts b/packages/core/src/providers/FeatureRegistry.ts new file mode 100644 index 000000000..ee9177801 --- /dev/null +++ b/packages/core/src/providers/FeatureRegistry.ts @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2019-2023 HERE Europe B.V. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * License-Filename: LICENSE + */ + +import {Feature} from '../features/Feature'; + + +export class FeatureRegistryInfo { + feature: Feature; + tiles: Set; + + constructor(feature: Feature) { + this.feature = feature; + this.tiles = new Set(); + } +} + +export class FeatureRegistry { + private _map: Map = new Map(); + + has(id: string | number): boolean { + return this._map.has(String(id)); + } + + get(id: number | string): FeatureRegistryInfo { + return this._map.get(String(id)); + } + + set(id: string | number, featureStorageInfo: FeatureRegistryInfo) { + this._map.set(String(id), featureStorageInfo); + } + + delete(id: string | number) { + this._map.delete(String(id)); + } + + toArray(): FeatureRegistryInfo['feature'][] { + const array = new Array(this._map.size); + let i = 0; + this._map.forEach((f) => array[i++] = f.feature); + return array; + } + + size(): number { + return this._map.size; + } + + clear() { + this._map.clear(); + } +}