From 565a79b74266e6a99a6ebacd1597903bf359016d Mon Sep 17 00:00:00 2001 From: Lingbo Jiang Date: Tue, 2 Jul 2024 16:38:07 +1000 Subject: [PATCH 1/5] Release-6.5.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1801376b..4bf807c2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "auscope-portal", - "version": "6.6.0", + "version": "6.5.2", "license": "MIT", "scripts": { "ng": "ng", From 20cad1ea6d282f9bca0f9e522a5dd389ea6c4a18 Mon Sep 17 00:00:00 2001 From: "stuart.woodman" Date: Wed, 17 Jul 2024 15:21:09 +1000 Subject: [PATCH 2/5] Fix custom layers panel. Fix issue with search results panel being opened when custom layers panel is open. --- src/app/app.module.ts | 2 - .../custompanel/custompanel.component.html | 44 ++++++- .../custompanel/custompanel.component.scss | 19 +++ .../custompanel/custompanel.component.ts | 116 +++++++++++------- .../custompanel/layergroup.component.html | 64 ---------- .../custompanel/layergroup.component.ts | 57 --------- .../menupanel/search/searchpanel.component.ts | 11 +- src/app/services/ui/uilayer-model.service.ts | 10 ++ 8 files changed, 152 insertions(+), 171 deletions(-) create mode 100644 src/app/menupanel/custompanel/custompanel.component.scss delete mode 100644 src/app/menupanel/custompanel/layergroup.component.html delete mode 100644 src/app/menupanel/custompanel/layergroup.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index aecb9c3d..69e98f88 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -119,7 +119,6 @@ import { AppRoutingModule } from './app-routing.module'; import { UserStateService } from './services/user/user-state.service'; import { AuthGuard } from './services/auth/auth.guard'; import { AuthService } from './services/auth/auth.service'; -import { LayerGroupComponent } from './menupanel/custompanel/layergroup.component'; import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { AuthErrorHandlerInterceptor } from './interceptors/auth-error.interceptor'; import { ROIModule } from './modalwindow/roi/roi.modal.modules'; @@ -139,7 +138,6 @@ PlotlyModule.plotlyjs = PlotlyJS; CesiumMapPreviewComponent, BrowsePanelComponent, CustomPanelComponent, - LayerGroupComponent, ActiveLayersPanelComponent, FilterPanelComponent, SearchPanelComponent, diff --git a/src/app/menupanel/custompanel/custompanel.component.html b/src/app/menupanel/custompanel/custompanel.component.html index fba30660..a288740a 100644 --- a/src/app/menupanel/custompanel/custompanel.component.html +++ b/src/app/menupanel/custompanel/custompanel.component.html @@ -14,7 +14,27 @@ - + + + + + + +
+
+
{{layer.name}}
+ + +
+
+ + + +
@@ -30,4 +50,24 @@
- + + + + + + +
+
+
{{layer.name}}
+ + +
+
+ + + +
\ No newline at end of file diff --git a/src/app/menupanel/custompanel/custompanel.component.scss b/src/app/menupanel/custompanel/custompanel.component.scss new file mode 100644 index 00000000..6e0a172d --- /dev/null +++ b/src/app/menupanel/custompanel/custompanel.component.scss @@ -0,0 +1,19 @@ +.custom-table { + table-layout: fixed; + margin-bottom: 5px; + width: 100%; + + .custom-result-row { + vertical-align: baseline; + + .text-truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .custom-btn { + line-height: 0.8em; + } + } +} \ No newline at end of file diff --git a/src/app/menupanel/custompanel/custompanel.component.ts b/src/app/menupanel/custompanel/custompanel.component.ts index da720edb..d6e06b9f 100644 --- a/src/app/menupanel/custompanel/custompanel.component.ts +++ b/src/app/menupanel/custompanel/custompanel.component.ts @@ -1,27 +1,24 @@ import { Component, Output, Inject, EventEmitter } from '@angular/core'; import { LayerHandlerService, LayerModel, RenderStatusService, KMLDocService, ResourceType, - Constants } from '@auscope/portal-core-ui'; -import { NgbdModalStatusReportComponent } from '../../toppanel/renderstatus/renderstatus.component'; -import { BsModalService } from 'ngx-bootstrap/modal'; -import { BsModalRef } from 'ngx-bootstrap/modal'; + Constants, CsMapService} from '@auscope/portal-core-ui'; import { UILayerModel } from '../common/model/ui/uilayer.model'; import { UILayerModelService } from 'app/services/ui/uilayer-model.service'; -import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import * as JSZip from 'jszip'; import { HttpClient } from '@angular/common/http'; import { throwError as observableThrowError, Observable } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; import { HttpResponse } from '@angular/common/http'; +import { LayerManagerService } from 'app/services/ui/layer-manager.service'; +import { SidebarService } from 'app/portal/sidebar.service'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { InfoPanelComponent } from '../common/infopanel/infopanel.component'; -type LayerGroups = { 'Results': LayerModel[] }; @Component({ selector: '[appCustomPanel]', templateUrl: './custompanel.component.html', - styleUrls: ['../menupanel.scss'] + styleUrls: ['../menupanel.scss', './custompanel.component.scss'] }) - - export class CustomPanelComponent { // URL that the user types in @@ -34,21 +31,22 @@ export class CustomPanelComponent { statusMsg: string; // Displays custom layers for URLs in sidebar - urlLayerGroups: LayerGroups = { 'Results': [] }; + urlLayers: LayerModel[] = []; // Displays custom layers for KML file in sidebar - fileLayerGroups: LayerGroups = { 'Results': [] }; + fileLayers: LayerModel[] = []; - bsModalRef: BsModalRef; @Output() expanded: EventEmitter = new EventEmitter(); constructor(private http: HttpClient, private layerHandlerService: LayerHandlerService, + private layerManagerService: LayerManagerService, private renderStatusService: RenderStatusService, - private modalService: BsModalService, private uiLayerModelService: UILayerModelService, - public activeModalService: NgbModal, private kmlService: KMLDocService, + private sidebarService: SidebarService, + private csMapService: CsMapService, + public activeModalService: NgbModal, @Inject('env') private env ) { this.loading = false; @@ -56,13 +54,12 @@ export class CustomPanelComponent { } /** - * Makes a filter or download tab panel visible - * - * @param layerId layer id string - * @param panelType panel type string, either 'filterpanel' or 'downloadpanel' + * Get the UILayerModel for the layer + * @param layerId ID of layer + * @returns UILayerModel for layer */ - public selectTabPanel(layerId: string, panelType: string) { - this.uiLayerModelService.getUILayerModel(layerId).tabpanel.setPanelOpen(panelType); + public getUILayerModel(layerId: string): UILayerModel { + return this.uiLayerModelService.getUILayerModel(layerId); } /** @@ -87,7 +84,7 @@ export class CustomPanelComponent { this.statusMsg = ''; // Clear the results from the previous search, start the loading spinner - this.urlLayerGroups = { 'Results': [] }; + this.urlLayers = []; this.loading = true; // Check for empty URL @@ -118,16 +115,16 @@ export class CustomPanelComponent { const proxyUrl = this.env.portalBaseUrl + Constants.PROXY_API + "?usewhitelist=false&url=" + searchUrl; this.getGoogleMapDoc(proxyUrl).subscribe(response => { - let kml = response; + const kml = response; const reader = new FileReader(); // This fires after the blob has been read/loaded. reader.addEventListener('loadend', (e) => { - var kmlTxt = e.target.result; + const kmlTxt = e.target.result; // Remove unwanted characters and inject proxy for embedded URLs - let kmlStr = this.kmlService.cleanKML(kmlTxt.toString()); + const kmlStr = this.kmlService.cleanKML(kmlTxt.toString()); const parser = new DOMParser(); let kmlDoc = parser.parseFromString(kmlStr, "text/xml"); @@ -140,10 +137,8 @@ export class CustomPanelComponent { // Start reading the blob as text. reader.readAsText(kml); - }); - } else { // If KMZ URL ... if (searchUrl.toLowerCase().endsWith('.kmz')) { @@ -173,16 +168,16 @@ export class CustomPanelComponent { // This fires after the blob has been read/loaded. reader.addEventListener('loadend', (e) => { - var kmzTxt = e.target.result; + const kmzTxt = e.target.result; let getDom = xml => (new DOMParser()).parseFromString(xml, "text/xml") const getExtension = fileName => fileName.split(".").pop().toLowerCase(); // unzip the kmz and iterate through the files - var zipKMZ = new JSZip(); // reassemble the kmz (files) in this object + const zipKMZ = new JSZip(); // reassemble the kmz (files) in this object let getKmzDom = (kmzDoc) => { - var zip = new JSZip() + const zip = new JSZip() return zip.loadAsync(kmzDoc) .then(zip => { let kmlDom = null @@ -192,7 +187,7 @@ export class CustomPanelComponent { kmlDom = file.async("string").then(x => { // Remove unwanted characters and inject proxy for embedded URLs - let kmlStr = this.kmlService.cleanKMZ(x); + const kmlStr = this.kmlService.cleanKMZ(x); const parser = new DOMParser(); let kmlDoc = parser.parseFromString(kmlStr, "text/xml"); @@ -208,24 +203,20 @@ export class CustomPanelComponent { //zipKMZ.file(relPath, kmlStr); zipKMZ.file(relPath, xmlStr); }) - } else { // add the file (non kml) into the zip file.async("blob").then(x => { zipKMZ.file(relPath, x); }); } - //}) }) - return kmlDom || Promise.reject("No kmz file found") - }).catch(function (err) { return console.log("ERROR [unzipping kmz]: " + err.msg + JSON.stringify(err)); }) }; - getKmzDom(kmzTxt).then(kmzDom => { + getKmzDom(kmzTxt).then(() => { let me = this; @@ -264,7 +255,7 @@ export class CustomPanelComponent { // Evaluate the layers and if found set up loadable map layers for (const layerRec of layerRecs) { // Make the layer group listing visible in the UI - this.urlLayerGroups['Results'].unshift(layerRec); + this.urlLayers.unshift(layerRec); // Configure layers so they can be added to map const uiLayerModel = new UILayerModel(layerRec.id, this.renderStatusService.getStatusBSubject(layerRec)); this.uiLayerModelService.setUILayerModel(layerRec.id, uiLayerModel); @@ -293,12 +284,14 @@ export class CustomPanelComponent { * * @param uiLayerModel ui layer model object whose status will be displayed */ + /* public openStatusReport(uiLayerModel: UILayerModel) { this.bsModalRef = this.modalService.show(NgbdModalStatusReportComponent, { class: 'modal-lg' }); uiLayerModel.statusMap.getStatusBSubject().subscribe((value) => { this.bsModalRef.content.resourceMap = value.resourceMap; }); } + */ /** * adds support so that kmlFeatureDatasupport will display a features attributes when they @@ -376,7 +369,7 @@ export class CustomPanelComponent { * @returns true if the layer is found within recordsList, false otherwise */ private recordsListContainsRecord(recordsList: any, name: string, url: string): boolean { - if (recordsList['Results'].findIndex(x => x.cswRecords[0].name === name && x.cswRecords[0].onlineResources[0].url === url) != -1) { + if (recordsList.findIndex(x => x.cswRecords[0].name === name && x.cswRecords[0].onlineResources[0].url === url) != -1) { return true; } return false; @@ -392,17 +385,19 @@ export class CustomPanelComponent { // Make a layer model object if (docType == ResourceType.KMZ) { layerRec = me.layerHandlerService.makeCustomKMZLayerRecord(name, proxyUrl, kmzData); + layerRec.group = 'kmz-layer'; } else { layerRec = me.layerHandlerService.makeCustomKMLLayerRecord(name, proxyUrl, kmzData); + layerRec.group = 'kml-layer'; } // Configure layers so it can be added to map const uiLayerModel = new UILayerModel(layerRec.id, me.renderStatusService.getStatusBSubject(layerRec)); me.uiLayerModelService.setUILayerModel(layerRec.id, uiLayerModel); // Make the layer group listing visible in the UI - if (sourceType == "URL" && !this.recordsListContainsRecord(me.urlLayerGroups, name, proxyUrl)) { - me.urlLayerGroups['Results'].unshift(layerRec); - } else if (!this.recordsListContainsRecord(me.fileLayerGroups, name, proxyUrl)) { - me.fileLayerGroups['Results'].unshift(layerRec); + if (sourceType == "URL" && !this.recordsListContainsRecord(me.urlLayers, name, proxyUrl)) { + me.urlLayers.unshift(layerRec); + } else if (!this.recordsListContainsRecord(me.fileLayers, name, proxyUrl)) { + me.fileLayers.unshift(layerRec); } } @@ -492,4 +487,43 @@ export class CustomPanelComponent { } } } + + /** + * Add a KML layer to the map + * + * @param layer the KML LayerModel + */ + public addLayer(layer: LayerModel) { + this.layerManagerService.addLayer(layer, [], null, null); + this.sidebarService.setOpenState(true); + } + + /** + * Remove a KML layer from the map. + * + * @param layer the KML LayerModel + */ + public removeLayer(layer: LayerModel) { + this.layerManagerService.removeLayer(layer); + if (this.csMapService.getLayerModelList()?.length === 0) { + this.sidebarService.setOpenState(false); + } + } + + /** + * Display layer information in modal + * + * @param layer the LayerModel + */ + public displayRecordInfo(layer: LayerModel) { + if (layer) { + const modelRef = this.activeModalService.open(InfoPanelComponent, { + size: "lg", + backdrop: false + }); + modelRef.componentInstance.cswRecords = layer.cswRecords; + modelRef.componentInstance.layer = layer; + } + } + } diff --git a/src/app/menupanel/custompanel/layergroup.component.html b/src/app/menupanel/custompanel/layergroup.component.html deleted file mode 100644 index b0b171a2..00000000 --- a/src/app/menupanel/custompanel/layergroup.component.html +++ /dev/null @@ -1,64 +0,0 @@ - -
  • - - {{layerGroup.key}} - - -
  • -
    diff --git a/src/app/menupanel/custompanel/layergroup.component.ts b/src/app/menupanel/custompanel/layergroup.component.ts deleted file mode 100644 index d0908243..00000000 --- a/src/app/menupanel/custompanel/layergroup.component.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Component, Input } from '@angular/core'; -import { LayerModel } from '@auscope/portal-core-ui'; -import { UILayerModel } from '../common/model/ui/uilayer.model'; -import { UILayerModelService } from 'app/services/ui/uilayer-model.service'; -import { InfoPanelComponent } from '../common/infopanel/infopanel.component'; -import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; -import { LayerManagerService } from 'app/services/ui/layer-manager.service'; - - -@Component({ - selector: 'layer-group', - templateUrl: './layergroup.component.html', - styleUrls: ['../menupanel.scss'] -}) -export class LayerGroupComponent { - - // Contains the layers on display - @Input() layerGroups: { 'Results': LayerModel[] }; - - constructor(private uiLayerModelService: UILayerModelService, private layerManagerService: LayerManagerService, - public activeModalService: NgbModal) { - } - - /** - * Retrieve UILayerModel from the UILayerModelService - * - * @param layerId ID of layer - */ - public getUILayerModel(layerId: string): UILayerModel { - return this.uiLayerModelService.getUILayerModel(layerId); - } - - /** - * Remove a layer from the map - * - * @param layer layer to be removed - */ - public removeLayer(layer: LayerModel) { - this.layerManagerService.removeLayer(layer); - } - - /** - * Display the record information dialog - * - * @param cswRecord CSW record for information - */ - public displayRecordInformation(layer: LayerModel) { - if (layer) { - const modelRef = this.activeModalService.open(InfoPanelComponent, { - size: "lg", - backdrop: false - }); - modelRef.componentInstance.cswRecords = layer.cswRecords; - modelRef.componentInstance.layer = layer; - } - } -} diff --git a/src/app/menupanel/search/searchpanel.component.ts b/src/app/menupanel/search/searchpanel.component.ts index 3da85b00..6a53ca7b 100644 --- a/src/app/menupanel/search/searchpanel.component.ts +++ b/src/app/menupanel/search/searchpanel.component.ts @@ -217,22 +217,23 @@ export class SearchPanelComponent implements OnInit { } public setShowingResultsPanel(showingResults: boolean) { + if (showingResults && this.showingKmlOgcOptions) { + this.showingKmlOgcOptions = false; + } this.showingResultsPanel = showingResults; if (this.selectedSearchResult) { this.showingInfoPanel = showingResults; } - if (showingResults && this.showingKmlOgcOptions) { - this.showingKmlOgcOptions = false; - } } public setShowingKmlOgcOptions(showingOptions: boolean) { - this.showingKmlOgcOptions = showingOptions; - this.searching = !this.searching if (showingOptions && this.showingResultsPanel) { this.showingResultsPanel = false; this.showingInfoPanel = false; + + this.searching = !this.searching } + this.showingKmlOgcOptions = showingOptions; } /** diff --git a/src/app/services/ui/uilayer-model.service.ts b/src/app/services/ui/uilayer-model.service.ts index ab633bb5..36fbf898 100644 --- a/src/app/services/ui/uilayer-model.service.ts +++ b/src/app/services/ui/uilayer-model.service.ts @@ -17,5 +17,15 @@ export class UILayerModelService { public setUILayerModel(layerId: string, uiLayerModel: UILayerModel) { this.uiLayerModels.set(layerId, uiLayerModel); } + + /** + * Check whether layer has been added to the map + * + * @param layerId ID of the layer + * @returns true if layer has been added to the map, false otherwise + */ + isLayerAdded(layerId: string) { + return this.getUILayerModel(layerId) && this.getUILayerModel(layerId).statusMap.getRenderStarted(); + } } From 7d3b709e94b81a3e6d0021e9a4ae5f305905cb2f Mon Sep 17 00:00:00 2001 From: "stuart.woodman" Date: Wed, 17 Jul 2024 16:17:31 +1000 Subject: [PATCH 3/5] Disable search stop when custom panel opened (will need to be re-added later). --- src/app/menupanel/search/searchpanel.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/menupanel/search/searchpanel.component.ts b/src/app/menupanel/search/searchpanel.component.ts index 6a53ca7b..6de5934a 100644 --- a/src/app/menupanel/search/searchpanel.component.ts +++ b/src/app/menupanel/search/searchpanel.component.ts @@ -230,8 +230,8 @@ export class SearchPanelComponent implements OnInit { if (showingOptions && this.showingResultsPanel) { this.showingResultsPanel = false; this.showingInfoPanel = false; - - this.searching = !this.searching + // TODO: Kill searching if in the middle of one + //this.searching = !this.searching } this.showingKmlOgcOptions = showingOptions; } From 3922ed42ea6eeb656eac6b26a5d967c93094f30e Mon Sep 17 00:00:00 2001 From: "stuart.woodman" Date: Fri, 16 Aug 2024 09:02:03 +1000 Subject: [PATCH 4/5] Prevent layers with world bounds from being modified when the preview is displayed. --- .../common/infopanel/subpanel/subpanel.component.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/menupanel/common/infopanel/subpanel/subpanel.component.ts b/src/app/menupanel/common/infopanel/subpanel/subpanel.component.ts index eaf81c64..5fe8c0ee 100644 --- a/src/app/menupanel/common/infopanel/subpanel/subpanel.component.ts +++ b/src/app/menupanel/common/infopanel/subpanel/subpanel.component.ts @@ -111,8 +111,10 @@ export class InfoPanelSubComponent implements OnInit { } else if (this.layer.legendImg && this.layer.legendImg !== '') { this.legendUrl = this.env.portalBaseUrl + 'legend/' + this.layer.legendImg; } - // Gather up BBOX coordinates to calculate the centre and envelope - const bbox = this.cswRecord.geographicElements[0]; + + // Gather up BBOX coordinates to calculate the centre and envelope. Use a copy of coords so they don't stay modified for the main map + const bbox = { ...this.cswRecord.geographicElements[0] }; + // Make sure that the view is only of Australia // On most maps if we use world-wide bounds it will make the Australian features too small if (bbox.westBoundLongitude < 100) { From 24c6d3d4e597e3e67186e1efbcb807e54b953b24 Mon Sep 17 00:00:00 2001 From: "stuart.woodman" Date: Fri, 23 Aug 2024 09:19:19 +1000 Subject: [PATCH 5/5] Fix issue with Passive Seismic dataselect downloads being unavailable. --- .../downloadpanel.component.html | 32 ++++++++++--------- .../downloadpanel/downloadpanel.component.ts | 30 ++++++----------- 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/src/app/menupanel/common/downloadpanel/downloadpanel.component.html b/src/app/menupanel/common/downloadpanel/downloadpanel.component.html index 9441266d..cd68fd1b 100644 --- a/src/app/menupanel/common/downloadpanel/downloadpanel.component.html +++ b/src/app/menupanel/common/downloadpanel/downloadpanel.component.html @@ -70,11 +70,12 @@
    South: {{
    - - @@ -90,7 +91,8 @@
    South: {{
    - @@ -113,18 +115,18 @@
    South: {{
    -
    - -

    Select an area to download not exceeding {{downloadSizeLimit}} m2.

    -
    +
    + +

    Select an area to download not exceeding {{downloadSizeLimit}} m2.

    +
    -
    - -

    Click on the map to draw bounding box.

    -
    +
    + +

    Click on the map to draw bounding box.

    +
    -
    +

    Bounding Box

    @@ -166,9 +168,9 @@
    South: {{b
    - -