From fb1d4ae8a65cd9958e41c10fad3287f912e59c11 Mon Sep 17 00:00:00 2001 From: "stuart.woodman" Date: Thu, 26 Sep 2024 13:49:52 +1000 Subject: [PATCH] Any layer that has no supported resource but does have a defined bbox can now be added to the map. Replaces existing cswrenderer functionality. --- .../lib/service/cesium-map/cs-map.service.ts | 84 ++++++++----------- .../src/lib/service/wcsw/cs-csw.service.ts | 18 ++-- .../src/lib/service/wms/cs-wms.service.ts | 4 +- .../src/lib/utility/utilities.service.ts | 69 ++++++++++++++- 4 files changed, 108 insertions(+), 67 deletions(-) diff --git a/projects/portal-core-ui/src/lib/service/cesium-map/cs-map.service.ts b/projects/portal-core-ui/src/lib/service/cesium-map/cs-map.service.ts index f504494..79ead6b 100644 --- a/projects/portal-core-ui/src/lib/service/cesium-map/cs-map.service.ts +++ b/projects/portal-core-ui/src/lib/service/cesium-map/cs-map.service.ts @@ -15,7 +15,7 @@ import { CsKMLService } from '../kml/cs-kml.service'; import { CsVMFService } from '../vmf/cs-vmf.service'; import { MapsManagerService, RectangleEditorObservable, EventRegistrationInput, CesiumEvent, EventResult } from '@auscope/angular-cesium'; import { Entity, ProviderViewModel, buildModuleUrl, OpenStreetMapImageryProvider, BingMapsStyle, BingMapsImageryProvider, - ArcGisMapServerImageryProvider, TileMapServiceImageryProvider, Cartesian2, WebMercatorProjection, SplitDirection } from 'cesium'; + ArcGisMapServerImageryProvider, Cartesian2, WebMercatorProjection, SplitDirection } from 'cesium'; import { UtilitiesService } from '../../utility/utilities.service'; import ImageryLayerCollection from 'cesium/Source/Scene/ImageryLayerCollection'; declare var Cesium: any; @@ -53,7 +53,7 @@ export class CsMapService { event: CesiumEvent.LEFT_CLICK }; const mapEventManager = this.mapsManagerService.getMap().getMapEventsManager(); - const clickEvent = mapEventManager.register(eventRegistration).subscribe((result) => { + mapEventManager.register(eventRegistration).subscribe((result) => { this.mapClickHandler(result); }); } @@ -100,7 +100,6 @@ export class CsMapService { */ public mapClickHandler(eventResult: EventResult) { try { - const me = this; // Filter out drag event if (!eventResult.movement || Math.abs(eventResult.movement.startPosition.x - eventResult.movement.endPosition.x) > 2 || @@ -133,7 +132,8 @@ export class CsMapService { // tslint:disable-next-line:forin for (const layerModel of this.layerModelList) { if (!UtilitiesService.layerContainsResourceType(layerModel, ResourceType.WMS) && - !UtilitiesService.layerContainsResourceType(layerModel, ResourceType.WWW)) { + !UtilitiesService.layerContainsResourceType(layerModel, ResourceType.WWW) && + !UtilitiesService.layerContainsBboxGeographicElement(layerModel)) { continue; } const cswRecords = layerModel.cswRecords; @@ -190,32 +190,6 @@ export class CsMapService { } } - /** - * Get a list of current map supported OnlineResource types. - * Excludes config CSW renderer list. - * @returns a list of supported OnlineResource types as strings - */ - public getSupportedOnlineResourceTypes(): ResourceType[] { - return [ResourceType.WMS, ResourceType.IRIS, ResourceType.KML, ResourceType.KMZ, ResourceType.VMF]; - } - - /** - * Check if a layer is supported to be added to the map - * @param layer layer to be added to map - * @returns true if layer is supported, false otherwise - */ - public isMapSupportedLayer(layer: LayerModel): boolean { - if (this.conf.cswrenderer && this.conf.cswrenderer.includes(layer.id)) { - return true; - } - for (const resourceType of this.getSupportedOnlineResourceTypes()) { - if (UtilitiesService.layerContainsResourceType(layer, resourceType)) { - return true; - } - } - return false; - } - /** * Updates this service's layer models with new filter values so they can be displayed * @@ -224,7 +198,7 @@ export class CsMapService { */ public updateFilterDisplay(layerId: string, optionalFilters) { const layer = this.getLayerModel(layerId); - if (layer && layer.filterCollection) { + if (layer?.filterCollection) { // Optional filters for (const layerFilt of layer.filterCollection.optionalFilters) { for (const optFilt of optionalFilters) { @@ -255,11 +229,7 @@ export class CsMapService { this.removeLayer(layer); } // Add layer depending on type - if (this.conf.cswrenderer && this.conf.cswrenderer.includes(layer.id)) { - // Add a CSW layer to map - this.csCSWService.addLayer(layer, param); - this.cacheLayerModelList(layer); - } else if (UtilitiesService.layerContainsResourceType(layer, ResourceType.WMS)) { + if (UtilitiesService.layerContainsResourceType(layer, ResourceType.WMS)) { // Add a WMS layer to map this.csWMSService.addLayer(layer, param); this.cacheLayerModelList(layer); @@ -279,16 +249,28 @@ export class CsMapService { // Add a KML layer to map this.csKMLService.addLayer(layer, param); this.cacheLayerModelList(layer); - } else if (UtilitiesService.layerContainsResourceType(layer, ResourceType.WFS)) { + } + // Stu: be sure to leave whole blocks commented out until implemented or records with these resources will + // fire before hitting the catch-all CSW element below which should always remain the last in the chain + /* + else if (UtilitiesService.layerContainsResourceType(layer, ResourceType.WFS)) { // Add a WFS layer to map // FIXME this.csWFSService.addLayer(layer, param); // FIXME this.layerModelList[layer.id] = layer; // TODO: Add to getSupportedOnlineResourceTypes() when supported - } else if (UtilitiesService.layerContainsResourceType(layer, ResourceType.WWW)) { + } + */ + /* + else if (UtilitiesService.layerContainsResourceType(layer, ResourceType.WWW)) { // Add a WWW layer to map // FIXME this.csWWWService.addLayer(layer, param); // FIXME this.layerModelList[layer.id] = layer; // TODO: Add to getSupportedOnlineResourceTypes() when supported + } + */ + else if(UtilitiesService.layerContainsBboxGeographicElement(layer)) { + this.csCSWService.addLayer(layer); + this.cacheLayerModelList(layer); } else { throw new Error('No Suitable service found'); } @@ -321,7 +303,7 @@ export class CsMapService { * Add layer to the map. taking a short cut by wrapping the csw in a layerModel * @param layer the layer to add to the map */ - public addCSWRecord(cswRecord: CSWRecordModel): void { + public addCSWRecord(cswRecord: CSWRecordModel): void { const itemLayer = new LayerModel(); itemLayer.cswRecords = [cswRecord]; itemLayer['expanded'] = false; @@ -336,7 +318,7 @@ export class CsMapService { } catch (error) { throw error; } - } + } /** * Remove layer from map @@ -345,8 +327,8 @@ export class CsMapService { public removeLayer(layer: LayerModel): void { this.csMapObject.removeLayerById(layer.id); this.manageStateService.removeLayer(layer.id); - if (this.conf.cswrenderer && this.conf.cswrenderer.includes(layer.id)) { - this.csCSWService.rmLayer(layer); + if (UtilitiesService.layerContainsResourceType(layer, ResourceType.WMS)) { + this.csWMSService.rmLayer(layer); } else if (UtilitiesService.layerContainsResourceType(layer, ResourceType.IRIS)) { this.csIrisService.rmLayer(layer); } else if (UtilitiesService.layerContainsResourceType(layer, ResourceType.VMF)) { @@ -355,8 +337,8 @@ export class CsMapService { this.csKMLService.rmLayer(layer); } else if (UtilitiesService.layerContainsResourceType(layer, ResourceType.KMZ)) { this.csKMLService.rmLayer(layer); - } else { - this.csWMSService.rmLayer(layer); + } else if (UtilitiesService.layerContainsBboxGeographicElement(layer)) { + this.csCSWService.rmLayer(layer); } this.layerModelList = this.layerModelList.filter(l => l.id !== layer.id); } @@ -411,25 +393,25 @@ export class CsMapService { */ public setLayerOpacity(layer: LayerModel, opacity: number) { if (this.layerExists(layer.id)) { - if (this.conf.cswrenderer && this.conf.cswrenderer.includes(layer.id)) { - this.csCSWService.setOpacity(layer, opacity); - } else { - this.csWMSService.setOpacity(layer, opacity); + if (UtilitiesService.layerContainsResourceType(layer, ResourceType.WMS)) { + this.csWMSService.setLayerOpacity(layer, opacity); + } else if (UtilitiesService.layerContainsBboxGeographicElement(layer)) { + this.csCSWService.setLayerOpacity(layer, opacity); } } } /** * Test whether a layer supports opacity, currently we only support WMS and - * anything in the cswrenderer list + * anything added as a CSW bbox * * @param layer the layer * @returns true if a layer supports opacity, false otherwise */ public layerHasOpacity(layer: LayerModel): boolean { if (this.layerExists(layer.id)) { - if ((this.conf.cswrenderer && this.conf.cswrenderer.includes(layer.id)) || - UtilitiesService.layerContainsResourceType(layer, ResourceType.WMS)) { + if (UtilitiesService.layerContainsResourceType(layer, ResourceType.WMS) || + UtilitiesService.layerContainsBboxGeographicElement(layer)) { return true; } } diff --git a/projects/portal-core-ui/src/lib/service/wcsw/cs-csw.service.ts b/projects/portal-core-ui/src/lib/service/wcsw/cs-csw.service.ts index f5b5545..45fd214 100644 --- a/projects/portal-core-ui/src/lib/service/wcsw/cs-csw.service.ts +++ b/projects/portal-core-ui/src/lib/service/wcsw/cs-csw.service.ts @@ -1,4 +1,3 @@ - import { Injectable, Inject } from '@angular/core'; import { LayerModel } from '../../model/data/layer.model'; import { OnlineResourceModel } from '../../model/data/onlineresource.model'; @@ -29,7 +28,6 @@ export class CsCSWService { private map: AcMapComponent = null; private viewer: any = null; - private opacity: number = 1.0; constructor(private layerHandlerService: LayerHandlerService, @@ -56,15 +54,14 @@ export class CsCSWService { } /** - * setOpacity - sets opacity - * @param layer + * setLayerOpacity - sets opacity for a given layer + * @param layer the LayerModel * @param opacity value from 0.0 to 1.0 */ - public setOpacity(layer, opacity: number) { + public setLayerOpacity(layer, opacity: number) { for (const entity of layer.csLayers) { if (entity.rectangle) { - entity.rectangle.material = new ColorMaterialProperty(Color.fromAlpha(POLYGON_COLOUR, POLYGON_ALPHA*opacity)); - this.opacity = opacity; + entity.rectangle.material = new ColorMaterialProperty(Color.fromAlpha(POLYGON_COLOUR, POLYGON_ALPHA * opacity)); } else if (entity.label) { entity.label.fillColor = Color.fromAlpha(FONT_COLOUR, opacity); } @@ -89,7 +86,6 @@ export class CsCSWService { distanceDisplayCondition: new DistanceDisplayCondition(0.0, 7000000.0), // Randomize position to reduce chance of 2 labels overwriting each other pixelOffset: new Cartesian2(5, 20 + Math.floor(Math.random()*10)*20) - } }); } @@ -100,7 +96,6 @@ export class CsCSWService { * @param bbox - bounding box object; members: westBoundLongitude, southBoundLatitude, eastBoundLongitude, northBoundLatitude */ private addPolygon(name, bbox): Entity { - const me = this; return this.viewer.entities.add({ name: name, rectangle: { @@ -112,7 +107,7 @@ export class CsCSWService { ), // 'CallBackProperty' is used to avoid flickering when material colour is changed material: new ColorMaterialProperty(new CallbackProperty(function(time, result) { - return Color.fromAlpha(POLYGON_COLOUR, POLYGON_ALPHA*me.opacity); + return Color.fromAlpha(POLYGON_COLOUR, POLYGON_ALPHA); }, true)) }, }); @@ -121,9 +116,8 @@ export class CsCSWService { /** * Add the CSW layer * @param layer the layer to add to the map - * @param param the WFS layer to be added to the map */ - public addLayer(layer: LayerModel, param?: any): void { + public addLayer(layer: LayerModel): void { const cswRecords = this.layerHandlerService.getCSWRecord(layer); this.map = this.mapsManagerService.getMap(); this.viewer = this.map.getCesiumViewer(); diff --git a/projects/portal-core-ui/src/lib/service/wms/cs-wms.service.ts b/projects/portal-core-ui/src/lib/service/wms/cs-wms.service.ts index bd3a21b..e1264c5 100644 --- a/projects/portal-core-ui/src/lib/service/wms/cs-wms.service.ts +++ b/projects/portal-core-ui/src/lib/service/wms/cs-wms.service.ts @@ -302,10 +302,10 @@ export class CsWMSService { /** * Set layer opacity - * @method setOpacity + * @method setLayerOpacity * @param layer layer whose opacity is to be changed */ - public setOpacity(layer: LayerModel, opacity: number) { + public setLayerOpacity(layer: LayerModel, opacity: number) { for (const imgLayer of layer.csLayers) { imgLayer.alpha = opacity; } diff --git a/projects/portal-core-ui/src/lib/utility/utilities.service.ts b/projects/portal-core-ui/src/lib/utility/utilities.service.ts index 2759ad6..f54f97b 100644 --- a/projects/portal-core-ui/src/lib/utility/utilities.service.ts +++ b/projects/portal-core-ui/src/lib/utility/utilities.service.ts @@ -628,9 +628,9 @@ export class UtilitiesService { * @returns true if a layer contains a resource of type resourceType, false otherwise */ public static layerContainsResourceType(layer: LayerModel, resourceType: ResourceType): boolean { - if (layer.cswRecords && layer.cswRecords.length > 0) { + if (layer.cswRecords?.length > 0) { for (const record of layer.cswRecords) { - if (record.onlineResources && record.onlineResources.length > 0) { + if (record.onlineResources?.length > 0) { if (record.onlineResources.find(r => r.type === resourceType)) { return true; } @@ -640,6 +640,71 @@ export class UtilitiesService { return false; } + /** + * Get a list of current map supported OnlineResource types + * + * @returns a list of supported OnlineResource types as strings + */ + public static getSupportedOnlineResourceTypes(): ResourceType[] { + return [ResourceType.WMS, ResourceType.IRIS, ResourceType.KML, ResourceType.KMZ, ResourceType.VMF]; + } + + /** + * Check is a layer has a supported OnlineResource type + * + * @param layer the LayerModel + * @returns true if the layer contains an OnlineResource of one of the supported types, false otherwise + */ + public static getLayerHasSupportedOnlineResourceType(layer: LayerModel): boolean { + for (const resourceType of this.getSupportedOnlineResourceTypes()) { + if (UtilitiesService.layerContainsResourceType(layer, resourceType)) { + return true; + } + } + return false; + } + + /** + * Check if a layer is supported to be added to the map + * + * @param layer layer to be added to map + * @returns true if layer is supported, false otherwise + */ + public static isMapSupportedLayer(layer: LayerModel): boolean { + // Addable if one of supported resource types + if (this.getLayerHasSupportedOnlineResourceType(layer)) { + return true; + } + // Addable if layer's CSWRecords have at leasr one bbox geographic element + if (UtilitiesService.layerContainsBboxGeographicElement(layer)) { + return true; + } + return false; + } + + /** + * Find whether a layer contains a valid bbox geographic element + * + * @param layer the LayerModel + * @returns true if a layer's CSWRecord(s) contains at least one valid bbox geographic element + */ + public static layerContainsBboxGeographicElement(layer: LayerModel): boolean { + if (layer.cswRecords?.length > 0) { + for (const record of layer.cswRecords) { + if (record.geographicElements?.length > 0) { + for (const geoElement of record.geographicElements) { + if (geoElement.type && geoElement.type === 'bbox' && + geoElement.northBoundLatitude && geoElement.eastBoundLongitude && + geoElement.southBoundLatitude && geoElement.westBoundLongitude) { + return true; + } + } + } + } + } + return false; + } + /** * Retrieve all resources of a given type for a given layer *