diff --git a/projects/nshmp-apps/src/app/ncm/geophysical-profiles/services/app.service.ts b/projects/nshmp-apps/src/app/ncm/geophysical-profiles/services/app.service.ts index 49b54d1fbd09afcfdd0e3e8546d466299e9b2260..cc022de3656ee09fb05ae228149460bf1af6d1ec 100644 --- a/projects/nshmp-apps/src/app/ncm/geophysical-profiles/services/app.service.ts +++ b/projects/nshmp-apps/src/app/ncm/geophysical-profiles/services/app.service.ts @@ -1,6 +1,7 @@ import {HttpParams} from '@angular/common/http'; import {computed, Injectable, Signal, signal} from '@angular/core'; import {FormBuilder} from '@angular/forms'; +import {ActivatedRoute, Router} from '@angular/router'; import { FormGroupControls, NshmpService, @@ -23,12 +24,23 @@ import {PlotData} from 'plotly.js'; import {environment} from 'projects/nshmp-apps/src/environments/environment'; import {AppServiceModel} from 'projects/nshmp-apps/src/shared/models/app-service.model'; import {SharedService} from 'projects/nshmp-apps/src/shared/services/shared.service'; +import {apps} from 'projects/nshmp-apps/src/shared/utils/applications.utils'; import {catchError} from 'rxjs'; import {ControlForm} from '../models/control-form.model'; import {Plots} from '../models/plots.model'; import {AppState} from '../models/state.model'; +/** + * URL query parameters + */ +interface Query { + depthInc?: number; + depthMax?: number; + depthMin?: number; + location?: string | string[]; +} + /** * NCM geophysical profiles application service. */ @@ -54,7 +66,9 @@ export class AppService constructor( private formBuilder: FormBuilder, private spinnerService: SpinnerService, - private nshmpService: NshmpService + private nshmpService: NshmpService, + private route: ActivatedRoute, + private router: Router ) { super(); @@ -225,6 +239,8 @@ export class AppService }, usageResponse, }); + + this.initialFormSet(); }); } @@ -336,6 +352,42 @@ export class AppService }; } + /** + * Initial form set from query parameters. + */ + private initialFormSet(): void { + const query = this.route.snapshot.queryParams as Query; + const locations: Location[] = []; + + if (query.location) { + if (Array.isArray(query.location)) { + locations.push(...query.location.map(loc => this.queryToLocation(loc))); + } else { + locations.push(this.queryToLocation(query.location)); + } + } + + locations.slice(0, -1).forEach(() => { + this.addLocationForm(); + }); + + const defaultValues = this.defaultFormValues(); + + this.formGroup.patchValue({ + depthInc: query.depthInc ?? defaultValues.depthInc, + depthMax: query.depthMax ?? defaultValues.depthMax, + depthMin: query.depthMin ?? defaultValues.depthMin, + locations, + }); + + if (this.formGroup.valid) { + this.callService(); + } else { + this.formGroup.markAsDirty(); + } + this.formGroup.valueChanges.subscribe(() => this.updateUrl()); + } + /** * Returns a new location form group for the form array. */ @@ -353,6 +405,21 @@ export class AppService return form; } + /** + * Convert string comma delimited latitude and longitude into Location. + * + * @param location The comma delimited location: "latitude, longitude" + * @returns + */ + private queryToLocation(location: string): Location { + const [latitude, longitude] = location.split(','); + + return { + latitude: Number.parseFloat(latitude), + longitude: Number.parseFloat(longitude), + }; + } + /** * Transform the service response to plots. */ @@ -450,4 +517,26 @@ export class AppService }, }; } + + /** + * Update URL query based on control panel change. + */ + private updateUrl(): void { + const values = this.formGroup.getRawValue(); + + const location = this.formGroup.controls.locations.controls + .map(control => control.getRawValue()) + .map(value => `${value.latitude},${value.longitude}`); + + this.router + .navigate([apps().ncm.geophysicalProfiles.routerLink], { + queryParams: { + depthInc: values.depthInc, + depthMax: values.depthMax, + depthMin: values.depthMin, + location, + }, + }) + .catch((error: Error) => this.nshmpService.throwError$(error)); + } }