From ea82f02f51a860beb0fad5a9d2d1f2bb29fd9775 Mon Sep 17 00:00:00 2001 From: phil Date: Tue, 24 Dec 2024 03:33:22 +0100 Subject: [PATCH 1/4] Fix background opacity adjustment --- .../gisaf-mapbox/gisaf-mapbox.component.ts | 71 ++++++++++++------- 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/src/app/map/gisaf-mapbox/gisaf-mapbox.component.ts b/src/app/map/gisaf-mapbox/gisaf-mapbox.component.ts index 0ede25d..faddedf 100644 --- a/src/app/map/gisaf-mapbox/gisaf-mapbox.component.ts +++ b/src/app/map/gisaf-mapbox/gisaf-mapbox.component.ts @@ -197,21 +197,35 @@ export class GisafMapboxComponent implements OnInit, OnDestroy { } _getNewSingleOpacity(layerId: string, originalOpacity: number | object): number | object { - if (typeof (originalOpacity) === 'number') { + if (originalOpacity === undefined) { + return undefined + } + else if (typeof originalOpacity === 'number') { return originalOpacity * this._baseStyleOpacity } - else { - let newOpacity = {} - for (const k in originalOpacity) { - let v = originalOpacity[k] - if (k == 'stops') { - newOpacity[k] = v.map(stop => [stop[0], stop[1] * this._baseStyleOpacity]) - } - else { - newOpacity[k] = v - } + else if (typeof originalOpacity === 'object') { // Also matches array + if (originalOpacity[0] == 'interpolate') { + // Change the last interpolation point + originalOpacity[Object.values(originalOpacity).length - 1] = this._baseStyleOpacity + return originalOpacity } - return newOpacity + else { + let newOpacity = {} + for (const k in originalOpacity) { + let v = originalOpacity[k] + if (k == 'stops') { + newOpacity[k] = v.map(stop => [stop[0], stop[1] * this._baseStyleOpacity]) + } + else { + newOpacity[k] = v + } + } + return newOpacity + } + } + else { + console.log(`Cannot process opacity of layer ${layerId}, unknown type ${typeof originalOpacity}`) + return originalOpacity } } @@ -219,25 +233,30 @@ export class GisafMapboxComponent implements OnInit, OnDestroy { let originalStyle = this.originalBaseStyle.style['layers'].find( (_layer: object) => layer['id'] == _layer['id'] ) - if (!('paint' in originalStyle)) { - originalStyle['paint'] = {} - } - if (['raster', 'background', 'fill', 'line'].indexOf(layer['type']) != -1) { - let prop = layer['type'] + '-opacity' - return { - [prop]: this._getNewSingleOpacity(layer['id'], originalStyle['paint'][prop] || 1.0) - } - } - else { + let originalPaint = originalStyle['paint'] || {} + if (layer['type'] == 'symbol') { let prop1 = 'text-opacity' let prop2 = 'icon-opacity' - let newOpacity1 = this._getNewSingleOpacity(layer['id'], originalStyle['paint'][prop1] || 1.0) - let newOpacity2 = this._getNewSingleOpacity(layer['id'], originalStyle['paint'][prop2] || 1.0) + let newOpacity1 = this._getNewSingleOpacity(layer['id'], originalPaint[prop1] || 1.0) + let newOpacity2 = this._getNewSingleOpacity(layer['id'], originalPaint[prop2] || 1.0) return { [prop1]: newOpacity1, [prop2]: newOpacity2, } } + else if (layer['type'] == 'line') { + let prop = layer['type'] + '-opacity' + return { + [prop]: this._getNewSingleOpacity(layer['id'], originalPaint[prop] || 1.0) + } + } + else { + // layer['type'] in ['raster', 'background', 'fill', 'line', 'fill-extrusion'] + let prop = layer['type'] + '-opacity' + return { + [prop]: this._getNewSingleOpacity(layer['id'], originalPaint[prop] || 1.0), + } + } } applyBaseStyleOpacity() { @@ -247,7 +266,9 @@ export class GisafMapboxComponent implements OnInit, OnDestroy { continue } for (const [key, value] of Object.entries(this._getNewOpacity(bsLayer))) { - this.map.setPaintProperty(bsLayer.id, key, value) + if (value !== undefined) { + this.map.setPaintProperty(bsLayer.id, key, value) + } } } } From c890800454d1282023d4d52e1e235843b35dae61 Mon Sep 17 00:00:00 2001 From: phil Date: Tue, 24 Dec 2024 03:46:27 +0100 Subject: [PATCH 2/4] Initial README doc --- README.md | 34 +++++----------------------------- 1 file changed, 5 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index e75a7ca..3ffa8d2 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,7 @@ -# GisafApp +# Gisaf frontend -This project was generated with [angular-cli](https://github.com/angular/angular-cli) version 1.0.0-beta.24. +The web app (front-end, user interface) for Gisaf, +a web based GIS initially developed for CSR Geomatics, Auroville. -## Development server -Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. - -## Code scaffolding - -Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive/pipe/service/class/module`. - -## Build - -Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build. - -## Running unit tests - -Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). - -## Running end-to-end tests - -Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). -Before running the tests make sure you are serving the app via `ng serve`. - -## Deploying to Github Pages - -Run `ng github-pages:deploy` to deploy to Github Pages. - -## Further help - -To get more help on the `angular-cli` use `ng help` or go check out the [Angular-CLI README](https://github.com/angular/angular-cli/blob/master/README.md). +See the [Gisaf server repository](https://code.philo.ydns.eu/philorg/gisaf-server) +for information about this project. From 5ff197ad490fd1a33db3cecfa5846897fe160af8 Mon Sep 17 00:00:00 2001 From: phil Date: Tue, 24 Dec 2024 03:49:04 +0100 Subject: [PATCH 3/4] Fix link in README doc --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3ffa8d2..d743a5f 100644 --- a/README.md +++ b/README.md @@ -3,5 +3,5 @@ The web app (front-end, user interface) for Gisaf, a web based GIS initially developed for CSR Geomatics, Auroville. -See the [Gisaf server repository](https://code.philo.ydns.eu/philorg/gisaf-server) +See the [Gisaf server repository](https://code.philo.ydns.eu/philorg/gisaf-backend) for information about this project. From 4c4dc3fc5c23f5f287ad0d3e6cad336ff81a01b2 Mon Sep 17 00:00:00 2001 From: phil Date: Wed, 25 Dec 2024 17:09:41 +0100 Subject: [PATCH 4/4] Display frontend and backend version --- src/app/app.component.html | 4 +- src/app/app.component.ts | 141 ++++++++++++++++++++----------------- src/version.json | 3 + tsconfig.json | 25 +++---- 4 files changed, 93 insertions(+), 80 deletions(-) create mode 100644 src/version.json diff --git a/src/app/app.component.html b/src/app/app.component.html index e3737be..7aedc3b 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -2,7 +2,7 @@ @@ -47,4 +47,4 @@ account_circle - \ No newline at end of file + diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 1be626d..9ab6b35 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,5 +1,7 @@ -import { Component, OnInit, - ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core' +import { + Component, OnInit, + ChangeDetectionStrategy, ChangeDetectorRef +} from '@angular/core' import { Title } from '@angular/platform-browser' import { BootstrapService } from './_services/bootstrap.service' import { ConfigService } from './_services/config.service' @@ -8,80 +10,87 @@ import { MatDialog, MatDialogRef } from '@angular/material/dialog' import { AuthenticationService } from './_services/authentication.service' import { LoginDialogComponent } from './login/login.component' +import versionJson from '../version.json' + +export class Version { + public backend: string + public frontend: string +} @Component({ - selector: 'app-root', - templateUrl: './app.component.html', - styleUrls: ['./app.component.css'], - changeDetection: ChangeDetectionStrategy.OnPush, + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.css'], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class AppComponent implements OnInit { - title = 'Gisaf' - version: string + title: string = 'Gisaf' + version: Version = new Version() - routes = [ - { - 'target': 'dashboard', - 'icon': 'home', - 'text': 'Home', - }, - { - 'target': 'map', - 'icon': 'map', - 'text': 'Map', - }, - { - 'target': 'measures', - 'icon': 'insert_chart', - 'text': 'Measures', - }, - ] + routes = [ + { + 'target': 'dashboard', + 'icon': 'home', + 'text': 'Home', + }, + { + 'target': 'map', + 'icon': 'map', + 'text': 'Map', + }, + { + 'target': 'measures', + 'icon': 'insert_chart', + 'text': 'Measures', + }, + ] - constructor( - public configService: ConfigService, - private titleService: Title, - private bootstrapService: BootstrapService, - public authenticationService: AuthenticationService, - private snackBar: MatSnackBar, - private cdr: ChangeDetectorRef, - public dialogRef: MatDialogRef, - public dialog: MatDialog - ) {} + constructor( + public configService: ConfigService, + private titleService: Title, + private bootstrapService: BootstrapService, + public authenticationService: AuthenticationService, + private snackBar: MatSnackBar, + private cdr: ChangeDetectorRef, + public dialogRef: MatDialogRef, + public dialog: MatDialog + ) { } - ngOnInit() { - // Bootstrap: set app wide configuration - this.bootstrapService.get().subscribe({ - next: res => { - this.version = res.version - this.title = res.title || this.title - this.titleService.setTitle(res.windowTitle || this.title) - this.configService.setConf(res) - if (res.redirect && (window != window.top)) { - // Refusing to be embedded in an iframe - let loc = res.redirect + window.location.pathname - window.document.body.innerHTML = ` + ngOnInit() { + // Bootstrap: set app wide configuration + this.bootstrapService.get().subscribe({ + next: res => { + this.version.backend = res.version + this.version.frontend = versionJson["version"] + this.title = res.title || this.title + this.titleService.setTitle(res.windowTitle || this.title) + this.configService.setConf(res) + if (res.redirect && (window != window.top)) { + // Refusing to be embedded in an iframe + let loc = res.redirect + window.location.pathname + window.document.body.innerHTML = ` The web site you are visiting is trying to embed Gisaf (${this.title}) in an iFrame, it isn't a nice thing to do.
Please click this link to go to the real site: ${loc} ` - } - }, - error: err => { - this.snackBar.open( - 'Cannot connect to the server (' + err.statusText + '). Please retry later.', - 'OK' - ) - } - }) - } + } + }, + error: err => { + this.snackBar.open( + 'Cannot connect to the server (' + err.statusText + '). Please retry later.', + 'OK' + ) + } + }) + } - openLoginDialog() { - const dialogRef = this.dialog.open(LoginDialogComponent, { - height: '24em', - width: '21em' - }) + openLoginDialog() { + const dialogRef = this.dialog.open(LoginDialogComponent, { + height: '24em', + width: '21em' + }) - // dialogRef.afterClosed().subscribe( - // result => {} - // ) - } + // dialogRef.afterClosed().subscribe( + // result => {} + // ) + } } diff --git a/src/version.json b/src/version.json new file mode 100644 index 0000000..1be1b18 --- /dev/null +++ b/src/version.json @@ -0,0 +1,3 @@ +{ + "version": "0.0.0" +} diff --git a/tsconfig.json b/tsconfig.json index d8eccc2..3b4a837 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,27 +1,28 @@ { "compileOnSave": false, "compilerOptions": { - "importHelpers": true, - "module": "es2020", - "esModuleInterop": true, - "outDir": "./dist/out-tsc", - "sourceMap": true, "declaration": false, - "moduleResolution": "node", + "esModuleInterop": true, "experimentalDecorators": true, - "target": "ES2022", - "typeRoots": [ - "node_modules/@types", - "@types" - ], + "importHelpers": true, "lib": [ "es2019", "dom", "esnext.asynciterable" ], + "module": "es2020", + "moduleResolution": "node", + "resolveJsonModule": true, + "outDir": "./dist/out-tsc", + "sourceMap": true, + "target": "ES2022", + "typeRoots": [ + "node_modules/@types", + "@types" + ], "useDefineForClassFields": false }, "angularCompilerOptions": { "strictTemplates": true } -} \ No newline at end of file +}